Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: add per device user friendly xgmi events for vega20

Non-outbound data metrics are non useful so mark them as legacy.
Bucket new perf counters into device and not device ip.
Bind events to chip instead of IP.
Report available event counters and not number of hw counter banks.
Move DF public macros to private since not needed outside of IP version.

v5: cleanup by moving per chip configs into structs

v4: After more discussion, replace *_LEGACY references with IP references
to indicate concept of pmu-typed versus event-config-typed event
registration.

v3: attr groups const array is global but attr groups are allocated per
device which doesn't work and causes problems on memory allocation and
de-allocation for pmu unregister. Switch to building const attr groups
per pmu instead to simplify solution.

v2: add comments on sysfs structure and formatting.

Signed-off-by: Jonathan Kim <jonathan.kim@amd.com>
Reviewed-by: Harish Kasiviswanathan <harish.kasiviswanathan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Jonathan Kim and committed by
Alex Deucher
b4a7db71 576e0ec2

+415 -155
-13
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 1294 1294 1295 1295 #include "amdgpu_object.h" 1296 1296 1297 - /* used by df_v3_6.c and amdgpu_pmu.c */ 1298 - #define AMDGPU_PMU_ATTR(_name, _object) \ 1299 - static ssize_t \ 1300 - _name##_show(struct device *dev, \ 1301 - struct device_attribute *attr, \ 1302 - char *page) \ 1303 - { \ 1304 - BUILD_BUG_ON(sizeof(_object) >= PAGE_SIZE - 1); \ 1305 - return sprintf(page, _object "\n"); \ 1306 - } \ 1307 - \ 1308 - static struct device_attribute pmu_attr_##_name = __ATTR_RO(_name) 1309 - 1310 1297 static inline bool amdgpu_is_tmz(struct amdgpu_device *adev) 1311 1298 { 1312 1299 return adev->gmc.tmz_enabled;
+382 -66
drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c
··· 19 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 20 * OTHER DEALINGS IN THE SOFTWARE. 21 21 * 22 - * Author: Jonathan Kim <jonathan.kim@amd.com> 23 - * 24 22 */ 25 23 26 24 #include <linux/perf_event.h> 27 25 #include <linux/init.h> 28 26 #include "amdgpu.h" 29 27 #include "amdgpu_pmu.h" 30 - #include "df_v3_6.h" 31 28 32 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 + 37 + struct amdgpu_pmu_event_attribute { 38 + struct device_attribute attr; 39 + const char *event_str; 40 + unsigned int type; 41 + }; 33 42 34 43 /* record to keep track of pmu entry per pmu type per device */ 35 44 struct amdgpu_pmu_entry { ··· 46 37 struct amdgpu_device *adev; 47 38 struct pmu pmu; 48 39 unsigned int pmu_perf_type; 40 + char *pmu_type_name; 41 + char *pmu_file_prefix; 42 + struct attribute_group fmt_attr_group; 43 + struct amdgpu_pmu_event_attribute *fmt_attr; 44 + struct attribute_group evt_attr_group; 45 + struct amdgpu_pmu_event_attribute *evt_attr; 49 46 }; 47 + 48 + static ssize_t amdgpu_pmu_event_show(struct device *dev, 49 + struct device_attribute *attr, char *buf) 50 + { 51 + struct amdgpu_pmu_event_attribute *amdgpu_pmu_attr; 52 + 53 + amdgpu_pmu_attr = container_of(attr, struct amdgpu_pmu_event_attribute, 54 + attr); 55 + 56 + if (!amdgpu_pmu_attr->type) 57 + return sprintf(buf, "%s\n", amdgpu_pmu_attr->event_str); 58 + 59 + return sprintf(buf, "%s,type=0x%x\n", 60 + amdgpu_pmu_attr->event_str, amdgpu_pmu_attr->type); 61 + } 50 62 51 63 static LIST_HEAD(amdgpu_pmu_list); 52 64 65 + 66 + struct amdgpu_pmu_attr { 67 + const char *name; 68 + const char *config; 69 + }; 70 + 71 + struct amdgpu_pmu_type { 72 + const unsigned int type; 73 + const unsigned int num_of_type; 74 + }; 75 + 76 + struct amdgpu_pmu_config { 77 + struct amdgpu_pmu_attr *formats; 78 + unsigned int num_formats; 79 + struct amdgpu_pmu_attr *events; 80 + unsigned int num_events; 81 + struct amdgpu_pmu_type *types; 82 + unsigned int num_types; 83 + }; 84 + 85 + /* 86 + * Events fall under two categories: 87 + * - PMU typed 88 + * Events in /sys/bus/event_source/devices/amdgpu_<pmu_type>_<dev_num> have 89 + * performance counter operations handled by one IP <pmu_type>. Formats and 90 + * events should be defined by <pmu_type>_<asic_type>_formats and 91 + * <pmu_type>_<asic_type>_events respectively. 92 + * 93 + * - Event config typed 94 + * Events in /sys/bus/event_source/devices/amdgpu_<dev_num> have performance 95 + * counter operations that can be handled by multiple IPs dictated by their 96 + * "type" format field. Formats and events should be defined by 97 + * amdgpu_pmu_formats and <asic_type>_events respectively. Format field 98 + * "type" is generated in amdgpu_pmu_event_show and defined in 99 + * <asic_type>_event_config_types. 100 + */ 101 + 102 + static struct amdgpu_pmu_attr amdgpu_pmu_formats[NUM_FORMATS_AMDGPU_PMU] = { 103 + { .name = "event", .config = "config:0-7" }, 104 + { .name = "instance", .config = "config:8-15" }, 105 + { .name = "umask", .config = "config:16-23"}, 106 + { .name = "type", .config = "config:56-63"} 107 + }; 108 + 109 + /* Vega20 events */ 110 + static struct amdgpu_pmu_attr vega20_events[NUM_EVENTS_VEGA20_MAX] = { 111 + { .name = "xgmi_link0_data_outbound", 112 + .config = "event=0x7,instance=0x46,umask=0x2" }, 113 + { .name = "xgmi_link1_data_outbound", 114 + .config = "event=0x7,instance=0x47,umask=0x2" } 115 + }; 116 + 117 + static struct amdgpu_pmu_type vega20_types[NUM_EVENT_TYPES_VEGA20] = { 118 + { .type = AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI, 119 + .num_of_type = NUM_EVENTS_VEGA20_XGMI } 120 + }; 121 + 122 + static struct amdgpu_pmu_config vega20_config = { 123 + .formats = amdgpu_pmu_formats, 124 + .num_formats = ARRAY_SIZE(amdgpu_pmu_formats), 125 + .events = vega20_events, 126 + .num_events = ARRAY_SIZE(vega20_events), 127 + .types = vega20_types, 128 + .num_types = ARRAY_SIZE(vega20_types) 129 + }; 130 + 131 + /* Vega20 data fabric (DF) events */ 132 + static struct amdgpu_pmu_attr df_vega20_formats[NUM_FORMATS_DF_VEGA20] = { 133 + { .name = "event", .config = "config:0-7" }, 134 + { .name = "instance", .config = "config:8-15" }, 135 + { .name = "umask", .config = "config:16-23"} 136 + }; 137 + 138 + static struct amdgpu_pmu_attr df_vega20_events[NUM_EVENTS_DF_VEGA20] = { 139 + { .name = "cake0_pcsout_txdata", 140 + .config = "event=0x7,instance=0x46,umask=0x2" }, 141 + { .name = "cake1_pcsout_txdata", 142 + .config = "event=0x7,instance=0x47,umask=0x2" }, 143 + { .name = "cake0_pcsout_txmeta", 144 + .config = "event=0x7,instance=0x46,umask=0x4" }, 145 + { .name = "cake1_pcsout_txmeta", 146 + .config = "event=0x7,instance=0x47,umask=0x4" }, 147 + { .name = "cake0_ftiinstat_reqalloc", 148 + .config = "event=0xb,instance=0x46,umask=0x4" }, 149 + { .name = "cake1_ftiinstat_reqalloc", 150 + .config = "event=0xb,instance=0x47,umask=0x4" }, 151 + { .name = "cake0_ftiinstat_rspalloc", 152 + .config = "event=0xb,instance=0x46,umask=0x8" }, 153 + { .name = "cake1_ftiinstat_rspalloc", 154 + .config = "event=0xb,instance=0x47,umask=0x8" } 155 + }; 156 + 157 + static struct amdgpu_pmu_config df_vega20_config = { 158 + .formats = df_vega20_formats, 159 + .num_formats = ARRAY_SIZE(df_vega20_formats), 160 + .events = df_vega20_events, 161 + .num_events = ARRAY_SIZE(df_vega20_events), 162 + .types = NULL, 163 + .num_types = 0 164 + }; 53 165 54 166 /* initialize perf counter */ 55 167 static int amdgpu_perf_event_init(struct perf_event *event) ··· 183 53 184 54 /* update the hw_perf_event struct with config data */ 185 55 hwc->config = event->attr.config; 56 + hwc->config_base = AMDGPU_PMU_PERF_TYPE_NONE; 186 57 187 58 return 0; 188 59 } ··· 203 72 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); 204 73 hwc->state = 0; 205 74 206 - switch (pe->pmu_perf_type) { 207 - case PERF_TYPE_AMDGPU_DF: 75 + switch (hwc->config_base) { 76 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 77 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 208 78 if (!(flags & PERF_EF_RELOAD)) { 209 79 target_cntr = pe->adev->df.funcs->pmc_start(pe->adev, 210 80 hwc->config, 0 /* unused */, ··· 233 101 struct amdgpu_pmu_entry *pe = container_of(event->pmu, 234 102 struct amdgpu_pmu_entry, 235 103 pmu); 236 - 237 104 u64 count, prev; 238 105 239 106 do { 240 107 prev = local64_read(&hwc->prev_count); 241 108 242 - switch (pe->pmu_perf_type) { 243 - case PERF_TYPE_AMDGPU_DF: 109 + switch (hwc->config_base) { 110 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 111 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 244 112 pe->adev->df.funcs->pmc_get_count(pe->adev, 245 113 hwc->config, hwc->idx, &count); 246 114 break; ··· 264 132 if (hwc->state & PERF_HES_UPTODATE) 265 133 return; 266 134 267 - switch (pe->pmu_perf_type) { 268 - case PERF_TYPE_AMDGPU_DF: 135 + switch (hwc->config_base) { 136 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 137 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 269 138 pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx, 270 139 0); 271 140 break; ··· 293 160 struct amdgpu_pmu_entry, 294 161 pmu); 295 162 163 + switch (pe->pmu_perf_type) { 164 + case AMDGPU_PMU_PERF_TYPE_DF: 165 + hwc->config_base = AMDGPU_PMU_EVENT_CONFIG_TYPE_DF; 166 + break; 167 + case AMDGPU_PMU_PERF_TYPE_ALL: 168 + hwc->config_base = (hwc->config >> 169 + AMDGPU_PMU_EVENT_CONFIG_TYPE_SHIFT) & 170 + AMDGPU_PMU_EVENT_CONFIG_TYPE_MASK; 171 + break; 172 + } 173 + 296 174 event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; 297 175 298 - switch (pe->pmu_perf_type) { 299 - case PERF_TYPE_AMDGPU_DF: 176 + switch (hwc->config_base) { 177 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 178 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 300 179 target_cntr = pe->adev->df.funcs->pmc_start(pe->adev, 301 180 hwc->config, 0 /* unused */, 302 181 1 /* add counter */); ··· 341 196 342 197 amdgpu_perf_stop(event, PERF_EF_UPDATE); 343 198 344 - switch (pe->pmu_perf_type) { 345 - case PERF_TYPE_AMDGPU_DF: 199 + switch (hwc->config_base) { 200 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: 201 + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: 346 202 pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx, 347 203 1); 348 204 break; ··· 354 208 perf_event_update_userpage(event); 355 209 } 356 210 357 - /* vega20 pmus */ 358 - 359 - /* init pmu tracking per pmu type */ 360 - static int init_pmu_by_type(struct amdgpu_device *adev, 361 - const struct attribute_group *attr_groups[], 362 - char *pmu_type_name, char *pmu_file_prefix, 363 - unsigned int pmu_perf_type, 364 - unsigned int num_counters) 211 + static void amdgpu_pmu_create_event_attrs_by_type( 212 + struct attribute_group *attr_group, 213 + struct amdgpu_pmu_event_attribute *pmu_attr, 214 + struct amdgpu_pmu_attr events[], 215 + int s_offset, 216 + int e_offset, 217 + unsigned int type) 365 218 { 366 - char pmu_name[PMU_NAME_SIZE]; 367 - struct amdgpu_pmu_entry *pmu_entry; 368 - int ret = 0; 219 + int i; 369 220 370 - pmu_entry = kzalloc(sizeof(struct amdgpu_pmu_entry), GFP_KERNEL); 221 + pmu_attr += s_offset; 371 222 372 - if (!pmu_entry) 223 + for (i = s_offset; i < e_offset; i++) { 224 + attr_group->attrs[i] = &pmu_attr->attr.attr; 225 + sysfs_attr_init(&pmu_attr->attr.attr); 226 + pmu_attr->attr.attr.name = events[i].name; 227 + pmu_attr->attr.attr.mode = 0444; 228 + pmu_attr->attr.show = amdgpu_pmu_event_show; 229 + pmu_attr->event_str = events[i].config; 230 + pmu_attr->type = type; 231 + pmu_attr++; 232 + } 233 + } 234 + 235 + static void amdgpu_pmu_create_attrs(struct attribute_group *attr_group, 236 + struct amdgpu_pmu_event_attribute *pmu_attr, 237 + struct amdgpu_pmu_attr events[], 238 + int num_events) 239 + { 240 + amdgpu_pmu_create_event_attrs_by_type(attr_group, pmu_attr, events, 0, 241 + num_events, AMDGPU_PMU_EVENT_CONFIG_TYPE_NONE); 242 + } 243 + 244 + 245 + static int amdgpu_pmu_alloc_pmu_attrs( 246 + struct attribute_group *fmt_attr_group, 247 + struct amdgpu_pmu_event_attribute **fmt_attr, 248 + struct attribute_group *evt_attr_group, 249 + struct amdgpu_pmu_event_attribute **evt_attr, 250 + struct amdgpu_pmu_config *config) 251 + { 252 + *fmt_attr = kcalloc(config->num_formats, sizeof(**fmt_attr), 253 + GFP_KERNEL); 254 + 255 + if (!(*fmt_attr)) 373 256 return -ENOMEM; 374 257 375 - pmu_entry->adev = adev; 258 + fmt_attr_group->attrs = kcalloc(config->num_formats + 1, 259 + sizeof(*fmt_attr_group->attrs), GFP_KERNEL); 260 + 261 + if (!fmt_attr_group->attrs) 262 + goto err_fmt_attr_grp; 263 + 264 + *evt_attr = kcalloc(config->num_events, sizeof(**evt_attr), GFP_KERNEL); 265 + 266 + if (!(*evt_attr)) 267 + goto err_evt_attr; 268 + 269 + evt_attr_group->attrs = kcalloc(config->num_events + 1, 270 + sizeof(*evt_attr_group->attrs), GFP_KERNEL); 271 + 272 + if (!evt_attr_group->attrs) 273 + goto err_evt_attr_grp; 274 + 275 + return 0; 276 + err_evt_attr_grp: 277 + kfree(*evt_attr); 278 + err_evt_attr: 279 + kfree(fmt_attr_group->attrs); 280 + err_fmt_attr_grp: 281 + kfree(*fmt_attr); 282 + return -ENOMEM; 283 + } 284 + 285 + /* init pmu tracking per pmu type */ 286 + static int init_pmu_entry_by_type_and_add(struct amdgpu_pmu_entry *pmu_entry, 287 + struct amdgpu_pmu_config *config) 288 + { 289 + const struct attribute_group *attr_groups[] = { 290 + &pmu_entry->fmt_attr_group, 291 + &pmu_entry->evt_attr_group, 292 + NULL 293 + }; 294 + char pmu_name[PMU_NAME_SIZE]; 295 + int ret = 0, total_num_events = 0; 296 + 376 297 pmu_entry->pmu = (struct pmu){ 377 298 .event_init = amdgpu_perf_event_init, 378 299 .add = amdgpu_perf_add, ··· 450 237 .task_ctx_nr = perf_invalid_context, 451 238 }; 452 239 453 - pmu_entry->pmu.attr_groups = attr_groups; 454 - pmu_entry->pmu_perf_type = pmu_perf_type; 455 - snprintf(pmu_name, PMU_NAME_SIZE, "%s_%d", 456 - pmu_file_prefix, adev_to_drm(adev)->primary->index); 240 + ret = amdgpu_pmu_alloc_pmu_attrs(&pmu_entry->fmt_attr_group, 241 + &pmu_entry->fmt_attr, 242 + &pmu_entry->evt_attr_group, 243 + &pmu_entry->evt_attr, 244 + config); 245 + 246 + if (ret) 247 + goto err_out; 248 + 249 + amdgpu_pmu_create_attrs(&pmu_entry->fmt_attr_group, pmu_entry->fmt_attr, 250 + config->formats, config->num_formats); 251 + 252 + if (pmu_entry->pmu_perf_type == AMDGPU_PMU_PERF_TYPE_ALL) { 253 + int i; 254 + 255 + for (i = 0; i < config->num_types; i++) { 256 + amdgpu_pmu_create_event_attrs_by_type( 257 + &pmu_entry->evt_attr_group, 258 + pmu_entry->evt_attr, 259 + config->events, 260 + total_num_events, 261 + total_num_events + 262 + config->types[i].num_of_type, 263 + config->types[i].type); 264 + total_num_events += config->types[i].num_of_type; 265 + } 266 + } else { 267 + amdgpu_pmu_create_attrs(&pmu_entry->evt_attr_group, 268 + pmu_entry->evt_attr, 269 + config->events, config->num_events); 270 + total_num_events = config->num_events; 271 + } 272 + 273 + pmu_entry->pmu.attr_groups = kmemdup(attr_groups, sizeof(attr_groups), 274 + GFP_KERNEL); 275 + 276 + if (!pmu_entry->pmu.attr_groups) 277 + goto err_attr_group; 278 + 279 + snprintf(pmu_name, PMU_NAME_SIZE, "%s_%d", pmu_entry->pmu_file_prefix, 280 + adev_to_drm(pmu_entry->adev)->primary->index); 457 281 458 282 ret = perf_pmu_register(&pmu_entry->pmu, pmu_name, -1); 459 283 460 - if (ret) { 461 - kfree(pmu_entry); 462 - pr_warn("Error initializing AMDGPU %s PMUs.\n", pmu_type_name); 463 - return ret; 464 - } 284 + if (ret) 285 + goto err_register; 465 286 466 - pr_info("Detected AMDGPU %s Counters. # of Counters = %d.\n", 467 - pmu_type_name, num_counters); 287 + if (pmu_entry->pmu_perf_type != AMDGPU_PMU_PERF_TYPE_ALL) 288 + pr_info("Detected AMDGPU %s Counters. # of Counters = %d.\n", 289 + pmu_entry->pmu_type_name, total_num_events); 290 + else 291 + pr_info("Detected AMDGPU %d Perf Events.\n", total_num_events); 292 + 468 293 469 294 list_add_tail(&pmu_entry->entry, &amdgpu_pmu_list); 470 295 471 296 return 0; 297 + err_register: 298 + kfree(pmu_entry->pmu.attr_groups); 299 + err_attr_group: 300 + kfree(pmu_entry->fmt_attr_group.attrs); 301 + kfree(pmu_entry->fmt_attr); 302 + kfree(pmu_entry->evt_attr_group.attrs); 303 + kfree(pmu_entry->evt_attr); 304 + err_out: 305 + pr_warn("Error initializing AMDGPU %s PMUs.\n", 306 + pmu_entry->pmu_type_name); 307 + return ret; 472 308 } 473 - 474 - /* init amdgpu_pmu */ 475 - int amdgpu_pmu_init(struct amdgpu_device *adev) 476 - { 477 - int ret = 0; 478 - 479 - switch (adev->asic_type) { 480 - case CHIP_VEGA20: 481 - /* init df */ 482 - ret = init_pmu_by_type(adev, df_v3_6_attr_groups, 483 - "DF", "amdgpu_df", PERF_TYPE_AMDGPU_DF, 484 - DF_V3_6_MAX_COUNTERS); 485 - 486 - /* other pmu types go here*/ 487 - break; 488 - default: 489 - return 0; 490 - } 491 - 492 - return 0; 493 - } 494 - 495 309 496 310 /* destroy all pmu data associated with target device */ 497 311 void amdgpu_pmu_fini(struct amdgpu_device *adev) ··· 526 286 struct amdgpu_pmu_entry *pe, *temp; 527 287 528 288 list_for_each_entry_safe(pe, temp, &amdgpu_pmu_list, entry) { 529 - if (pe->adev == adev) { 530 - list_del(&pe->entry); 531 - perf_pmu_unregister(&pe->pmu); 532 - kfree(pe); 533 - } 289 + if (pe->adev != adev) 290 + continue; 291 + list_del(&pe->entry); 292 + perf_pmu_unregister(&pe->pmu); 293 + kfree(pe->pmu.attr_groups); 294 + kfree(pe->fmt_attr_group.attrs); 295 + kfree(pe->fmt_attr); 296 + kfree(pe->evt_attr_group.attrs); 297 + kfree(pe->evt_attr); 298 + kfree(pe); 534 299 } 300 + } 301 + 302 + static struct amdgpu_pmu_entry *create_pmu_entry(struct amdgpu_device *adev, 303 + unsigned int pmu_type, 304 + char *pmu_type_name, 305 + char *pmu_file_prefix) 306 + { 307 + struct amdgpu_pmu_entry *pmu_entry; 308 + 309 + pmu_entry = kzalloc(sizeof(struct amdgpu_pmu_entry), GFP_KERNEL); 310 + 311 + if (!pmu_entry) 312 + return pmu_entry; 313 + 314 + pmu_entry->adev = adev; 315 + pmu_entry->fmt_attr_group.name = "format"; 316 + pmu_entry->fmt_attr_group.attrs = NULL; 317 + pmu_entry->evt_attr_group.name = "events"; 318 + pmu_entry->evt_attr_group.attrs = NULL; 319 + pmu_entry->pmu_perf_type = pmu_type; 320 + pmu_entry->pmu_type_name = pmu_type_name; 321 + pmu_entry->pmu_file_prefix = pmu_file_prefix; 322 + 323 + return pmu_entry; 324 + } 325 + 326 + /* init amdgpu_pmu */ 327 + int amdgpu_pmu_init(struct amdgpu_device *adev) 328 + { 329 + int ret = 0; 330 + struct amdgpu_pmu_entry *pmu_entry, *pmu_entry_df; 331 + 332 + switch (adev->asic_type) { 333 + case CHIP_VEGA20: 334 + pmu_entry_df = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_DF, 335 + "DF", "amdgpu_df"); 336 + 337 + if (!pmu_entry_df) 338 + return -ENOMEM; 339 + 340 + ret = init_pmu_entry_by_type_and_add(pmu_entry_df, 341 + &df_vega20_config); 342 + 343 + if (ret) { 344 + kfree(pmu_entry_df); 345 + return ret; 346 + } 347 + 348 + pmu_entry = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_ALL, 349 + "", "amdgpu"); 350 + 351 + if (!pmu_entry) { 352 + amdgpu_pmu_fini(adev); 353 + return -ENOMEM; 354 + } 355 + 356 + ret = init_pmu_entry_by_type_and_add(pmu_entry, 357 + &vega20_config); 358 + 359 + if (ret) { 360 + kfree(pmu_entry); 361 + amdgpu_pmu_fini(adev); 362 + return ret; 363 + } 364 + 365 + break; 366 + default: 367 + return 0; 368 + }; 369 + 370 + return ret; 535 371 }
+24 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.h
··· 19 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 20 * OTHER DEALINGS IN THE SOFTWARE. 21 21 * 22 - * Author: Jonathan Kim <jonathan.kim@amd.com> 23 - * 24 22 */ 25 23 26 24 #ifndef _AMDGPU_PMU_H_ 27 25 #define _AMDGPU_PMU_H_ 28 26 27 + /* PMU types. */ 29 28 enum amdgpu_pmu_perf_type { 30 - PERF_TYPE_AMDGPU_DF = 0, 31 - PERF_TYPE_AMDGPU_MAX 29 + AMDGPU_PMU_PERF_TYPE_NONE = 0, 30 + AMDGPU_PMU_PERF_TYPE_DF, 31 + AMDGPU_PMU_PERF_TYPE_ALL 32 32 }; 33 + 34 + /* 35 + * PMU type AMDGPU_PMU_PERF_TYPE_ALL can hold events of different "type" 36 + * configurations. Event config types are parsed from the 64-bit raw 37 + * config (See EVENT_CONFIG_TYPE_SHIFT and EVENT_CONFIG_TYPE_MASK) and 38 + * are registered into the HW perf events config_base. 39 + * 40 + * PMU types with only a single event configuration type 41 + * (non-AMDGPU_PMU_PERF_TYPE_ALL) have their event config type auto generated 42 + * when the performance counter is added. 43 + */ 44 + enum amdgpu_pmu_event_config_type { 45 + AMDGPU_PMU_EVENT_CONFIG_TYPE_NONE = 0, 46 + AMDGPU_PMU_EVENT_CONFIG_TYPE_DF, 47 + AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI, 48 + AMDGPU_PMU_EVENT_CONFIG_TYPE_MAX 49 + }; 50 + 51 + #define AMDGPU_PMU_EVENT_CONFIG_TYPE_SHIFT 56 52 + #define AMDGPU_PMU_EVENT_CONFIG_TYPE_MASK 0xff 33 53 34 54 int amdgpu_pmu_init(struct amdgpu_device *adev); 35 55 void amdgpu_pmu_fini(struct amdgpu_device *adev);
+9 -63
drivers/gpu/drm/amd/amdgpu/df_v3_6.c
··· 30 30 #define DF_3_6_SMN_REG_INST_DIST 0x8 31 31 #define DF_3_6_INST_CNT 8 32 32 33 + /* Defined in global_features.h as FTI_PERFMON_VISIBLE */ 34 + #define DF_V3_6_MAX_COUNTERS 4 35 + 36 + /* get flags from df perfmon config */ 37 + #define DF_V3_6_GET_EVENT(x) (x & 0xFFUL) 38 + #define DF_V3_6_GET_INSTANCE(x) ((x >> 8) & 0xFFUL) 39 + #define DF_V3_6_GET_UNITMASK(x) ((x >> 16) & 0xFFUL) 40 + #define DF_V3_6_PERFMON_OVERFLOW 0xFFFFFFFFFFFFULL 41 + 33 42 static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0, 34 43 16, 32, 0, 0, 0, 2, 4, 8}; 35 - 36 - /* init df format attrs */ 37 - AMDGPU_PMU_ATTR(event, "config:0-7"); 38 - AMDGPU_PMU_ATTR(instance, "config:8-15"); 39 - AMDGPU_PMU_ATTR(umask, "config:16-23"); 40 - 41 - /* df format attributes */ 42 - static struct attribute *df_v3_6_format_attrs[] = { 43 - &pmu_attr_event.attr, 44 - &pmu_attr_instance.attr, 45 - &pmu_attr_umask.attr, 46 - NULL 47 - }; 48 - 49 - /* df format attribute group */ 50 - static struct attribute_group df_v3_6_format_attr_group = { 51 - .name = "format", 52 - .attrs = df_v3_6_format_attrs, 53 - }; 54 - 55 - /* df event attrs */ 56 - AMDGPU_PMU_ATTR(cake0_pcsout_txdata, 57 - "event=0x7,instance=0x46,umask=0x2"); 58 - AMDGPU_PMU_ATTR(cake1_pcsout_txdata, 59 - "event=0x7,instance=0x47,umask=0x2"); 60 - AMDGPU_PMU_ATTR(cake0_pcsout_txmeta, 61 - "event=0x7,instance=0x46,umask=0x4"); 62 - AMDGPU_PMU_ATTR(cake1_pcsout_txmeta, 63 - "event=0x7,instance=0x47,umask=0x4"); 64 - AMDGPU_PMU_ATTR(cake0_ftiinstat_reqalloc, 65 - "event=0xb,instance=0x46,umask=0x4"); 66 - AMDGPU_PMU_ATTR(cake1_ftiinstat_reqalloc, 67 - "event=0xb,instance=0x47,umask=0x4"); 68 - AMDGPU_PMU_ATTR(cake0_ftiinstat_rspalloc, 69 - "event=0xb,instance=0x46,umask=0x8"); 70 - AMDGPU_PMU_ATTR(cake1_ftiinstat_rspalloc, 71 - "event=0xb,instance=0x47,umask=0x8"); 72 - 73 - /* df event attributes */ 74 - static struct attribute *df_v3_6_event_attrs[] = { 75 - &pmu_attr_cake0_pcsout_txdata.attr, 76 - &pmu_attr_cake1_pcsout_txdata.attr, 77 - &pmu_attr_cake0_pcsout_txmeta.attr, 78 - &pmu_attr_cake1_pcsout_txmeta.attr, 79 - &pmu_attr_cake0_ftiinstat_reqalloc.attr, 80 - &pmu_attr_cake1_ftiinstat_reqalloc.attr, 81 - &pmu_attr_cake0_ftiinstat_rspalloc.attr, 82 - &pmu_attr_cake1_ftiinstat_rspalloc.attr, 83 - NULL 84 - }; 85 - 86 - /* df event attribute group */ 87 - static struct attribute_group df_v3_6_event_attr_group = { 88 - .name = "events", 89 - .attrs = df_v3_6_event_attrs 90 - }; 91 - 92 - /* df event attr groups */ 93 - const struct attribute_group *df_v3_6_attr_groups[] = { 94 - &df_v3_6_format_attr_group, 95 - &df_v3_6_event_attr_group, 96 - NULL 97 - }; 98 44 99 45 static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev, 100 46 uint32_t ficaa_val)
-9
drivers/gpu/drm/amd/amdgpu/df_v3_6.h
··· 35 35 DF_V3_6_MGCG_ENABLE_63_CYCLE_DELAY = 15 36 36 }; 37 37 38 - /* Defined in global_features.h as FTI_PERFMON_VISIBLE */ 39 - #define DF_V3_6_MAX_COUNTERS 4 40 - 41 - /* get flags from df perfmon config */ 42 - #define DF_V3_6_GET_EVENT(x) (x & 0xFFUL) 43 - #define DF_V3_6_GET_INSTANCE(x) ((x >> 8) & 0xFFUL) 44 - #define DF_V3_6_GET_UNITMASK(x) ((x >> 16) & 0xFFUL) 45 - #define DF_V3_6_PERFMON_OVERFLOW 0xFFFFFFFFFFFFULL 46 - 47 38 extern const struct attribute_group *df_v3_6_attr_groups[]; 48 39 extern const struct amdgpu_df_funcs df_v3_6_funcs; 49 40