1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 */ 5 6 #include "drm/drm_file.h" 7 #include "drm/msm_drm.h" 8 9 #include "linux/anon_inodes.h" 10 #include "linux/gfp_types.h" 11 #include "linux/poll.h" 12 #include "linux/slab.h" 13 14 #include "msm_drv.h" 15 #include "msm_gpu.h" 16 #include "msm_perfcntr.h" 17 18 #include "adreno/adreno_gpu.h" 19 20 /* space used: */ 21 #define fifo_count(stream) \ 22 (CIRC_CNT((stream)->fifo.head, (stream)->fifo.tail, (stream)->fifo_size)) 23 #define fifo_count_to_end(stream) \ 24 (CIRC_CNT_TO_END(smp_load_acquire(&(stream)->fifo.head), (stream)->fifo.tail, (stream)->fifo_size)) 25 /* space available: */ 26 #define fifo_space(stream) \ 27 (CIRC_SPACE((stream)->fifo.head, (stream)->fifo.tail, (stream)->fifo_size)) 28 29 static int 30 msm_perfcntr_resume_locked(struct msm_perfcntr_stream *stream) 31 { 32 if (!stream) 33 return 0; 34 35 /* Reprogram SEL regs on highest priority rb: */ 36 struct msm_ringbuffer *ring = stream->gpu->rb[0]; 37 38 queue_work(ring->sched.submit_wq, &stream->sel_work); 39 40 hrtimer_start(&stream->sample_timer, 41 ns_to_ktime(stream->sample_period_ns), 42 HRTIMER_MODE_REL_PINNED); 43 44 return 0; 45 } 46 47 int 48 msm_perfcntr_resume(struct msm_gpu *gpu) 49 { 50 if (!gpu->perfcntrs) 51 return 0; 52 guard(mutex)(&gpu->perfcntr_lock); 53 return msm_perfcntr_resume_locked(gpu->perfcntrs->stream); 54 } 55 56 static void 57 msm_perfcntr_suspend_locked(struct msm_perfcntr_stream *stream) 58 { 59 if (!stream) 60 return; 61 62 hrtimer_cancel(&stream->sample_timer); 63 kthread_cancel_work_sync(&stream->sample_work); 64 65 /* 66 * We can't use cancel_work_sync() here, since sel_work acquires 67 * gpu->lock which (a) in suspend path can already be held, or 68 * (b) in release path would invert the order of gpu->lock and 69 * gpu->perfcntr_lock. Either would cause deadlock. 70 */ 71 cancel_work(&stream->sel_work); 72 73 stream->sel_fence = ++stream->gpu->perfcntrs->sel_seqno; 74 stream->seqno = 0; 75 } 76 77 void 78 msm_perfcntr_suspend(struct msm_gpu *gpu) 79 { 80 if (!gpu->perfcntrs) 81 return; 82 guard(mutex)(&gpu->perfcntr_lock); 83 msm_perfcntr_suspend_locked(gpu->perfcntrs->stream); 84 } 85 86 static int 87 msm_perfcntrs_stream_release(struct inode *inode, struct file *file) 88 { 89 struct msm_perfcntr_stream *stream = file->private_data; 90 struct msm_gpu *gpu = stream->gpu; 91 92 scoped_guard (mutex, &gpu->perfcntr_lock) { 93 struct msm_perfcntr_state *perfcntrs = gpu->perfcntrs; 94 95 msm_perfcntr_suspend_locked(stream); 96 perfcntrs->stream = NULL; 97 98 /* release previously allocated counters: */ 99 for (unsigned i = 0; i < gpu->num_perfcntr_groups; i++) 100 perfcntrs->groups[i]->allocated_counters = 0; 101 } 102 103 /* 104 * In the suspend path we use async cancel_work(), to avoid blocking 105 * on sel_work, which acquires gpu->lock (which could deadlock since 106 * other paths acquire gpu->lock before perfcntr_lock) or already 107 * hold gpu->lock. 108 * 109 * But since we are freeing the stream, after dropping perfcntr_lock 110 * we need to block until sel_work is done: 111 */ 112 cancel_work_sync(&stream->sel_work); 113 114 kfree(stream->group_idx); 115 kfree(stream->fifo.buf); 116 kfree(stream); 117 118 return 0; 119 } 120 121 static __poll_t 122 msm_perfcntrs_stream_poll(struct file *file, poll_table *wait) 123 { 124 struct msm_perfcntr_stream *stream = file->private_data; 125 __poll_t events = 0; 126 127 poll_wait(file, &stream->poll_wq, wait); 128 129 /* Are there samples to read? */ 130 if (fifo_count(stream) > 0) 131 events |= EPOLLIN; 132 133 return events; 134 } 135 136 static ssize_t 137 msm_perfcntrs_stream_read(struct file *file, char __user *buf, 138 size_t count, loff_t *ppos) 139 { 140 struct msm_perfcntr_stream *stream = file->private_data; 141 int ret; 142 143 if (!(file->f_flags & O_NONBLOCK)) { 144 ret = wait_event_interruptible(stream->poll_wq, 145 fifo_count(stream) > 0); 146 if (ret) 147 return ret; 148 } 149 150 guard(mutex)(&stream->read_lock); 151 152 struct circ_buf *fifo = &stream->fifo; 153 const char *fptr = &fifo->buf[fifo->tail]; 154 155 count = min_t(size_t, count, fifo_count_to_end(stream)); 156 if (!count) 157 return -EAGAIN; 158 if (copy_to_user(buf, fptr, count)) 159 return -EFAULT; 160 161 smp_store_release(&fifo->tail, (fifo->tail + count) & (stream->fifo_size - 1)); 162 *ppos += count; 163 164 return count; 165 } 166 167 static const struct file_operations stream_fops = { 168 .owner = THIS_MODULE, 169 .release = msm_perfcntrs_stream_release, 170 .poll = msm_perfcntrs_stream_poll, 171 .read = msm_perfcntrs_stream_read, 172 }; 173 174 static void 175 sel_worker(struct work_struct *w) 176 { 177 struct msm_perfcntr_stream *stream = 178 container_of(w, typeof(*stream), sel_work); 179 struct msm_gpu *gpu = stream->gpu; 180 /* Reprogram SEL regs on highest priority rb: */ 181 struct msm_ringbuffer *ring = stream->gpu->rb[0]; 182 183 /* 184 * If in the process of resuming, wait for that. Otherwise sel_worker 185 * which is enqueued in the resume path can be scheduled before the 186 * resume completes. 187 */ 188 pm_runtime_barrier(&gpu->pdev->dev); 189 190 /* 191 * sel_work could end up scheduled before suspend, but running 192 * after. See msm_perfcntr_suspend_locked() 193 * 194 * So if we end up running sel_work after the GPU is already 195 * suspended, just bail. It will be scheduled again after 196 * the GPU is resumed. 197 */ 198 if (!pm_runtime_get_if_active(&gpu->pdev->dev)) 199 return; 200 201 scoped_guard (mutex, &gpu->lock) { 202 guard(mutex)(&gpu->perfcntr_lock); 203 204 if (stream == gpu->perfcntrs->stream) { 205 msm_gpu_hw_init(gpu); 206 gpu->funcs->perfcntr_configure(gpu, ring, stream); 207 } 208 } 209 210 pm_runtime_put_autosuspend(&gpu->pdev->dev); 211 } 212 213 static void 214 sample_write(struct msm_perfcntr_stream *stream, int *head, const void *buf, size_t sz) 215 { 216 /* 217 * FIFO size is power-of-two, and guaranteed to have enough space to 218 * fit what we are writing. So we should not hit the wrap-around 219 * point writing things that are power-of-two sized 220 */ 221 WARN_ON(CIRC_SPACE_TO_END(*head, stream->fifo.tail, stream->fifo_size) < sz); 222 223 memcpy(&stream->fifo.buf[*head], buf, sz); 224 225 /* Advance head, wrapping around if necessary: */ 226 *head = (*head + sz) & (stream->fifo_size - 1); 227 } 228 229 static void 230 sample_write_u32(struct msm_perfcntr_stream *stream, int *head, uint32_t val) 231 { 232 sample_write(stream, head, &val, sizeof(val)); 233 } 234 235 static void 236 sample_write_u64(struct msm_perfcntr_stream *stream, int *head, uint64_t val) 237 { 238 sample_write(stream, head, &val, sizeof(val)); 239 } 240 241 static void 242 sample_worker(struct kthread_work *work) 243 { 244 struct msm_perfcntr_stream *stream = 245 container_of(work, typeof(*stream), sample_work); 246 struct msm_gpu *gpu = stream->gpu; 247 struct msm_rbmemptrs *memptrs = gpu->rb[0]->memptrs; 248 249 if (memptrs->perfcntr_fence != stream->sel_fence) 250 return; 251 252 /* 253 * Ensure we have enough space to capture a sample period's 254 * worth of data: 255 */ 256 if (stream->period_size > fifo_space(stream)) { 257 stream->seqno = 0; 258 return; 259 } 260 261 /* Inhibit IFPC while accessing registers: */ 262 if (gpu->funcs->sysprof_setup) 263 gpu->funcs->sysprof_setup(gpu, true); 264 265 if (gpu->funcs->perfcntr_flush) 266 gpu->funcs->perfcntr_flush(gpu); 267 268 /* Keep local copy of head to avoid updating fifo until the end: */ 269 int head = stream->fifo.head; 270 271 /* 272 * We expect the GPU to be powered at this point, as the timer 273 * and kthread work are canceled/flushed in the suspend path: 274 */ 275 sample_write_u64(stream, &head, 276 to_adreno_gpu(gpu)->funcs->get_timestamp(gpu)); 277 sample_write_u32(stream, &head, stream->seqno++); 278 sample_write_u32(stream, &head, 0); 279 280 for (unsigned i = 0; i < stream->nr_groups; i++) { 281 unsigned group_idx = msm_perfcntr_group_idx(stream, i); 282 unsigned base = msm_perfcntr_counter_base(stream, group_idx); 283 284 const struct msm_perfcntr_group *group = 285 &gpu->perfcntr_groups[group_idx]; 286 287 struct msm_perfcntr_group_state *group_state = 288 gpu->perfcntrs->groups[group_idx]; 289 290 unsigned nr = group_state->allocated_counters; 291 for (unsigned j = 0; j < nr; j++) { 292 const struct msm_perfcntr_counter *counter = 293 &group->counters[j + base]; 294 uint64_t val = gpu_read64(gpu, counter->counter_reg_lo); 295 sample_write_u64(stream, &head, val); 296 } 297 } 298 299 /* Re-enable IFPC: */ 300 if (gpu->funcs->sysprof_setup) 301 gpu->funcs->sysprof_setup(gpu, false); 302 303 smp_store_release(&stream->fifo.head, head); 304 wake_up_all(&stream->poll_wq); 305 } 306 307 static enum hrtimer_restart 308 sample_timer(struct hrtimer *hrtimer) 309 { 310 struct msm_perfcntr_stream *stream = 311 container_of(hrtimer, typeof(*stream), sample_timer); 312 313 kthread_queue_work(stream->gpu->worker, &stream->sample_work); 314 315 hrtimer_forward_now(hrtimer, ns_to_ktime(stream->sample_period_ns)); 316 317 return HRTIMER_RESTART; 318 } 319 320 static int 321 get_group_idx(struct msm_gpu *gpu, const char *name, size_t len) 322 { 323 for (unsigned i = 0; i < gpu->num_perfcntr_groups; i++) { 324 const struct msm_perfcntr_group *group = 325 &gpu->perfcntr_groups[i]; 326 if (!strncmp(group->name, name, len)) 327 return i; 328 } 329 330 return -1; 331 } 332 333 static int 334 get_available_counters(struct msm_gpu *gpu, int group_idx, uint32_t flags) 335 { 336 struct msm_perfcntr_state *perfcntrs = gpu->perfcntrs; 337 338 /* 339 * For local counter reservation, anything that is not used by 340 * global perfcntr stream is available: 341 */ 342 if (!(flags & MSM_PERFCNTR_STREAM)) { 343 return gpu->perfcntr_groups[group_idx].num_counters - 344 perfcntrs->groups[group_idx]->allocated_counters; 345 } 346 347 /* 348 * For global counter collection, anything that is not reserved by 349 * one or more contexts is available: 350 */ 351 guard(mutex)(&gpu->dev->filelist_mutex); 352 353 unsigned reserved_counters = 0; 354 struct drm_file *file; 355 356 list_for_each_entry (file, &gpu->dev->filelist, lhead) { 357 struct msm_context *ctx = file->driver_priv; 358 359 if (!ctx || !ctx->perfctx) 360 continue; 361 362 unsigned n = ctx->perfctx->reserved_counters[group_idx]; 363 reserved_counters = max(reserved_counters, n); 364 } 365 366 return gpu->perfcntr_groups[group_idx].num_counters - reserved_counters; 367 } 368 369 int 370 msm_ioctl_perfcntr_config(struct drm_device *dev, void *data, struct drm_file *file) 371 { 372 struct msm_drm_private *priv = dev->dev_private; 373 const struct drm_msm_perfcntr_config *args = data; 374 struct msm_context *ctx = file->driver_priv; 375 struct msm_gpu *gpu = priv->gpu; 376 int stream_fd = 0; 377 378 if (!gpu || !gpu->num_perfcntr_groups) 379 return -ENXIO; 380 381 struct msm_perfcntr_state *perfcntrs = gpu->perfcntrs; 382 383 /* 384 * Validate args that don't require locks/power first: 385 */ 386 387 if (args->flags & ~MSM_PERFCNTR_FLAGS) 388 return UERR(EINVAL, dev, "invalid flags"); 389 390 if (args->nr_groups && !args->group_stride) 391 return UERR(EINVAL, dev, "invalid group_stride"); 392 393 if (args->nr_groups > gpu->num_perfcntr_groups) 394 return UERR(EINVAL, dev, "too many groups"); 395 396 if (args->nr_groups && !args->groups) 397 return UERR(EINVAL, dev, "no groups"); 398 399 if (args->flags & MSM_PERFCNTR_STREAM) { 400 if (!perfmon_capable()) 401 return UERR(EPERM, dev, "invalid permissions"); 402 if (!args->nr_groups) 403 return UERR(EINVAL, dev, "invalid nr_groups"); 404 if (!args->period) 405 return UERR(EINVAL, dev, "invalid sampling period"); 406 if (args->bufsz_shift > const_ilog2(SZ_128M)) 407 return UERR(EINVAL, dev, "buffer size too big (>128M)"); 408 } else { 409 if (args->period) 410 return UERR(EINVAL, dev, "sampling period not allowed"); 411 if (args->bufsz_shift) 412 return UERR(EINVAL, dev, "sample buf size not allowed"); 413 } 414 415 /* 416 * To avoid iterating over the groups multiple times, allocate and setup 417 * both a ctx and global stream object. Only one of the two will be 418 * kept in the end. 419 */ 420 421 struct msm_perfcntr_context_state *perfctx __free(kfree) = kzalloc( 422 struct_size(perfctx, reserved_counters, gpu->num_perfcntr_groups), 423 GFP_KERNEL); 424 if (!perfctx) 425 return -ENOMEM; 426 427 struct msm_perfcntr_stream *stream __free(kfree) = kzalloc_obj(*stream); 428 if (!stream) 429 return -ENOMEM; 430 431 uint8_t *nr_counters __free(kfree) = kzalloc_objs(uint8_t, gpu->num_perfcntr_groups); 432 if (!nr_counters) 433 return -ENOMEM; 434 435 uint32_t *group_idx __free(kfree) = kzalloc_objs(uint32_t, args->nr_groups); 436 if (!group_idx) 437 return -ENOMEM; 438 439 stream->gpu = gpu; 440 stream->sample_period_ns = args->period; 441 stream->nr_groups = args->nr_groups; 442 stream->fifo_size = 1ull << args->bufsz_shift; 443 444 mutex_init(&stream->read_lock); 445 446 guard(mutex)(&gpu->perfcntr_lock); 447 448 if (args->flags & MSM_PERFCNTR_STREAM) { 449 if (perfcntrs->stream) 450 return UERR(EBUSY, dev, "perfcntr stream already open"); 451 } 452 453 size_t bufsz = 16; /* header size includes seqno and 64b timestamp: */ 454 int ret = 0; 455 456 for (unsigned i = 0; i < args->nr_groups; i++) { 457 struct drm_msm_perfcntr_group g = {0}; 458 size_t sz = min_t(size_t, args->group_stride, sizeof(g)); 459 void __user *userptr = 460 u64_to_user_ptr(args->groups + (i * args->group_stride)); 461 462 if (copy_from_user(&g, userptr, sz)) 463 return -EFAULT; 464 465 if (g.pad) 466 return UERR(EINVAL, dev, "groups[%d]: invalid pad", i); 467 468 int idx = get_group_idx(gpu, g.group_name, sizeof(g.group_name)); 469 470 if (idx < 0) 471 return UERR(EINVAL, dev, "groups[%d]: unknown group", i); 472 473 if (nr_counters[idx]) 474 return UERR(EINVAL, dev, "groups[%d]: duplicate group", i); 475 476 if (g.nr_countables > gpu->perfcntr_groups[idx].num_counters) 477 return UERR(EINVAL, dev, "groups[%d]: too many counters", i); 478 479 if (args->flags & MSM_PERFCNTR_STREAM) { 480 if (g.nr_countables && !g.countables) 481 return UERR(EINVAL, dev, "groups[%d]: no countables", i); 482 } else { 483 if (g.countables) 484 return UERR(EINVAL, dev, "groups[%d]: countables should be NULL", i); 485 } 486 487 int avail_counters = get_available_counters(gpu, idx, args->flags); 488 if (g.nr_countables > avail_counters) { 489 /* 490 * Defer error return until we process all groups, in 491 * case there are other E2BIG groups: 492 */ 493 ret = UERR(E2BIG, dev, "groups[%d]: too few counters available", i); 494 495 if (args->flags & MSM_PERFCNTR_UPDATE) { 496 /* Let userspace know how many counters are actually avail: */ 497 g.nr_countables = avail_counters; 498 if (copy_to_user(userptr, &g, sz)) 499 return -EFAULT; 500 } 501 } 502 503 group_idx[i] = idx; 504 perfctx->reserved_counters[idx] = g.nr_countables; 505 506 /* +1 to catch duplicate zero sized groups: */ 507 nr_counters[idx] = g.nr_countables + 1; 508 509 if (args->flags & MSM_PERFCNTR_STREAM) { 510 size_t sz = sizeof(uint32_t) * g.nr_countables; 511 void __user *userptr = u64_to_user_ptr(g.countables); 512 513 if (copy_from_user(perfcntrs->groups[idx]->countables, userptr, sz)) 514 return -EFAULT; 515 516 /* Samples are 64b per countable: */ 517 bufsz += 2 * sz; 518 } 519 } 520 521 if (ret) 522 return ret; 523 524 if (args->flags & MSM_PERFCNTR_STREAM) { 525 /* 526 * Validate requested buffer size is large enough for at least 527 * a single sample period. 528 * 529 * Note the circ_buf implementation needs to be 1 byte larger 530 * than max it can hold (see CIRC_SPACE()). 531 */ 532 if (stream->fifo_size <= bufsz) 533 return UERR(EINVAL, dev, "required buffer size: %zu", bufsz); 534 535 /* There aren't enough counters to hit this limit: */ 536 WARN_ON(bufsz > SZ_128M); 537 538 stream->period_size = bufsz; 539 540 void *buf __free(kfree) = kmalloc(stream->fifo_size, GFP_KERNEL); 541 if (!buf) 542 return -ENOMEM; 543 544 FD_PREPARE(fdf, O_CLOEXEC, 545 anon_inode_getfile("[msm_perfcntrs]", &stream_fops, stream, 0)); 546 if (fdf.err) 547 return fdf.err; 548 549 INIT_WORK(&stream->sel_work, sel_worker); 550 kthread_init_work(&stream->sample_work, sample_worker); 551 init_waitqueue_head(&stream->poll_wq); 552 hrtimer_setup(&stream->sample_timer, sample_timer, 553 CLOCK_MONOTONIC, HRTIMER_MODE_REL); 554 555 stream->sel_fence = ++perfcntrs->sel_seqno; 556 stream->group_idx = no_free_ptr(group_idx); 557 stream->fifo.buf = no_free_ptr(buf); 558 559 /* commit the allocated counters, subtracting off original +1: */ 560 for (unsigned i = 0; i < gpu->num_perfcntr_groups; i++) 561 perfcntrs->groups[i]->allocated_counters = nr_counters[i] - 1; 562 563 perfcntrs->stream = no_free_ptr(stream); 564 565 msm_perfcntr_resume_locked(perfcntrs->stream); 566 567 stream_fd = fd_publish(fdf); 568 } else { 569 kfree(ctx->perfctx); 570 ctx->perfctx = no_free_ptr(perfctx); 571 } 572 573 return stream_fd; 574 } 575 576 /** 577 * msm_perfcntr_group_idx - map idx of perfcntr group to group_idx 578 * @stream: The global perfcntr stream 579 * @n: The requested group_idx 580 * 581 * The PERFCNTR_CONFIG ioctl requested N counters/countables per perfcntr 582 * group, but the order of groups is not required to match the order they 583 * are defined in the perfcntr tables (which is not stable/UABI, only the 584 * group names are UABI). 585 * 586 * But the order samples are returned in the stream should match the 587 * order they are requested in the PERFCNTR_CONFIG ioctl. This helper 588 * handles the order remapping. 589 * 590 * Returns an index into gpu->perfcntr_groups[] and perfcntrs->groups[]. 591 */ 592 uint32_t 593 msm_perfcntr_group_idx(const struct msm_perfcntr_stream *stream, uint32_t n) 594 { 595 WARN_ON_ONCE(n >= stream->nr_groups); 596 return stream->group_idx[n]; 597 } 598 599 /** 600 * msm_perfcntr_counter_base - get idx of the first counter in group 601 * @stream: The global perfcntr stream 602 * @group_idx: the index of the counter group 603 * 604 * For global counter collection, counters are allocated from the end 605 * (last counter) while UMD allocates them from the start (0..N-1). 606 * Since UMD always allocated them from the start this also minimizes 607 * the chance of conflict when using old UMD which predates 608 * PERFCNTR_CONFIG ioctl. 609 * 610 * Returns the index of first counter to use. An index into 611 * msm_perfcntr_group::counters[]. 612 */ 613 uint32_t 614 msm_perfcntr_counter_base(const struct msm_perfcntr_stream *stream, uint32_t group_idx) 615 { 616 struct msm_gpu *gpu = stream->gpu; 617 struct msm_perfcntr_state *perfcntrs = gpu->perfcntrs; 618 unsigned num_counters = gpu->perfcntr_groups[group_idx].num_counters; 619 unsigned allocated_counters = perfcntrs->groups[group_idx]->allocated_counters; 620 621 return num_counters - allocated_counters; 622 } 623 624 static void 625 __msm_perfcntr_cleanup(struct msm_gpu *gpu, struct msm_perfcntr_state *perfcntrs) 626 { 627 struct device *dev = &gpu->pdev->dev; 628 629 for (unsigned i = 0; i < gpu->num_perfcntr_groups; i++) 630 devm_kfree(dev, perfcntrs->groups[i]); 631 632 devm_kfree(dev, perfcntrs); 633 } 634 635 void 636 msm_perfcntr_cleanup(struct msm_gpu *gpu) 637 { 638 if (!gpu->perfcntrs) 639 return; 640 641 __msm_perfcntr_cleanup(gpu, gpu->perfcntrs); 642 gpu->perfcntrs = NULL; 643 } 644 645 struct msm_perfcntr_state * 646 msm_perfcntr_init(struct msm_gpu *gpu) 647 { 648 struct msm_perfcntr_state *perfcntrs; 649 struct device *dev = &gpu->pdev->dev; 650 size_t sz; 651 652 sz = struct_size(perfcntrs, groups, gpu->num_perfcntr_groups); 653 perfcntrs = devm_kzalloc(dev, sz, GFP_KERNEL); 654 if (!perfcntrs) 655 return ERR_PTR(-ENOMEM); 656 657 for (unsigned i = 0; i < gpu->num_perfcntr_groups; i++) { 658 const struct msm_perfcntr_group *group = 659 &gpu->perfcntr_groups[i]; 660 661 sz = struct_size(perfcntrs->groups[i], countables, group->num_counters); 662 perfcntrs->groups[i] = devm_kzalloc(dev, sz, GFP_KERNEL); 663 if (!perfcntrs->groups[i]) { 664 __msm_perfcntr_cleanup(gpu, perfcntrs); 665 return ERR_PTR(-ENOMEM); 666 } 667 } 668 669 return perfcntrs; 670 } 671