1 /* 2 * Copyright 2019 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #include <linux/perf_event.h> 25 #include <linux/init.h> 26 #include "amdgpu.h" 27 #include "amdgpu_pmu.h" 28 29 #define PMU_NAME_SIZE 32 30 #define NUM_FORMATS_AMDGPU_PMU 4 31 #define NUM_FORMATS_DF_VEGA20 3 32 #define NUM_EVENTS_DF_VEGA20 8 33 #define NUM_EVENT_TYPES_VEGA20 1 34 #define NUM_EVENTS_VEGA20_XGMI 2 35 #define NUM_EVENTS_VEGA20_MAX NUM_EVENTS_VEGA20_XGMI 36 #define NUM_EVENT_TYPES_ARCTURUS 1 37 #define NUM_EVENTS_ARCTURUS_XGMI 6 38 #define NUM_EVENTS_ARCTURUS_MAX NUM_EVENTS_ARCTURUS_XGMI 39 40 struct amdgpu_pmu_event_attribute { 41 struct device_attribute attr; 42 const char *event_str; 43 unsigned int type; 44 }; 45 46 /* record to keep track of pmu entry per pmu type per device */ 47 struct amdgpu_pmu_entry { 48 struct list_head entry; 49 struct amdgpu_device *adev; 50 struct pmu pmu; 51 unsigned int pmu_perf_type; 52 char *pmu_type_name; 53 char *pmu_file_prefix; 54 struct attribute_group fmt_attr_group; 55 struct amdgpu_pmu_event_attribute *fmt_attr; 56 struct attribute_group evt_attr_group; 57 struct amdgpu_pmu_event_attribute *evt_attr; 58 }; 59 60 static ssize_t amdgpu_pmu_event_show(struct device *dev, 61 struct device_attribute *attr, char *buf) 62 { 63 struct amdgpu_pmu_event_attribute *amdgpu_pmu_attr; 64 65 amdgpu_pmu_attr = container_of(attr, struct amdgpu_pmu_event_attribute, 66 attr); 67 68 if (!amdgpu_pmu_attr->type) 69 return sprintf(buf, "%s\n", amdgpu_pmu_attr->event_str); 70 71 return sprintf(buf, "%s,type=0x%x\n", 72 amdgpu_pmu_attr->event_str, amdgpu_pmu_attr->type); 73 } 74 75 static LIST_HEAD(amdgpu_pmu_list); 76 77 78 struct amdgpu_pmu_attr { 79 const char *name; 80 const char *config; 81 }; 82 83 struct amdgpu_pmu_type { 84 const unsigned int type; 85 const unsigned int num_of_type; 86 }; 87 88 struct amdgpu_pmu_config { 89 struct amdgpu_pmu_attr *formats; 90 unsigned int num_formats; 91 struct amdgpu_pmu_attr *events; 92 unsigned int num_events; 93 struct amdgpu_pmu_type *types; 94 unsigned int num_types; 95 }; 96 97 /* 98 * Events fall under two categories: 99 * - PMU typed 100 * Events in /sys/bus/event_source/devices/amdgpu_<pmu_type>_<dev_num> have 101 * performance counter operations handled by one IP <pmu_type>. Formats and 102 * events should be defined by <pmu_type>_<asic_type>_formats and 103 * <pmu_type>_<asic_type>_events respectively. 104 * 105 * - Event config typed 106 * Events in /sys/bus/event_source/devices/amdgpu_<dev_num> have performance 107 * counter operations that can be handled by multiple IPs dictated by their 108 * "type" format field. Formats and events should be defined by 109 * amdgpu_pmu_formats and <asic_type>_events respectively. Format field 110 * "type" is generated in amdgpu_pmu_event_show and defined in 111 * <asic_type>_event_config_types. 112 */ 113 114 static struct amdgpu_pmu_attr amdgpu_pmu_formats[NUM_FORMATS_AMDGPU_PMU] = { 115 { .name = "event", .config = "config:0-7" }, 116 { .name = "instance", .config = "config:8-15" }, 117 { .name = "umask", .config = "config:16-23"}, 118 { .name = "type", .config = "config:56-63"} 119 }; 120 121 /* Vega20 events */ 122 static struct amdgpu_pmu_attr vega20_events[NUM_EVENTS_VEGA20_MAX] = { 123 { .name = "xgmi_link0_data_outbound", 124 .config = "event=0x7,instance=0x46,umask=0x2" }, 125 { .name = "xgmi_link1_data_outbound", 126 .config = "event=0x7,instance=0x47,umask=0x2" } 127 }; 128 129 static struct amdgpu_pmu_type vega20_types[NUM_EVENT_TYPES_VEGA20] = { 130 { .type = AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI, 131 .num_of_type = NUM_EVENTS_VEGA20_XGMI } 132 }; 133 134 static struct amdgpu_pmu_config vega20_config = { 135 .formats = amdgpu_pmu_formats, 136 .num_formats = ARRAY_SIZE(amdgpu_pmu_formats), 137 .events = vega20_events, 138 .num_events = ARRAY_SIZE(vega20_events), 139 .types = vega20_types, 140 .num_types = ARRAY_SIZE(vega20_types) 141 }; 142 143 /* Vega20 data fabric (DF) events */ 144 static struct amdgpu_pmu_attr df_vega20_formats[NUM_FORMATS_DF_VEGA20] = { 145 { .name = "event", .config = "config:0-7" }, 146 { .name = "instance", .config = "config:8-15" }, 147 { .name = "umask", .config = "config:16-23"} 148 }; 149 150 static struct amdgpu_pmu_attr df_vega20_events[NUM_EVENTS_DF_VEGA20] = { 151 { .name = "cake0_pcsout_txdata", 152 .config = "event=0x7,instance=0x46,umask=0x2" }, 153 { .name = "cake1_pcsout_txdata", 154 .config = "event=0x7,instance=0x47,umask=0x2" }, 155 { .name = "cake0_pcsout_txmeta", 156 .config = "event=0x7,instance=0x46,umask=0x4" }, 157 { .name = "cake1_pcsout_txmeta", 158 .config = "event=0x7,instance=0x47,umask=0x4" }, 159 { .name = "cake0_ftiinstat_reqalloc", 160 .config = "event=0xb,instance=0x46,umask=0x4" }, 161 { .name = "cake1_ftiinstat_reqalloc", 162 .config = "event=0xb,instance=0x47,umask=0x4" }, 163 { .name = "cake0_ftiinstat_rspalloc", 164 .config = "event=0xb,instance=0x46,umask=0x8" }, 165 { .name = "cake1_ftiinstat_rspalloc", 166 .config = "event=0xb,instance=0x47,umask=0x8" } 167 }; 168 169 static struct amdgpu_pmu_config df_vega20_config = { 170 .formats = df_vega20_formats, 171 .num_formats = ARRAY_SIZE(df_vega20_formats), 172 .events = df_vega20_events, 173 .num_events = ARRAY_SIZE(df_vega20_events), 174 .types = NULL, 175 .num_types = 0 176 }; 177 178 /* Arcturus events */ 179 static struct amdgpu_pmu_attr arcturus_events[NUM_EVENTS_ARCTURUS_MAX] = { 180 { .name = "xgmi_link0_data_outbound", 181 .config = "event=0x7,instance=0x4b,umask=0x2" }, 182 { .name = "xgmi_link1_data_outbound", 183 .config = "event=0x7,instance=0x4c,umask=0x2" }, 184 { .name = "xgmi_link2_data_outbound", 185 .config = "event=0x7,instance=0x4d,umask=0x2" }, 186 { .name = "xgmi_link3_data_outbound", 187 .config = "event=0x7,instance=0x4e,umask=0x2" }, 188 { .name = "xgmi_link4_data_outbound", 189 .config = "event=0x7,instance=0x4f,umask=0x2" }, 190 { .name = "xgmi_link5_data_outbound", 191 .config = "event=0x7,instance=0x50,umask=0x2" } 192 }; 193 194 static struct amdgpu_pmu_type arcturus_types[NUM_EVENT_TYPES_ARCTURUS] = { 195 { .type = AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI, 196 .num_of_type = NUM_EVENTS_ARCTURUS_XGMI } 197 }; 198 199 static struct amdgpu_pmu_config arcturus_config = { 200 .formats = amdgpu_pmu_formats, 201 .num_formats = ARRAY_SIZE(amdgpu_pmu_formats), 202 .events = arcturus_events, 203 .num_events = ARRAY_SIZE(arcturus_events), 204 .types = arcturus_types, 205 .num_types = ARRAY_SIZE(arcturus_types) 206 }; 207 208 /* initialize perf counter */ 209 static int amdgpu_perf_event_init(struct perf_event *event) 210 { 211 struct hw_perf_event *hwc = &event->hw; 212 213 /* test the event attr type check for PMU enumeration */ 214 if (event->attr.type != event->pmu->type) 215 return -ENOENT; 216 217 /* update the hw_perf_event struct with config data */ 218 hwc->config = event->attr.config; 219 hwc->config_base = AMDGPU_PMU_PERF_TYPE_NONE; 220 221 return 0; 222 } 223 224 /* start perf counter */ 225 static void amdgpu_perf_start(struct perf_event *event, int flags) 226 { 227 struct hw_perf_event *hwc = &event->hw; 228 struct amdgpu_pmu_entry *pe = container_of(event->pmu, 229 struct amdgpu_pmu_entry, 230 pmu); 231 int target_cntr = 0; 232 233 if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) 234 return; 235 236 if ((!pe->adev->df.funcs) || 237 (!pe->adev->df.funcs->pmc_start)) 238 return; 239 240 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); 241 hwc->state = 0; 242 243 switch (hwc->config_base) { 244 case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 245 case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 246 if (!(flags & PERF_EF_RELOAD)) { 247 target_cntr = pe->adev->df.funcs->pmc_start(pe->adev, 248 hwc->config, 0 /* unused */, 249 1 /* add counter */); 250 if (target_cntr < 0) 251 break; 252 253 hwc->idx = target_cntr; 254 } 255 256 pe->adev->df.funcs->pmc_start(pe->adev, hwc->config, 257 hwc->idx, 0); 258 break; 259 default: 260 break; 261 } 262 263 perf_event_update_userpage(event); 264 } 265 266 /* read perf counter */ 267 static void amdgpu_perf_read(struct perf_event *event) 268 { 269 struct hw_perf_event *hwc = &event->hw; 270 struct amdgpu_pmu_entry *pe = container_of(event->pmu, 271 struct amdgpu_pmu_entry, 272 pmu); 273 u64 count, prev; 274 275 if ((!pe->adev->df.funcs) || 276 (!pe->adev->df.funcs->pmc_get_count)) 277 return; 278 279 prev = local64_read(&hwc->prev_count); 280 do { 281 switch (hwc->config_base) { 282 case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 283 case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 284 pe->adev->df.funcs->pmc_get_count(pe->adev, 285 hwc->config, hwc->idx, &count); 286 break; 287 default: 288 count = 0; 289 break; 290 } 291 } while (!local64_try_cmpxchg(&hwc->prev_count, &prev, count)); 292 293 local64_add(count - prev, &event->count); 294 } 295 296 /* stop perf counter */ 297 static void amdgpu_perf_stop(struct perf_event *event, int flags) 298 { 299 struct hw_perf_event *hwc = &event->hw; 300 struct amdgpu_pmu_entry *pe = container_of(event->pmu, 301 struct amdgpu_pmu_entry, 302 pmu); 303 304 if (hwc->state & PERF_HES_UPTODATE) 305 return; 306 307 if ((!pe->adev->df.funcs) || 308 (!pe->adev->df.funcs->pmc_stop)) 309 return; 310 311 switch (hwc->config_base) { 312 case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 313 case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 314 pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx, 315 0); 316 break; 317 default: 318 break; 319 } 320 321 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); 322 hwc->state |= PERF_HES_STOPPED; 323 324 if (hwc->state & PERF_HES_UPTODATE) 325 return; 326 327 amdgpu_perf_read(event); 328 hwc->state |= PERF_HES_UPTODATE; 329 } 330 331 /* add perf counter */ 332 static int amdgpu_perf_add(struct perf_event *event, int flags) 333 { 334 struct hw_perf_event *hwc = &event->hw; 335 int retval = 0, target_cntr; 336 struct amdgpu_pmu_entry *pe = container_of(event->pmu, 337 struct amdgpu_pmu_entry, 338 pmu); 339 340 if ((!pe->adev->df.funcs) || 341 (!pe->adev->df.funcs->pmc_start)) 342 return -EINVAL; 343 344 switch (pe->pmu_perf_type) { 345 case AMDGPU_PMU_PERF_TYPE_DF: 346 hwc->config_base = AMDGPU_PMU_EVENT_CONFIG_TYPE_DF; 347 break; 348 case AMDGPU_PMU_PERF_TYPE_ALL: 349 hwc->config_base = (hwc->config >> 350 AMDGPU_PMU_EVENT_CONFIG_TYPE_SHIFT) & 351 AMDGPU_PMU_EVENT_CONFIG_TYPE_MASK; 352 break; 353 } 354 355 event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; 356 357 switch (hwc->config_base) { 358 case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 359 case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 360 target_cntr = pe->adev->df.funcs->pmc_start(pe->adev, 361 hwc->config, 0 /* unused */, 362 1 /* add counter */); 363 if (target_cntr < 0) 364 retval = target_cntr; 365 else 366 hwc->idx = target_cntr; 367 368 break; 369 default: 370 return 0; 371 } 372 373 if (retval) 374 return retval; 375 376 if (flags & PERF_EF_START) 377 amdgpu_perf_start(event, PERF_EF_RELOAD); 378 379 return retval; 380 } 381 382 /* delete perf counter */ 383 static void amdgpu_perf_del(struct perf_event *event, int flags) 384 { 385 struct hw_perf_event *hwc = &event->hw; 386 struct amdgpu_pmu_entry *pe = container_of(event->pmu, 387 struct amdgpu_pmu_entry, 388 pmu); 389 if ((!pe->adev->df.funcs) || 390 (!pe->adev->df.funcs->pmc_stop)) 391 return; 392 393 amdgpu_perf_stop(event, PERF_EF_UPDATE); 394 395 switch (hwc->config_base) { 396 case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 397 case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 398 pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx, 399 1); 400 break; 401 default: 402 break; 403 } 404 405 perf_event_update_userpage(event); 406 } 407 408 static void amdgpu_pmu_create_event_attrs_by_type( 409 struct attribute_group *attr_group, 410 struct amdgpu_pmu_event_attribute *pmu_attr, 411 struct amdgpu_pmu_attr events[], 412 int s_offset, 413 int e_offset, 414 unsigned int type) 415 { 416 int i; 417 418 pmu_attr += s_offset; 419 420 for (i = s_offset; i < e_offset; i++) { 421 attr_group->attrs[i] = &pmu_attr->attr.attr; 422 sysfs_attr_init(&pmu_attr->attr.attr); 423 pmu_attr->attr.attr.name = events[i].name; 424 pmu_attr->attr.attr.mode = 0444; 425 pmu_attr->attr.show = amdgpu_pmu_event_show; 426 pmu_attr->event_str = events[i].config; 427 pmu_attr->type = type; 428 pmu_attr++; 429 } 430 } 431 432 static void amdgpu_pmu_create_attrs(struct attribute_group *attr_group, 433 struct amdgpu_pmu_event_attribute *pmu_attr, 434 struct amdgpu_pmu_attr events[], 435 int num_events) 436 { 437 amdgpu_pmu_create_event_attrs_by_type(attr_group, pmu_attr, events, 0, 438 num_events, AMDGPU_PMU_EVENT_CONFIG_TYPE_NONE); 439 } 440 441 442 static int amdgpu_pmu_alloc_pmu_attrs( 443 struct attribute_group *fmt_attr_group, 444 struct amdgpu_pmu_event_attribute **fmt_attr, 445 struct attribute_group *evt_attr_group, 446 struct amdgpu_pmu_event_attribute **evt_attr, 447 struct amdgpu_pmu_config *config) 448 { 449 *fmt_attr = kcalloc(config->num_formats, sizeof(**fmt_attr), 450 GFP_KERNEL); 451 452 if (!(*fmt_attr)) 453 return -ENOMEM; 454 455 fmt_attr_group->attrs = kcalloc(config->num_formats + 1, 456 sizeof(*fmt_attr_group->attrs), GFP_KERNEL); 457 458 if (!fmt_attr_group->attrs) 459 goto err_fmt_attr_grp; 460 461 *evt_attr = kcalloc(config->num_events, sizeof(**evt_attr), GFP_KERNEL); 462 463 if (!(*evt_attr)) 464 goto err_evt_attr; 465 466 evt_attr_group->attrs = kcalloc(config->num_events + 1, 467 sizeof(*evt_attr_group->attrs), GFP_KERNEL); 468 469 if (!evt_attr_group->attrs) 470 goto err_evt_attr_grp; 471 472 return 0; 473 err_evt_attr_grp: 474 kfree(*evt_attr); 475 err_evt_attr: 476 kfree(fmt_attr_group->attrs); 477 err_fmt_attr_grp: 478 kfree(*fmt_attr); 479 return -ENOMEM; 480 } 481 482 /* init pmu tracking per pmu type */ 483 static int init_pmu_entry_by_type_and_add(struct amdgpu_pmu_entry *pmu_entry, 484 struct amdgpu_pmu_config *config) 485 { 486 const struct attribute_group *attr_groups[] = { 487 &pmu_entry->fmt_attr_group, 488 &pmu_entry->evt_attr_group, 489 NULL 490 }; 491 char pmu_name[PMU_NAME_SIZE]; 492 int ret = 0, total_num_events = 0; 493 494 pmu_entry->pmu = (struct pmu){ 495 .event_init = amdgpu_perf_event_init, 496 .add = amdgpu_perf_add, 497 .del = amdgpu_perf_del, 498 .start = amdgpu_perf_start, 499 .stop = amdgpu_perf_stop, 500 .read = amdgpu_perf_read, 501 .task_ctx_nr = perf_invalid_context, 502 }; 503 504 ret = amdgpu_pmu_alloc_pmu_attrs(&pmu_entry->fmt_attr_group, 505 &pmu_entry->fmt_attr, 506 &pmu_entry->evt_attr_group, 507 &pmu_entry->evt_attr, 508 config); 509 510 if (ret) 511 goto err_out; 512 513 amdgpu_pmu_create_attrs(&pmu_entry->fmt_attr_group, pmu_entry->fmt_attr, 514 config->formats, config->num_formats); 515 516 if (pmu_entry->pmu_perf_type == AMDGPU_PMU_PERF_TYPE_ALL) { 517 int i; 518 519 for (i = 0; i < config->num_types; i++) { 520 amdgpu_pmu_create_event_attrs_by_type( 521 &pmu_entry->evt_attr_group, 522 pmu_entry->evt_attr, 523 config->events, 524 total_num_events, 525 total_num_events + 526 config->types[i].num_of_type, 527 config->types[i].type); 528 total_num_events += config->types[i].num_of_type; 529 } 530 } else { 531 amdgpu_pmu_create_attrs(&pmu_entry->evt_attr_group, 532 pmu_entry->evt_attr, 533 config->events, config->num_events); 534 total_num_events = config->num_events; 535 } 536 537 pmu_entry->pmu.attr_groups = kmemdup(attr_groups, sizeof(attr_groups), 538 GFP_KERNEL); 539 540 if (!pmu_entry->pmu.attr_groups) { 541 ret = -ENOMEM; 542 goto err_attr_group; 543 } 544 545 snprintf(pmu_name, PMU_NAME_SIZE, "%s_%d", pmu_entry->pmu_file_prefix, 546 adev_to_drm(pmu_entry->adev)->primary->index); 547 548 ret = perf_pmu_register(&pmu_entry->pmu, pmu_name, -1); 549 550 if (ret) 551 goto err_register; 552 553 if (pmu_entry->pmu_perf_type != AMDGPU_PMU_PERF_TYPE_ALL) 554 pr_info("Detected AMDGPU %s Counters. # of Counters = %d.\n", 555 pmu_entry->pmu_type_name, total_num_events); 556 else 557 pr_info("Detected AMDGPU %d Perf Events.\n", total_num_events); 558 559 560 list_add_tail(&pmu_entry->entry, &amdgpu_pmu_list); 561 562 return 0; 563 err_register: 564 kfree(pmu_entry->pmu.attr_groups); 565 err_attr_group: 566 kfree(pmu_entry->fmt_attr_group.attrs); 567 kfree(pmu_entry->fmt_attr); 568 kfree(pmu_entry->evt_attr_group.attrs); 569 kfree(pmu_entry->evt_attr); 570 err_out: 571 pr_warn("Error initializing AMDGPU %s PMUs.\n", 572 pmu_entry->pmu_type_name); 573 return ret; 574 } 575 576 /* destroy all pmu data associated with target device */ 577 void amdgpu_pmu_fini(struct amdgpu_device *adev) 578 { 579 struct amdgpu_pmu_entry *pe, *temp; 580 581 list_for_each_entry_safe(pe, temp, &amdgpu_pmu_list, entry) { 582 if (pe->adev != adev) 583 continue; 584 list_del(&pe->entry); 585 perf_pmu_unregister(&pe->pmu); 586 kfree(pe->pmu.attr_groups); 587 kfree(pe->fmt_attr_group.attrs); 588 kfree(pe->fmt_attr); 589 kfree(pe->evt_attr_group.attrs); 590 kfree(pe->evt_attr); 591 kfree(pe); 592 } 593 } 594 595 static struct amdgpu_pmu_entry *create_pmu_entry(struct amdgpu_device *adev, 596 unsigned int pmu_type, 597 char *pmu_type_name, 598 char *pmu_file_prefix) 599 { 600 struct amdgpu_pmu_entry *pmu_entry; 601 602 pmu_entry = kzalloc(sizeof(struct amdgpu_pmu_entry), GFP_KERNEL); 603 604 if (!pmu_entry) 605 return pmu_entry; 606 607 pmu_entry->adev = adev; 608 pmu_entry->fmt_attr_group.name = "format"; 609 pmu_entry->fmt_attr_group.attrs = NULL; 610 pmu_entry->evt_attr_group.name = "events"; 611 pmu_entry->evt_attr_group.attrs = NULL; 612 pmu_entry->pmu_perf_type = pmu_type; 613 pmu_entry->pmu_type_name = pmu_type_name; 614 pmu_entry->pmu_file_prefix = pmu_file_prefix; 615 616 return pmu_entry; 617 } 618 619 /* init amdgpu_pmu */ 620 int amdgpu_pmu_init(struct amdgpu_device *adev) 621 { 622 int ret = 0; 623 struct amdgpu_pmu_entry *pmu_entry, *pmu_entry_df; 624 625 switch (adev->asic_type) { 626 case CHIP_VEGA20: 627 pmu_entry_df = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_DF, 628 "DF", "amdgpu_df"); 629 630 if (!pmu_entry_df) 631 return -ENOMEM; 632 633 ret = init_pmu_entry_by_type_and_add(pmu_entry_df, 634 &df_vega20_config); 635 636 if (ret) { 637 kfree(pmu_entry_df); 638 return ret; 639 } 640 641 pmu_entry = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_ALL, 642 "", "amdgpu"); 643 644 if (!pmu_entry) { 645 amdgpu_pmu_fini(adev); 646 return -ENOMEM; 647 } 648 649 ret = init_pmu_entry_by_type_and_add(pmu_entry, 650 &vega20_config); 651 652 if (ret) { 653 kfree(pmu_entry); 654 amdgpu_pmu_fini(adev); 655 return ret; 656 } 657 658 break; 659 case CHIP_ARCTURUS: 660 pmu_entry = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_ALL, 661 "", "amdgpu"); 662 if (!pmu_entry) 663 return -ENOMEM; 664 665 ret = init_pmu_entry_by_type_and_add(pmu_entry, 666 &arcturus_config); 667 668 if (ret) { 669 kfree(pmu_entry); 670 return -ENOMEM; 671 } 672 673 break; 674 675 default: 676 return 0; 677 } 678 679 return ret; 680 } 681