1 // SPDX-License-Identifier: GPL-2.0 or MIT 2 /* Copyright 2023 Collabora ltd. */ 3 4 #include <drm/drm_debugfs.h> 5 #include <drm/drm_drv.h> 6 #include <drm/drm_exec.h> 7 #include <drm/drm_file.h> 8 #include <drm/drm_managed.h> 9 #include <drm/drm_print.h> 10 #include <drm/gpu_scheduler.h> 11 #include <drm/panthor_drm.h> 12 13 #include <linux/build_bug.h> 14 #include <linux/cleanup.h> 15 #include <linux/clk.h> 16 #include <linux/delay.h> 17 #include <linux/dma-mapping.h> 18 #include <linux/dma-resv.h> 19 #include <linux/firmware.h> 20 #include <linux/interrupt.h> 21 #include <linux/io.h> 22 #include <linux/iopoll.h> 23 #include <linux/iosys-map.h> 24 #include <linux/module.h> 25 #include <linux/platform_device.h> 26 #include <linux/pm_runtime.h> 27 #include <linux/rcupdate.h> 28 29 #include "panthor_devfreq.h" 30 #include "panthor_device.h" 31 #include "panthor_fw.h" 32 #include "panthor_fw_regs.h" 33 #include "panthor_gem.h" 34 #include "panthor_gpu.h" 35 #include "panthor_gpu_regs.h" 36 #include "panthor_heap.h" 37 #include "panthor_mmu.h" 38 #include "panthor_sched.h" 39 40 /** 41 * DOC: Scheduler 42 * 43 * Mali CSF hardware adopts a firmware-assisted scheduling model, where 44 * the firmware takes care of scheduling aspects, to some extent. 45 * 46 * The scheduling happens at the scheduling group level, each group 47 * contains 1 to N queues (N is FW/hardware dependent, and exposed 48 * through the firmware interface). Each queue is assigned a command 49 * stream ring buffer, which serves as a way to get jobs submitted to 50 * the GPU, among other things. 51 * 52 * The firmware can schedule a maximum of M groups (M is FW/hardware 53 * dependent, and exposed through the firmware interface). Passed 54 * this maximum number of groups, the kernel must take care of 55 * rotating the groups passed to the firmware so every group gets 56 * a chance to have his queues scheduled for execution. 57 * 58 * The current implementation only supports with kernel-mode queues. 59 * In other terms, userspace doesn't have access to the ring-buffer. 60 * Instead, userspace passes indirect command stream buffers that are 61 * called from the queue ring-buffer by the kernel using a pre-defined 62 * sequence of command stream instructions to ensure the userspace driver 63 * always gets consistent results (cache maintenance, 64 * synchronization, ...). 65 * 66 * We rely on the drm_gpu_scheduler framework to deal with job 67 * dependencies and submission. As any other driver dealing with a 68 * FW-scheduler, we use the 1:1 entity:scheduler mode, such that each 69 * entity has its own job scheduler. When a job is ready to be executed 70 * (all its dependencies are met), it is pushed to the appropriate 71 * queue ring-buffer, and the group is scheduled for execution if it 72 * wasn't already active. 73 * 74 * Kernel-side group scheduling is timeslice-based. When we have less 75 * groups than there are slots, the periodic tick is disabled and we 76 * just let the FW schedule the active groups. When there are more 77 * groups than slots, we let each group a chance to execute stuff for 78 * a given amount of time, and then re-evaluate and pick new groups 79 * to schedule. The group selection algorithm is based on 80 * priority+round-robin. 81 * 82 * Even though user-mode queues is out of the scope right now, the 83 * current design takes them into account by avoiding any guess on the 84 * group/queue state that would be based on information we wouldn't have 85 * if userspace was in charge of the ring-buffer. That's also one of the 86 * reason we don't do 'cooperative' scheduling (encoding FW group slot 87 * reservation as dma_fence that would be returned from the 88 * drm_gpu_scheduler::prepare_job() hook, and treating group rotation as 89 * a queue of waiters, ordered by job submission order). This approach 90 * would work for kernel-mode queues, but would make user-mode queues a 91 * lot more complicated to retrofit. 92 */ 93 94 #define JOB_TIMEOUT_MS 5000 95 96 #define MAX_CSG_PRIO 0xf 97 98 #define NUM_INSTRS_PER_CACHE_LINE (64 / sizeof(u64)) 99 #define MAX_INSTRS_PER_JOB 24 100 101 struct panthor_group; 102 103 /** 104 * struct panthor_csg_slot - Command stream group slot 105 * 106 * This represents a FW slot for a scheduling group. 107 */ 108 struct panthor_csg_slot { 109 /** @group: Scheduling group bound to this slot. */ 110 struct panthor_group *group; 111 112 /** @priority: Group priority. */ 113 u8 priority; 114 }; 115 116 /** 117 * enum panthor_csg_priority - Group priority 118 */ 119 enum panthor_csg_priority { 120 /** @PANTHOR_CSG_PRIORITY_LOW: Low priority group. */ 121 PANTHOR_CSG_PRIORITY_LOW = 0, 122 123 /** @PANTHOR_CSG_PRIORITY_MEDIUM: Medium priority group. */ 124 PANTHOR_CSG_PRIORITY_MEDIUM, 125 126 /** @PANTHOR_CSG_PRIORITY_HIGH: High priority group. */ 127 PANTHOR_CSG_PRIORITY_HIGH, 128 129 /** 130 * @PANTHOR_CSG_PRIORITY_RT: Real-time priority group. 131 * 132 * Real-time priority allows one to preempt scheduling of other 133 * non-real-time groups. When such a group becomes executable, 134 * it will evict the group with the lowest non-rt priority if 135 * there's no free group slot available. 136 */ 137 PANTHOR_CSG_PRIORITY_RT, 138 139 /** @PANTHOR_CSG_PRIORITY_COUNT: Number of priority levels. */ 140 PANTHOR_CSG_PRIORITY_COUNT, 141 }; 142 143 /** 144 * struct panthor_scheduler - Object used to manage the scheduler 145 */ 146 struct panthor_scheduler { 147 /** @ptdev: Device. */ 148 struct panthor_device *ptdev; 149 150 /** 151 * @wq: Workqueue used by our internal scheduler logic and 152 * drm_gpu_scheduler. 153 * 154 * Used for the scheduler tick, group update or other kind of FW 155 * event processing that can't be handled in the threaded interrupt 156 * path. Also passed to the drm_gpu_scheduler instances embedded 157 * in panthor_queue. 158 */ 159 struct workqueue_struct *wq; 160 161 /** 162 * @heap_alloc_wq: Workqueue used to schedule tiler_oom works. 163 * 164 * We have a queue dedicated to heap chunk allocation works to avoid 165 * blocking the rest of the scheduler if the allocation tries to 166 * reclaim memory. 167 */ 168 struct workqueue_struct *heap_alloc_wq; 169 170 /** @tick_work: Work executed on a scheduling tick. */ 171 struct delayed_work tick_work; 172 173 /** 174 * @sync_upd_work: Work used to process synchronization object updates. 175 * 176 * We use this work to unblock queues/groups that were waiting on a 177 * synchronization object. 178 */ 179 struct work_struct sync_upd_work; 180 181 /** 182 * @resched_target: When the next tick should occur. 183 * 184 * Expressed in jiffies. 185 */ 186 u64 resched_target; 187 188 /** 189 * @last_tick: When the last tick occurred. 190 * 191 * Expressed in jiffies. 192 */ 193 u64 last_tick; 194 195 /** @tick_period: Tick period in jiffies. */ 196 u64 tick_period; 197 198 /** 199 * @lock: Lock protecting access to all the scheduler fields. 200 * 201 * Should be taken in the tick work, the irq handler, and anywhere the @groups 202 * fields are touched. 203 */ 204 struct mutex lock; 205 206 /** @groups: Various lists used to classify groups. */ 207 struct { 208 /** 209 * @groups.runnable: Runnable group lists. 210 * 211 * When a group has queues that want to execute something, 212 * its panthor_group::run_node should be inserted here. 213 * 214 * One list per-priority. 215 */ 216 struct list_head runnable[PANTHOR_CSG_PRIORITY_COUNT]; 217 218 /** 219 * @groups.idle: Idle group lists. 220 * 221 * When all queues of a group are idle (either because they 222 * have nothing to execute, or because they are blocked), the 223 * panthor_group::run_node field should be inserted here. 224 * 225 * One list per-priority. 226 */ 227 struct list_head idle[PANTHOR_CSG_PRIORITY_COUNT]; 228 229 /** 230 * @groups.waiting: List of groups whose queues are blocked on a 231 * synchronization object. 232 * 233 * Insert panthor_group::wait_node here when a group is waiting 234 * for synchronization objects to be signaled. 235 * 236 * This list is evaluated in the @sync_upd_work work. 237 */ 238 struct list_head waiting; 239 } groups; 240 241 /** 242 * @events_lock: Lock taken when processing events. 243 * 244 * This also needs to be taken when csg_slots are updated, to make sure 245 * the event processing logic doesn't touch groups that have left the CSG 246 * slot. 247 */ 248 spinlock_t events_lock; 249 250 /** 251 * @csg_slots: FW command stream group slots. 252 * 253 * Updates to the group binding must happen with both 254 * panthor_scheduler::lock and panthor_scheduler::events_lock held. 255 * The group binding may therefore be read while holding either lock. 256 * Other slot fields are protected by panthor_scheduler::lock. 257 */ 258 struct panthor_csg_slot csg_slots[MAX_CSGS]; 259 260 /** @csg_slot_count: Number of command stream group slots exposed by the FW. */ 261 u32 csg_slot_count; 262 263 /** @cs_slot_count: Number of command stream slot per group slot exposed by the FW. */ 264 u32 cs_slot_count; 265 266 /** @as_slot_count: Number of address space slots supported by the MMU. */ 267 u32 as_slot_count; 268 269 /** @used_csg_slot_count: Number of command stream group slot currently used. */ 270 u32 used_csg_slot_count; 271 272 /** @sb_slot_count: Number of scoreboard slots. */ 273 u32 sb_slot_count; 274 275 /** 276 * @might_have_idle_groups: True if an active group might have become idle. 277 * 278 * This will force a tick, so other runnable groups can be scheduled if one 279 * or more active groups became idle. 280 */ 281 bool might_have_idle_groups; 282 283 /** @pm: Power management related fields. */ 284 struct { 285 /** @pm.has_ref: True if the scheduler owns a runtime PM reference. */ 286 bool has_ref; 287 } pm; 288 289 /** @reset: Reset related fields. */ 290 struct { 291 /** @reset.lock: Lock protecting the other reset fields. */ 292 struct mutex lock; 293 294 /** 295 * @reset.in_progress: True if a reset is in progress. 296 * 297 * Set to true in panthor_sched_pre_reset() and back to false in 298 * panthor_sched_post_reset(). 299 */ 300 atomic_t in_progress; 301 302 /** 303 * @reset.stopped_groups: List containing all groups that were stopped 304 * before a reset. 305 * 306 * Insert panthor_group::run_node in the pre_reset path. 307 */ 308 struct list_head stopped_groups; 309 } reset; 310 }; 311 312 /** 313 * struct panthor_syncobj_32b - 32-bit FW synchronization object 314 */ 315 struct panthor_syncobj_32b { 316 /** @seqno: Sequence number. */ 317 u32 seqno; 318 319 /** 320 * @status: Status. 321 * 322 * Not zero on failure. 323 */ 324 u32 status; 325 }; 326 327 /** 328 * struct panthor_syncobj_64b - 64-bit FW synchronization object 329 */ 330 struct panthor_syncobj_64b { 331 /** @seqno: Sequence number. */ 332 u64 seqno; 333 334 /** 335 * @status: Status. 336 * 337 * Not zero on failure. 338 */ 339 u32 status; 340 341 /** @pad: MBZ. */ 342 u32 pad; 343 }; 344 345 /** 346 * struct panthor_queue - Execution queue 347 */ 348 struct panthor_queue { 349 /** @scheduler: DRM scheduler used for this queue. */ 350 struct drm_gpu_scheduler scheduler; 351 352 /** @entity: DRM scheduling entity used for this queue. */ 353 struct drm_sched_entity entity; 354 355 /** @name: DRM scheduler name for this queue. */ 356 char *name; 357 358 /** @timeout: Queue timeout related fields. */ 359 struct { 360 /** @timeout.work: Work executed when a queue timeout occurs. */ 361 struct delayed_work work; 362 363 /** 364 * @timeout.remaining: Time remaining before a queue timeout. 365 * 366 * When the timer is running, this value is set to MAX_SCHEDULE_TIMEOUT. 367 * When the timer is suspended, it's set to the time remaining when the 368 * timer was suspended. 369 */ 370 unsigned long remaining; 371 } timeout; 372 373 /** 374 * @doorbell_id: Doorbell assigned to this queue. 375 * 376 * Right now, all groups share the same doorbell, and the doorbell ID 377 * is assigned to group_slot + 1 when the group is assigned a slot. But 378 * we might decide to provide fine grained doorbell assignment at some 379 * point, so don't have to wake up all queues in a group every time one 380 * of them is updated. 381 */ 382 u8 doorbell_id; 383 384 /** 385 * @priority: Priority of the queue inside the group. 386 * 387 * Must be less than 16 (Only 4 bits available). 388 */ 389 u8 priority; 390 #define CSF_MAX_QUEUE_PRIO GENMASK(3, 0) 391 392 /** @ringbuf: Command stream ring-buffer. */ 393 struct panthor_kernel_bo *ringbuf; 394 395 /** @iface: Firmware interface. */ 396 struct { 397 /** @iface.mem: FW memory allocated for this interface. */ 398 struct panthor_kernel_bo *mem; 399 400 /** @iface.input: Input interface. */ 401 struct panthor_fw_ringbuf_input_iface *input; 402 403 /** @iface.output: Output interface. */ 404 const struct panthor_fw_ringbuf_output_iface *output; 405 406 /** @iface.input_fw_va: FW virtual address of the input interface buffer. */ 407 u32 input_fw_va; 408 409 /** @iface.output_fw_va: FW virtual address of the output interface buffer. */ 410 u32 output_fw_va; 411 } iface; 412 413 /** 414 * @syncwait: Stores information about the synchronization object this 415 * queue is waiting on. 416 */ 417 struct { 418 /** @syncwait.gpu_va: GPU address of the synchronization object. */ 419 u64 gpu_va; 420 421 /** @syncwait.ref: Reference value to compare against. */ 422 u64 ref; 423 424 /** @syncwait.gt: True if this is a greater-than test. */ 425 bool gt; 426 427 /** @syncwait.sync64: True if this is a 64-bit sync object. */ 428 bool sync64; 429 430 /** @syncwait.obj: Buffer object holding the synchronization object. */ 431 struct drm_gem_object *obj; 432 433 /** @syncwait.offset: Offset of the synchronization object inside @bo. */ 434 u64 offset; 435 436 /** 437 * @syncwait.kmap: Kernel mapping of the buffer object holding the 438 * synchronization object. 439 */ 440 void *kmap; 441 } syncwait; 442 443 /** @fence_ctx: Fence context fields. */ 444 struct { 445 /** @fence_ctx.lock: Used to protect access to all fences allocated by this context. */ 446 spinlock_t lock; 447 448 /** 449 * @fence_ctx.id: Fence context ID. 450 * 451 * Allocated with dma_fence_context_alloc(). 452 */ 453 u64 id; 454 455 /** @fence_ctx.seqno: Sequence number of the last initialized fence. */ 456 atomic64_t seqno; 457 458 /** 459 * @fence_ctx.last_fence: Fence of the last submitted job. 460 * 461 * We return this fence when we get an empty command stream. 462 * This way, we are guaranteed that all earlier jobs have completed 463 * when drm_sched_job::s_fence::finished without having to feed 464 * the CS ring buffer with a dummy job that only signals the fence. 465 */ 466 struct dma_fence *last_fence; 467 468 /** 469 * @fence_ctx.in_flight_jobs: List containing all in-flight jobs. 470 * 471 * Used to keep track and signal panthor_job::done_fence when the 472 * synchronization object attached to the queue is signaled. 473 */ 474 struct list_head in_flight_jobs; 475 } fence_ctx; 476 477 /** @profiling: Job profiling data slots and access information. */ 478 struct { 479 /** @profiling.slots: Kernel BO holding the slots. */ 480 struct panthor_kernel_bo *slots; 481 482 /** @profiling.slot_count: Number of jobs ringbuffer can hold at once. */ 483 u32 slot_count; 484 485 /** @profiling.seqno: Index of the next available profiling information slot. */ 486 u32 seqno; 487 } profiling; 488 }; 489 490 /** 491 * enum panthor_group_state - Scheduling group state. 492 */ 493 enum panthor_group_state { 494 /** @PANTHOR_CS_GROUP_CREATED: Group was created, but not scheduled yet. */ 495 PANTHOR_CS_GROUP_CREATED, 496 497 /** @PANTHOR_CS_GROUP_ACTIVE: Group is currently scheduled. */ 498 PANTHOR_CS_GROUP_ACTIVE, 499 500 /** 501 * @PANTHOR_CS_GROUP_SUSPENDED: Group was scheduled at least once, but is 502 * inactive/suspended right now. 503 */ 504 PANTHOR_CS_GROUP_SUSPENDED, 505 506 /** 507 * @PANTHOR_CS_GROUP_TERMINATED: Group was terminated. 508 * 509 * Can no longer be scheduled. The only allowed action is a destruction. 510 */ 511 PANTHOR_CS_GROUP_TERMINATED, 512 513 /** 514 * @PANTHOR_CS_GROUP_UNKNOWN_STATE: Group is an unknown state. 515 * 516 * The FW returned an inconsistent state. The group is flagged unusable 517 * and can no longer be scheduled. The only allowed action is a 518 * destruction. 519 * 520 * When that happens, we also schedule a FW reset, to start from a fresh 521 * state. 522 */ 523 PANTHOR_CS_GROUP_UNKNOWN_STATE, 524 }; 525 526 /** 527 * struct panthor_group - Scheduling group object 528 */ 529 struct panthor_group { 530 /** @refcount: Reference count */ 531 struct kref refcount; 532 533 /** @ptdev: Device. */ 534 struct panthor_device *ptdev; 535 536 /** @vm: VM bound to the group. */ 537 struct panthor_vm *vm; 538 539 /** @compute_core_mask: Mask of shader cores that can be used for compute jobs. */ 540 u64 compute_core_mask; 541 542 /** @fragment_core_mask: Mask of shader cores that can be used for fragment jobs. */ 543 u64 fragment_core_mask; 544 545 /** @tiler_core_mask: Mask of tiler cores that can be used for tiler jobs. */ 546 u64 tiler_core_mask; 547 548 /** @max_compute_cores: Maximum number of shader cores used for compute jobs. */ 549 u8 max_compute_cores; 550 551 /** @max_fragment_cores: Maximum number of shader cores used for fragment jobs. */ 552 u8 max_fragment_cores; 553 554 /** @max_tiler_cores: Maximum number of tiler cores used for tiler jobs. */ 555 u8 max_tiler_cores; 556 557 /** @priority: Group priority (check panthor_csg_priority). */ 558 u8 priority; 559 560 /** @blocked_queues: Bitmask reflecting the blocked queues. */ 561 u32 blocked_queues; 562 563 /** @idle_queues: Bitmask reflecting the idle queues. */ 564 u32 idle_queues; 565 566 /** 567 * @fatal_queues: Bitmask reflecting the queues that hit a fatal exception. 568 * 569 * This is an atomic because we don't want to acquire the events_lock 570 * every time we need to check the group state. 571 */ 572 atomic_t fatal_queues; 573 574 /** @tiler_oom: Mask of queues that have a tiler OOM event to process. */ 575 atomic_t tiler_oom; 576 577 /** @queue_count: Number of queues in this group. */ 578 u32 queue_count; 579 580 /** @queues: Queues owned by this group. */ 581 struct panthor_queue *queues[MAX_CS_PER_CSG]; 582 583 /** 584 * @csg_id: ID of the FW group slot. 585 * 586 * -1 when the group is not scheduled/active. 587 */ 588 int csg_id; 589 590 /** 591 * @destroyed: True when the group has been destroyed. 592 * 593 * If a group is destroyed it becomes useless: no further jobs can be submitted 594 * to its queues. We simply wait for all references to be dropped so we can 595 * release the group object. 596 */ 597 bool destroyed; 598 599 /** 600 * @timedout: True when a timeout occurred on any of the queues owned by 601 * this group. 602 * 603 * Timeouts can be reported by drm_sched or by the FW. If a reset is required, 604 * and the group can't be suspended, this also leads to a timeout. In any case, 605 * any timeout situation is unrecoverable, and the group becomes useless. We 606 * simply wait for all references to be dropped so we can release the group 607 * object. 608 * 609 * This is an atomic because it can be set from both a scheduling context 610 * (protected with panthor_scheduler::lock) and an event processing context 611 * (protected with panthor_scheduler::events_lock). We could protect access 612 * with the events_lock, but this is simpler to make it an atomic since the 613 * only allowed transition is false -> true. 614 */ 615 atomic_t timedout; 616 617 /** 618 * @innocent: True when the group becomes unusable because the group suspension 619 * failed during a reset. 620 * 621 * Sometimes the FW was put in a bad state by other groups, causing the group 622 * suspension happening in the reset path to fail. In that case, we consider the 623 * group innocent. 624 */ 625 bool innocent; 626 627 /** 628 * @syncobjs: Pool of per-queue synchronization objects. 629 * 630 * One sync object per queue. The position of the sync object is 631 * determined by the queue index. 632 */ 633 struct panthor_kernel_bo *syncobjs; 634 635 /** @fdinfo: Per-file info exposed through /proc/<process>/fdinfo */ 636 struct { 637 /** @fdinfo.data: Total sampled values for jobs in queues from this group. */ 638 struct panthor_gpu_usage data; 639 640 /** 641 * @fdinfo.lock: Spinlock to govern concurrent access from drm file's fdinfo 642 * callback and job post-completion processing function 643 */ 644 spinlock_t lock; 645 646 /** @fdinfo.kbo_sizes: Aggregate size of private kernel BO's held by the group. */ 647 size_t kbo_sizes; 648 } fdinfo; 649 650 /** @task_info: Info of current->group_leader that created the group. */ 651 struct { 652 /** @task_info.pid: pid of current->group_leader */ 653 pid_t pid; 654 655 /** @task_info.comm: comm of current->group_leader */ 656 char comm[TASK_COMM_LEN]; 657 } task_info; 658 659 /** @state: Group state. */ 660 enum panthor_group_state state; 661 662 /** 663 * @suspend_buf: Suspend buffer. 664 * 665 * Stores the state of the group and its queues when a group is suspended. 666 * Used at resume time to restore the group in its previous state. 667 * 668 * The size of the suspend buffer is exposed through the FW interface. 669 */ 670 struct panthor_kernel_bo *suspend_buf; 671 672 /** 673 * @protm_suspend_buf: Protection mode suspend buffer. 674 * 675 * Stores the state of the group and its queues when a group that's in 676 * protection mode is suspended. 677 * 678 * Used at resume time to restore the group in its previous state. 679 * 680 * The size of the protection mode suspend buffer is exposed through the 681 * FW interface. 682 */ 683 struct panthor_kernel_bo *protm_suspend_buf; 684 685 /** @tiler_oom_work: Work used to process tiler OOM events happening on this group. */ 686 struct work_struct tiler_oom_work; 687 688 /** @term_work: Work used to finish the group termination procedure. */ 689 struct work_struct term_work; 690 691 /** 692 * @release_work: Work used to release group resources. 693 * 694 * We need to postpone the group release to avoid a deadlock when 695 * the last ref is released in the tick work. 696 */ 697 struct work_struct release_work; 698 699 /** 700 * @run_node: Node used to insert the group in the 701 * panthor_group::groups::{runnable,idle} and 702 * panthor_group::reset.stopped_groups lists. 703 */ 704 struct list_head run_node; 705 706 /** 707 * @wait_node: Node used to insert the group in the 708 * panthor_group::groups::waiting list. 709 */ 710 struct list_head wait_node; 711 }; 712 713 struct panthor_job_profiling_data { 714 struct { 715 u64 before; 716 u64 after; 717 } cycles; 718 719 struct { 720 u64 before; 721 u64 after; 722 } time; 723 }; 724 725 /** 726 * group_queue_work() - Queue a group work 727 * @group: Group to queue the work for. 728 * @wname: Work name. 729 * 730 * Grabs a ref and queue a work item to the scheduler workqueue. If 731 * the work was already queued, we release the reference we grabbed. 732 * 733 * Work callbacks must release the reference we grabbed here. 734 */ 735 #define group_queue_work(group, wname) \ 736 do { \ 737 group_get(group); \ 738 if (!queue_work((group)->ptdev->scheduler->wq, &(group)->wname ## _work)) \ 739 group_put(group); \ 740 } while (0) 741 742 /** 743 * sched_queue_work() - Queue a scheduler work. 744 * @sched: Scheduler object. 745 * @wname: Work name. 746 * 747 * Conditionally queues a scheduler work if no reset is pending/in-progress. 748 */ 749 #define sched_queue_work(sched, wname) \ 750 do { \ 751 if (!atomic_read(&(sched)->reset.in_progress) && \ 752 !panthor_device_reset_is_pending((sched)->ptdev)) \ 753 queue_work((sched)->wq, &(sched)->wname ## _work); \ 754 } while (0) 755 756 /** 757 * sched_queue_delayed_work() - Queue a scheduler delayed work. 758 * @sched: Scheduler object. 759 * @wname: Work name. 760 * @delay: Work delay in jiffies. 761 * 762 * Conditionally queues a scheduler delayed work if no reset is 763 * pending/in-progress. 764 */ 765 #define sched_queue_delayed_work(sched, wname, delay) \ 766 do { \ 767 if (!atomic_read(&sched->reset.in_progress) && \ 768 !panthor_device_reset_is_pending((sched)->ptdev)) \ 769 mod_delayed_work((sched)->wq, &(sched)->wname ## _work, delay); \ 770 } while (0) 771 772 /* 773 * We currently set the maximum of groups per file to an arbitrary low value. 774 * But this can be updated if we need more. 775 */ 776 #define MAX_GROUPS_PER_POOL 128 777 778 /* 779 * Mark added on an entry of group pool Xarray to identify if the group has 780 * been fully initialized and can be accessed elsewhere in the driver code. 781 */ 782 #define GROUP_REGISTERED XA_MARK_1 783 784 /** 785 * struct panthor_group_pool - Group pool 786 * 787 * Each file get assigned a group pool. 788 */ 789 struct panthor_group_pool { 790 /** @xa: Xarray used to manage group handles. */ 791 struct xarray xa; 792 }; 793 794 /** 795 * struct panthor_job - Used to manage GPU job 796 */ 797 struct panthor_job { 798 /** @base: Inherit from drm_sched_job. */ 799 struct drm_sched_job base; 800 801 /** @refcount: Reference count. */ 802 struct kref refcount; 803 804 /** @group: Group of the queue this job will be pushed to. */ 805 struct panthor_group *group; 806 807 /** @queue_idx: Index of the queue inside @group. */ 808 u32 queue_idx; 809 810 /** @call_info: Information about the userspace command stream call. */ 811 struct { 812 /** @call_info.start: GPU address of the userspace command stream. */ 813 u64 start; 814 815 /** @call_info.size: Size of the userspace command stream. */ 816 u32 size; 817 818 /** 819 * @call_info.latest_flush: Flush ID at the time the userspace 820 * command stream was built. 821 * 822 * Needed for the flush reduction mechanism. 823 */ 824 u32 latest_flush; 825 } call_info; 826 827 /** @ringbuf: Position of this job is in the ring buffer. */ 828 struct { 829 /** @ringbuf.start: Start offset. */ 830 u64 start; 831 832 /** @ringbuf.end: End offset. */ 833 u64 end; 834 } ringbuf; 835 836 /** 837 * @node: Used to insert the job in the panthor_queue::fence_ctx::in_flight_jobs 838 * list. 839 */ 840 struct list_head node; 841 842 /** @done_fence: Fence signaled when the job is finished or cancelled. */ 843 struct dma_fence *done_fence; 844 845 /** @profiling: Job profiling information. */ 846 struct { 847 /** @profiling.mask: Current device job profiling enablement bitmask. */ 848 u32 mask; 849 850 /** @profiling.slot: Job index in the profiling slots BO. */ 851 u32 slot; 852 } profiling; 853 }; 854 855 static void 856 panthor_queue_put_syncwait_obj(struct panthor_queue *queue) 857 { 858 if (queue->syncwait.kmap) { 859 struct iosys_map map = IOSYS_MAP_INIT_VADDR(queue->syncwait.kmap); 860 861 drm_gem_vunmap(queue->syncwait.obj, &map); 862 queue->syncwait.kmap = NULL; 863 } 864 865 drm_gem_object_put(queue->syncwait.obj); 866 queue->syncwait.obj = NULL; 867 } 868 869 static void * 870 panthor_queue_get_syncwait_obj(struct panthor_group *group, struct panthor_queue *queue) 871 { 872 struct panthor_device *ptdev = group->ptdev; 873 struct panthor_gem_object *bo; 874 struct iosys_map map; 875 int ret; 876 877 if (queue->syncwait.kmap) { 878 bo = to_panthor_bo(queue->syncwait.obj); 879 goto out_sync; 880 } 881 882 bo = panthor_vm_get_bo_for_va(group->vm, 883 queue->syncwait.gpu_va, 884 &queue->syncwait.offset); 885 if (drm_WARN_ON(&ptdev->base, IS_ERR_OR_NULL(bo))) 886 goto err_put_syncwait_obj; 887 888 queue->syncwait.obj = &bo->base; 889 ret = drm_gem_vmap(queue->syncwait.obj, &map); 890 if (drm_WARN_ON(&ptdev->base, ret)) 891 goto err_put_syncwait_obj; 892 893 queue->syncwait.kmap = map.vaddr; 894 if (drm_WARN_ON(&ptdev->base, !queue->syncwait.kmap)) 895 goto err_put_syncwait_obj; 896 897 out_sync: 898 /* Make sure the CPU caches are invalidated before the seqno is read. 899 * panthor_gem_sync() is a NOP if map_wc=true, so no need to check 900 * it here. 901 */ 902 panthor_gem_sync(&bo->base, 903 DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE, 904 queue->syncwait.offset, 905 queue->syncwait.sync64 ? 906 sizeof(struct panthor_syncobj_64b) : 907 sizeof(struct panthor_syncobj_32b)); 908 909 return queue->syncwait.kmap + queue->syncwait.offset; 910 911 err_put_syncwait_obj: 912 panthor_queue_put_syncwait_obj(queue); 913 return NULL; 914 } 915 916 static void group_free_queue(struct panthor_group *group, struct panthor_queue *queue) 917 { 918 if (IS_ERR_OR_NULL(queue)) 919 return; 920 921 /* Disable the timeout before tearing down drm_sched components. */ 922 disable_delayed_work_sync(&queue->timeout.work); 923 924 if (queue->entity.fence_context) 925 drm_sched_entity_destroy(&queue->entity); 926 927 if (queue->scheduler.ops) 928 drm_sched_fini(&queue->scheduler); 929 930 kfree(queue->name); 931 932 panthor_queue_put_syncwait_obj(queue); 933 934 panthor_kernel_bo_destroy(queue->ringbuf); 935 panthor_kernel_bo_destroy(queue->iface.mem); 936 panthor_kernel_bo_destroy(queue->profiling.slots); 937 938 /* Release the last_fence we were holding, if any. */ 939 dma_fence_put(queue->fence_ctx.last_fence); 940 941 kfree(queue); 942 } 943 944 static void group_release_work(struct work_struct *work) 945 { 946 struct panthor_group *group = container_of(work, 947 struct panthor_group, 948 release_work); 949 u32 i; 950 951 /* dma-fences may still be accessing group->queues under rcu lock. */ 952 synchronize_rcu(); 953 954 for (i = 0; i < group->queue_count; i++) 955 group_free_queue(group, group->queues[i]); 956 957 panthor_kernel_bo_destroy(group->suspend_buf); 958 panthor_kernel_bo_destroy(group->protm_suspend_buf); 959 panthor_kernel_bo_destroy(group->syncobjs); 960 961 panthor_vm_put(group->vm); 962 kfree(group); 963 } 964 965 static void group_release(struct kref *kref) 966 { 967 struct panthor_group *group = container_of(kref, 968 struct panthor_group, 969 refcount); 970 struct panthor_device *ptdev = group->ptdev; 971 972 drm_WARN_ON(&ptdev->base, group->csg_id >= 0); 973 drm_WARN_ON(&ptdev->base, !list_empty(&group->run_node)); 974 drm_WARN_ON(&ptdev->base, !list_empty(&group->wait_node)); 975 976 queue_work(panthor_cleanup_wq, &group->release_work); 977 } 978 979 static void group_put(struct panthor_group *group) 980 { 981 if (group) 982 kref_put(&group->refcount, group_release); 983 } 984 985 static struct panthor_group * 986 group_get(struct panthor_group *group) 987 { 988 if (group) 989 kref_get(&group->refcount); 990 991 return group; 992 } 993 994 static bool 995 group_is_idle(struct panthor_group *group) 996 { 997 u32 inactive_queues = group->idle_queues | group->blocked_queues; 998 999 return hweight32(inactive_queues) == group->queue_count; 1000 } 1001 1002 static bool 1003 group_can_run(struct panthor_group *group) 1004 { 1005 return group->state != PANTHOR_CS_GROUP_TERMINATED && 1006 group->state != PANTHOR_CS_GROUP_UNKNOWN_STATE && 1007 !group->destroyed && 1008 !atomic_read(&group->fatal_queues) && 1009 !atomic_read(&group->timedout); 1010 } 1011 1012 static bool 1013 queue_timeout_is_suspended(struct panthor_queue *queue) 1014 { 1015 /* When running, the remaining time is set to MAX_SCHEDULE_TIMEOUT. */ 1016 return queue->timeout.remaining != MAX_SCHEDULE_TIMEOUT; 1017 } 1018 1019 static void 1020 queue_reset_timeout_locked(struct panthor_queue *queue) 1021 { 1022 lockdep_assert_held(&queue->fence_ctx.lock); 1023 1024 if (!queue_timeout_is_suspended(queue)) { 1025 mod_delayed_work(queue->scheduler.timeout_wq, 1026 &queue->timeout.work, 1027 msecs_to_jiffies(JOB_TIMEOUT_MS)); 1028 } 1029 } 1030 1031 static void 1032 queue_suspend_timeout_locked(struct panthor_queue *queue) 1033 { 1034 unsigned long qtimeout, now; 1035 struct panthor_group *group; 1036 struct panthor_job *job; 1037 bool timer_was_active; 1038 1039 lockdep_assert_held(&queue->fence_ctx.lock); 1040 1041 /* Already suspended, nothing to do. */ 1042 if (queue_timeout_is_suspended(queue)) 1043 return; 1044 1045 job = list_first_entry_or_null(&queue->fence_ctx.in_flight_jobs, 1046 struct panthor_job, node); 1047 group = job ? job->group : NULL; 1048 1049 /* If the queue is blocked and the group is idle, we want the timer to 1050 * keep running because the group can't be unblocked by other queues, 1051 * so it has to come from an external source, and we want to timebox 1052 * this external signalling. 1053 */ 1054 if (group && group_can_run(group) && 1055 (group->blocked_queues & BIT(job->queue_idx)) && 1056 group_is_idle(group)) 1057 return; 1058 1059 now = jiffies; 1060 qtimeout = queue->timeout.work.timer.expires; 1061 1062 /* Cancel the timer. */ 1063 timer_was_active = cancel_delayed_work(&queue->timeout.work); 1064 if (!timer_was_active || !job) 1065 queue->timeout.remaining = msecs_to_jiffies(JOB_TIMEOUT_MS); 1066 else if (time_after(qtimeout, now)) 1067 queue->timeout.remaining = qtimeout - now; 1068 else 1069 queue->timeout.remaining = 0; 1070 1071 if (WARN_ON_ONCE(queue->timeout.remaining > msecs_to_jiffies(JOB_TIMEOUT_MS))) 1072 queue->timeout.remaining = msecs_to_jiffies(JOB_TIMEOUT_MS); 1073 } 1074 1075 static void 1076 queue_suspend_timeout(struct panthor_queue *queue) 1077 { 1078 guard(spinlock_irqsave)(&queue->fence_ctx.lock); 1079 queue_suspend_timeout_locked(queue); 1080 } 1081 1082 static void 1083 queue_resume_timeout(struct panthor_queue *queue) 1084 { 1085 guard(spinlock_irqsave)(&queue->fence_ctx.lock); 1086 1087 if (queue_timeout_is_suspended(queue)) { 1088 mod_delayed_work(queue->scheduler.timeout_wq, 1089 &queue->timeout.work, 1090 queue->timeout.remaining); 1091 1092 queue->timeout.remaining = MAX_SCHEDULE_TIMEOUT; 1093 } 1094 } 1095 1096 /** 1097 * cs_slot_prog_locked() - Program a queue slot 1098 * @ptdev: Device. 1099 * @csg_id: Group slot ID. 1100 * @cs_id: Queue slot ID. 1101 * 1102 * Program a queue slot with the queue information so things can start being 1103 * executed on this queue. 1104 * 1105 * The group slot must have a group bound to it already (group_bind_locked()). 1106 */ 1107 static void 1108 cs_slot_prog_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs_id) 1109 { 1110 struct panthor_queue *queue = ptdev->scheduler->csg_slots[csg_id].group->queues[cs_id]; 1111 struct panthor_fw_cs_iface *cs_iface = panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); 1112 1113 lockdep_assert_held(&ptdev->scheduler->lock); 1114 1115 queue->iface.input->extract = queue->iface.output->extract; 1116 drm_WARN_ON(&ptdev->base, queue->iface.input->insert < queue->iface.input->extract); 1117 1118 cs_iface->input->ringbuf_base = panthor_kernel_bo_gpuva(queue->ringbuf); 1119 cs_iface->input->ringbuf_size = panthor_kernel_bo_size(queue->ringbuf); 1120 cs_iface->input->ringbuf_input = queue->iface.input_fw_va; 1121 cs_iface->input->ringbuf_output = queue->iface.output_fw_va; 1122 cs_iface->input->config = CS_CONFIG_PRIORITY(queue->priority) | 1123 CS_CONFIG_DOORBELL(queue->doorbell_id); 1124 cs_iface->input->ack_irq_mask = ~0; 1125 panthor_fw_update_reqs(cs_iface, req, 1126 CS_IDLE_SYNC_WAIT | 1127 CS_IDLE_EMPTY | 1128 CS_STATE_START, 1129 CS_IDLE_SYNC_WAIT | 1130 CS_IDLE_EMPTY | 1131 CS_STATE_MASK); 1132 if (queue->iface.input->insert != queue->iface.input->extract) 1133 queue_resume_timeout(queue); 1134 } 1135 1136 /** 1137 * cs_slot_reset_locked() - Reset a queue slot 1138 * @ptdev: Device. 1139 * @csg_id: Group slot. 1140 * @cs_id: Queue slot. 1141 * 1142 * Change the queue slot state to STOP and suspend the queue timeout if 1143 * the queue is not blocked. 1144 * 1145 * The group slot must have a group bound to it (group_bind_locked()). 1146 */ 1147 static int 1148 cs_slot_reset_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs_id) 1149 { 1150 struct panthor_fw_cs_iface *cs_iface = panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); 1151 struct panthor_group *group = ptdev->scheduler->csg_slots[csg_id].group; 1152 struct panthor_queue *queue = group->queues[cs_id]; 1153 1154 lockdep_assert_held(&ptdev->scheduler->lock); 1155 1156 panthor_fw_update_reqs(cs_iface, req, 1157 CS_STATE_STOP, 1158 CS_STATE_MASK); 1159 1160 queue_suspend_timeout(queue); 1161 1162 return 0; 1163 } 1164 1165 /** 1166 * csg_slot_sync_priority_locked() - Synchronize the group slot priority 1167 * @ptdev: Device. 1168 * @csg_id: Group slot ID. 1169 * 1170 * Group slot priority update happens asynchronously. When we receive a 1171 * %CSG_ENDPOINT_CONFIG, we know the update is effective, and can 1172 * reflect it to our panthor_csg_slot object. 1173 */ 1174 static void 1175 csg_slot_sync_priority_locked(struct panthor_device *ptdev, u32 csg_id) 1176 { 1177 struct panthor_csg_slot *csg_slot = &ptdev->scheduler->csg_slots[csg_id]; 1178 struct panthor_fw_csg_iface *csg_iface; 1179 u64 endpoint_req; 1180 1181 lockdep_assert_held(&ptdev->scheduler->lock); 1182 1183 csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); 1184 endpoint_req = panthor_fw_csg_endpoint_req_get(ptdev, csg_iface); 1185 csg_slot->priority = CSG_EP_REQ_PRIORITY_GET(endpoint_req); 1186 } 1187 1188 /** 1189 * cs_slot_sync_queue_state_locked() - Synchronize the queue slot priority 1190 * @ptdev: Device. 1191 * @csg_id: Group slot. 1192 * @cs_id: Queue slot. 1193 * 1194 * Queue state is updated on group suspend or STATUS_UPDATE event. 1195 */ 1196 static void 1197 cs_slot_sync_queue_state_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs_id) 1198 { 1199 struct panthor_group *group = ptdev->scheduler->csg_slots[csg_id].group; 1200 struct panthor_queue *queue = group->queues[cs_id]; 1201 struct panthor_fw_cs_iface *cs_iface = 1202 panthor_fw_get_cs_iface(group->ptdev, csg_id, cs_id); 1203 1204 u32 status_wait_cond; 1205 1206 switch (cs_iface->output->status_blocked_reason) { 1207 case CS_STATUS_BLOCKED_REASON_UNBLOCKED: 1208 if (queue->iface.input->insert == queue->iface.output->extract && 1209 cs_iface->output->status_scoreboards == 0) 1210 group->idle_queues |= BIT(cs_id); 1211 break; 1212 1213 case CS_STATUS_BLOCKED_REASON_SYNC_WAIT: 1214 if (list_empty(&group->wait_node)) { 1215 list_move_tail(&group->wait_node, 1216 &group->ptdev->scheduler->groups.waiting); 1217 } 1218 1219 /* The queue is only blocked if there's no deferred operation 1220 * pending, which can be checked through the scoreboard status. 1221 */ 1222 if (!cs_iface->output->status_scoreboards) 1223 group->blocked_queues |= BIT(cs_id); 1224 1225 queue->syncwait.gpu_va = cs_iface->output->status_wait_sync_ptr; 1226 queue->syncwait.ref = cs_iface->output->status_wait_sync_value; 1227 status_wait_cond = cs_iface->output->status_wait & CS_STATUS_WAIT_SYNC_COND_MASK; 1228 queue->syncwait.gt = status_wait_cond == CS_STATUS_WAIT_SYNC_COND_GT; 1229 if (cs_iface->output->status_wait & CS_STATUS_WAIT_SYNC_64B) { 1230 u64 sync_val_hi = cs_iface->output->status_wait_sync_value_hi; 1231 1232 queue->syncwait.sync64 = true; 1233 queue->syncwait.ref |= sync_val_hi << 32; 1234 } else { 1235 queue->syncwait.sync64 = false; 1236 } 1237 break; 1238 1239 default: 1240 /* Other reasons are not blocking. Consider the queue as runnable 1241 * in those cases. 1242 */ 1243 break; 1244 } 1245 } 1246 1247 static void 1248 csg_slot_sync_queues_state_locked(struct panthor_device *ptdev, u32 csg_id) 1249 { 1250 struct panthor_csg_slot *csg_slot = &ptdev->scheduler->csg_slots[csg_id]; 1251 struct panthor_group *group = csg_slot->group; 1252 u32 i; 1253 1254 lockdep_assert_held(&ptdev->scheduler->lock); 1255 1256 group->idle_queues = 0; 1257 group->blocked_queues = 0; 1258 1259 for (i = 0; i < group->queue_count; i++) { 1260 if (group->queues[i]) 1261 cs_slot_sync_queue_state_locked(ptdev, csg_id, i); 1262 } 1263 } 1264 1265 static void 1266 csg_slot_sync_state_locked(struct panthor_device *ptdev, u32 csg_id) 1267 { 1268 struct panthor_csg_slot *csg_slot = &ptdev->scheduler->csg_slots[csg_id]; 1269 struct panthor_fw_csg_iface *csg_iface; 1270 struct panthor_group *group; 1271 enum panthor_group_state new_state, old_state; 1272 u32 csg_state; 1273 1274 lockdep_assert_held(&ptdev->scheduler->lock); 1275 1276 csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); 1277 group = csg_slot->group; 1278 1279 if (!group) 1280 return; 1281 1282 old_state = group->state; 1283 csg_state = csg_iface->output->ack & CSG_STATE_MASK; 1284 switch (csg_state) { 1285 case CSG_STATE_START: 1286 case CSG_STATE_RESUME: 1287 new_state = PANTHOR_CS_GROUP_ACTIVE; 1288 break; 1289 case CSG_STATE_TERMINATE: 1290 new_state = PANTHOR_CS_GROUP_TERMINATED; 1291 break; 1292 case CSG_STATE_SUSPEND: 1293 new_state = PANTHOR_CS_GROUP_SUSPENDED; 1294 break; 1295 default: 1296 /* The unknown state might be caused by a FW state corruption, 1297 * which means the group metadata can't be trusted anymore, and 1298 * the SUSPEND operation might propagate the corruption to the 1299 * suspend buffers. Flag the group state as unknown to make 1300 * sure it's unusable after that point. 1301 */ 1302 drm_err(&ptdev->base, "Invalid state on CSG %d (state=%d)", 1303 csg_id, csg_state); 1304 new_state = PANTHOR_CS_GROUP_UNKNOWN_STATE; 1305 break; 1306 } 1307 1308 if (old_state == new_state) 1309 return; 1310 1311 /* The unknown state might be caused by a FW issue, reset the FW to 1312 * take a fresh start. 1313 */ 1314 if (new_state == PANTHOR_CS_GROUP_UNKNOWN_STATE) 1315 panthor_device_schedule_reset(ptdev); 1316 1317 if (new_state == PANTHOR_CS_GROUP_SUSPENDED) 1318 csg_slot_sync_queues_state_locked(ptdev, csg_id); 1319 1320 if (old_state == PANTHOR_CS_GROUP_ACTIVE) { 1321 u32 i; 1322 1323 /* Reset the queue slots so we start from a clean 1324 * state when starting/resuming a new group on this 1325 * CSG slot. No wait needed here, and no ringbell 1326 * either, since the CS slot will only be re-used 1327 * on the next CSG start operation. 1328 */ 1329 for (i = 0; i < group->queue_count; i++) { 1330 if (group->queues[i]) 1331 cs_slot_reset_locked(ptdev, csg_id, i); 1332 } 1333 } 1334 1335 group->state = new_state; 1336 } 1337 1338 static int 1339 csg_slot_prog_locked(struct panthor_device *ptdev, u32 csg_id, u32 priority) 1340 { 1341 struct panthor_fw_csg_iface *csg_iface; 1342 struct panthor_csg_slot *csg_slot; 1343 struct panthor_group *group; 1344 u32 queue_mask = 0, i; 1345 u64 endpoint_req; 1346 1347 lockdep_assert_held(&ptdev->scheduler->lock); 1348 1349 if (priority > MAX_CSG_PRIO) 1350 return -EINVAL; 1351 1352 if (drm_WARN_ON(&ptdev->base, csg_id >= MAX_CSGS)) 1353 return -EINVAL; 1354 1355 csg_slot = &ptdev->scheduler->csg_slots[csg_id]; 1356 group = csg_slot->group; 1357 if (!group || group->state == PANTHOR_CS_GROUP_ACTIVE) 1358 return 0; 1359 1360 csg_iface = panthor_fw_get_csg_iface(group->ptdev, csg_id); 1361 1362 for (i = 0; i < group->queue_count; i++) { 1363 if (group->queues[i]) { 1364 cs_slot_prog_locked(ptdev, csg_id, i); 1365 queue_mask |= BIT(i); 1366 } 1367 } 1368 1369 csg_iface->input->allow_compute = group->compute_core_mask; 1370 csg_iface->input->allow_fragment = group->fragment_core_mask; 1371 csg_iface->input->allow_other = group->tiler_core_mask; 1372 endpoint_req = CSG_EP_REQ_COMPUTE(group->max_compute_cores) | 1373 CSG_EP_REQ_FRAGMENT(group->max_fragment_cores) | 1374 CSG_EP_REQ_TILER(group->max_tiler_cores) | 1375 CSG_EP_REQ_PRIORITY(priority); 1376 panthor_fw_csg_endpoint_req_set(ptdev, csg_iface, endpoint_req); 1377 1378 csg_iface->input->config = panthor_vm_as(group->vm); 1379 1380 if (group->suspend_buf) 1381 csg_iface->input->suspend_buf = panthor_kernel_bo_gpuva(group->suspend_buf); 1382 else 1383 csg_iface->input->suspend_buf = 0; 1384 1385 if (group->protm_suspend_buf) { 1386 csg_iface->input->protm_suspend_buf = 1387 panthor_kernel_bo_gpuva(group->protm_suspend_buf); 1388 } else { 1389 csg_iface->input->protm_suspend_buf = 0; 1390 } 1391 1392 csg_iface->input->ack_irq_mask = ~0; 1393 panthor_fw_toggle_reqs(csg_iface, doorbell_req, doorbell_ack, queue_mask); 1394 return 0; 1395 } 1396 1397 static void 1398 cs_slot_process_fatal_event_locked(struct panthor_device *ptdev, 1399 u32 csg_id, u32 cs_id) 1400 { 1401 struct panthor_scheduler *sched = ptdev->scheduler; 1402 struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id]; 1403 struct panthor_group *group = csg_slot->group; 1404 struct panthor_fw_cs_iface *cs_iface; 1405 u32 fatal; 1406 u64 info; 1407 1408 lockdep_assert_held(&sched->events_lock); 1409 1410 cs_iface = panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); 1411 fatal = cs_iface->output->fatal; 1412 info = cs_iface->output->fatal_info; 1413 1414 if (group) { 1415 drm_warn(&ptdev->base, "CS_FATAL: pid=%d, comm=%s\n", 1416 group->task_info.pid, group->task_info.comm); 1417 1418 atomic_or(BIT(cs_id), &group->fatal_queues); 1419 } 1420 1421 if (CS_EXCEPTION_TYPE(fatal) == DRM_PANTHOR_EXCEPTION_CS_UNRECOVERABLE) { 1422 /* If this exception is unrecoverable, queue a reset, and make 1423 * sure we stop scheduling groups until the reset has happened. 1424 */ 1425 panthor_device_schedule_reset(ptdev); 1426 cancel_delayed_work(&sched->tick_work); 1427 } else { 1428 sched_queue_delayed_work(sched, tick, 0); 1429 } 1430 1431 drm_warn(&ptdev->base, 1432 "CSG slot %d CS slot: %d\n" 1433 "CS_FATAL.EXCEPTION_TYPE: 0x%x (%s)\n" 1434 "CS_FATAL.EXCEPTION_DATA: 0x%x\n" 1435 "CS_FATAL_INFO.EXCEPTION_DATA: 0x%llx\n", 1436 csg_id, cs_id, 1437 (unsigned int)CS_EXCEPTION_TYPE(fatal), 1438 panthor_exception_name(ptdev, CS_EXCEPTION_TYPE(fatal)), 1439 (unsigned int)CS_EXCEPTION_DATA(fatal), 1440 info); 1441 } 1442 1443 static void 1444 cs_slot_process_fault_event_locked(struct panthor_device *ptdev, 1445 u32 csg_id, u32 cs_id) 1446 { 1447 struct panthor_scheduler *sched = ptdev->scheduler; 1448 struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id]; 1449 struct panthor_group *group = csg_slot->group; 1450 struct panthor_queue *queue = group && cs_id < group->queue_count ? 1451 group->queues[cs_id] : NULL; 1452 struct panthor_fw_cs_iface *cs_iface; 1453 u32 fault; 1454 u64 info; 1455 1456 lockdep_assert_held(&sched->events_lock); 1457 1458 cs_iface = panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); 1459 fault = cs_iface->output->fault; 1460 info = cs_iface->output->fault_info; 1461 1462 if (queue) { 1463 u64 cs_extract = queue->iface.output->extract; 1464 struct panthor_job *job; 1465 1466 guard(spinlock_irqsave)(&queue->fence_ctx.lock); 1467 list_for_each_entry(job, &queue->fence_ctx.in_flight_jobs, node) { 1468 if (cs_extract >= job->ringbuf.end) 1469 continue; 1470 1471 if (cs_extract < job->ringbuf.start) 1472 break; 1473 1474 dma_fence_set_error(job->done_fence, -EINVAL); 1475 } 1476 } 1477 1478 if (group) { 1479 drm_warn(&ptdev->base, "CS_FAULT: pid=%d, comm=%s\n", 1480 group->task_info.pid, group->task_info.comm); 1481 } 1482 1483 drm_warn(&ptdev->base, 1484 "CSG slot %d CS slot: %d\n" 1485 "CS_FAULT.EXCEPTION_TYPE: 0x%x (%s)\n" 1486 "CS_FAULT.EXCEPTION_DATA: 0x%x\n" 1487 "CS_FAULT_INFO.EXCEPTION_DATA: 0x%llx\n", 1488 csg_id, cs_id, 1489 (unsigned int)CS_EXCEPTION_TYPE(fault), 1490 panthor_exception_name(ptdev, CS_EXCEPTION_TYPE(fault)), 1491 (unsigned int)CS_EXCEPTION_DATA(fault), 1492 info); 1493 } 1494 1495 static int group_process_tiler_oom(struct panthor_group *group, u32 cs_id) 1496 { 1497 struct panthor_device *ptdev = group->ptdev; 1498 struct panthor_scheduler *sched = ptdev->scheduler; 1499 u32 renderpasses_in_flight, pending_frag_count; 1500 struct panthor_heap_pool *heaps = NULL; 1501 u64 heap_address, new_chunk_va = 0; 1502 u32 vt_start, vt_end, frag_end; 1503 int ret, csg_id; 1504 1505 mutex_lock(&sched->lock); 1506 csg_id = group->csg_id; 1507 if (csg_id >= 0) { 1508 struct panthor_fw_cs_iface *cs_iface; 1509 1510 cs_iface = panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); 1511 heaps = panthor_vm_get_heap_pool(group->vm, false); 1512 heap_address = cs_iface->output->heap_address; 1513 vt_start = cs_iface->output->heap_vt_start; 1514 vt_end = cs_iface->output->heap_vt_end; 1515 frag_end = cs_iface->output->heap_frag_end; 1516 renderpasses_in_flight = vt_start - frag_end; 1517 pending_frag_count = vt_end - frag_end; 1518 } 1519 mutex_unlock(&sched->lock); 1520 1521 /* The group got scheduled out, we stop here. We will get a new tiler OOM event 1522 * when it's scheduled again. 1523 */ 1524 if (unlikely(csg_id < 0)) 1525 return 0; 1526 1527 if (IS_ERR(heaps)) { 1528 ret = -EINVAL; 1529 heaps = NULL; 1530 } else if (frag_end > vt_end || vt_end >= vt_start) { 1531 ret = -EINVAL; 1532 } else { 1533 /* We do the allocation without holding the scheduler lock to avoid 1534 * blocking the scheduling. 1535 */ 1536 ret = panthor_heap_grow(heaps, heap_address, 1537 renderpasses_in_flight, 1538 pending_frag_count, &new_chunk_va); 1539 } 1540 1541 /* If the heap context doesn't have memory for us, we want to let the 1542 * FW try to reclaim memory by waiting for fragment jobs to land or by 1543 * executing the tiler OOM exception handler, which is supposed to 1544 * implement incremental rendering. 1545 */ 1546 if (ret && ret != -ENOMEM) { 1547 drm_warn(&ptdev->base, "Failed to extend the tiler heap\n"); 1548 atomic_or(BIT(cs_id), &group->fatal_queues); 1549 sched_queue_delayed_work(sched, tick, 0); 1550 goto out_put_heap_pool; 1551 } 1552 1553 mutex_lock(&sched->lock); 1554 csg_id = group->csg_id; 1555 if (csg_id >= 0) { 1556 struct panthor_fw_csg_iface *csg_iface; 1557 struct panthor_fw_cs_iface *cs_iface; 1558 1559 csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); 1560 cs_iface = panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); 1561 1562 cs_iface->input->heap_start = new_chunk_va; 1563 cs_iface->input->heap_end = new_chunk_va; 1564 panthor_fw_update_reqs(cs_iface, req, cs_iface->output->ack, CS_TILER_OOM); 1565 panthor_fw_toggle_reqs(csg_iface, doorbell_req, doorbell_ack, BIT(cs_id)); 1566 panthor_fw_ring_csg_doorbells(ptdev, BIT(csg_id)); 1567 } 1568 mutex_unlock(&sched->lock); 1569 1570 /* We allocated a chunck, but couldn't link it to the heap 1571 * context because the group was scheduled out while we were 1572 * allocating memory. We need to return this chunk to the heap. 1573 */ 1574 if (unlikely(csg_id < 0 && new_chunk_va)) 1575 panthor_heap_return_chunk(heaps, heap_address, new_chunk_va); 1576 1577 ret = 0; 1578 1579 out_put_heap_pool: 1580 panthor_heap_pool_put(heaps); 1581 return ret; 1582 } 1583 1584 static void group_tiler_oom_work(struct work_struct *work) 1585 { 1586 struct panthor_group *group = 1587 container_of(work, struct panthor_group, tiler_oom_work); 1588 u32 tiler_oom = atomic_xchg(&group->tiler_oom, 0); 1589 1590 while (tiler_oom) { 1591 u32 cs_id = ffs(tiler_oom) - 1; 1592 1593 group_process_tiler_oom(group, cs_id); 1594 tiler_oom &= ~BIT(cs_id); 1595 } 1596 1597 group_put(group); 1598 } 1599 1600 static void 1601 cs_slot_process_tiler_oom_event_locked(struct panthor_device *ptdev, 1602 u32 csg_id, u32 cs_id) 1603 { 1604 struct panthor_scheduler *sched = ptdev->scheduler; 1605 struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id]; 1606 struct panthor_group *group = csg_slot->group; 1607 1608 lockdep_assert_held(&sched->events_lock); 1609 1610 if (drm_WARN_ON(&ptdev->base, !group)) 1611 return; 1612 1613 atomic_or(BIT(cs_id), &group->tiler_oom); 1614 1615 /* We don't use group_queue_work() here because we want to queue the 1616 * work item to the heap_alloc_wq. 1617 */ 1618 group_get(group); 1619 if (!queue_work(sched->heap_alloc_wq, &group->tiler_oom_work)) 1620 group_put(group); 1621 } 1622 1623 static bool cs_slot_process_irq_locked(struct panthor_device *ptdev, 1624 u32 csg_id, u32 cs_id) 1625 { 1626 struct panthor_fw_cs_iface *cs_iface; 1627 u32 req, ack, events; 1628 1629 lockdep_assert_held(&ptdev->scheduler->events_lock); 1630 1631 cs_iface = panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); 1632 req = cs_iface->input->req; 1633 ack = cs_iface->output->ack; 1634 events = (req ^ ack) & CS_EVT_MASK; 1635 1636 if (events & CS_FATAL) 1637 cs_slot_process_fatal_event_locked(ptdev, csg_id, cs_id); 1638 1639 if (events & CS_FAULT) 1640 cs_slot_process_fault_event_locked(ptdev, csg_id, cs_id); 1641 1642 if (events & CS_TILER_OOM) 1643 cs_slot_process_tiler_oom_event_locked(ptdev, csg_id, cs_id); 1644 1645 /* We don't acknowledge the TILER_OOM event since its handling is 1646 * deferred to a separate work. 1647 */ 1648 panthor_fw_update_reqs(cs_iface, req, ack, CS_FATAL | CS_FAULT); 1649 1650 return (events & (CS_FAULT | CS_TILER_OOM)) != 0; 1651 } 1652 1653 static void csg_slot_process_idle_event_locked(struct panthor_device *ptdev, u32 csg_id) 1654 { 1655 struct panthor_scheduler *sched = ptdev->scheduler; 1656 1657 lockdep_assert_held(&sched->events_lock); 1658 1659 /* Schedule a tick so we can evict idle groups and schedule non-idle 1660 * ones. This will also update runtime PM and devfreq busy/idle states, 1661 * so the device can lower its frequency or get suspended. 1662 */ 1663 sched_queue_delayed_work(sched, tick, 0); 1664 } 1665 1666 static void update_fdinfo_stats(struct panthor_job *job) 1667 { 1668 struct panthor_group *group = job->group; 1669 struct panthor_queue *queue = group->queues[job->queue_idx]; 1670 struct panthor_gpu_usage *fdinfo = &group->fdinfo.data; 1671 struct panthor_job_profiling_data *slots = queue->profiling.slots->kmap; 1672 struct panthor_job_profiling_data *data = &slots[job->profiling.slot]; 1673 1674 scoped_guard(spinlock, &group->fdinfo.lock) { 1675 if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_CYCLES) 1676 fdinfo->cycles += data->cycles.after - data->cycles.before; 1677 if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_TIMESTAMP) 1678 fdinfo->time += data->time.after - data->time.before; 1679 } 1680 } 1681 1682 static bool queue_check_job_completion(struct panthor_queue *queue) 1683 { 1684 struct panthor_syncobj_64b *syncobj = NULL; 1685 struct panthor_job *job, *job_tmp; 1686 bool cookie, progress = false; 1687 LIST_HEAD(done_jobs); 1688 1689 cookie = dma_fence_begin_signalling(); 1690 scoped_guard(spinlock_irqsave, &queue->fence_ctx.lock) { 1691 list_for_each_entry_safe(job, job_tmp, &queue->fence_ctx.in_flight_jobs, node) { 1692 if (!syncobj) { 1693 struct panthor_group *group = job->group; 1694 1695 syncobj = group->syncobjs->kmap + 1696 (job->queue_idx * sizeof(*syncobj)); 1697 } 1698 1699 if (syncobj->seqno < job->done_fence->seqno) 1700 break; 1701 1702 list_move_tail(&job->node, &done_jobs); 1703 dma_fence_signal_locked(job->done_fence); 1704 } 1705 1706 if (list_empty(&queue->fence_ctx.in_flight_jobs)) { 1707 /* If we have no job left, we cancel the timer, and reset remaining 1708 * time to its default so it can be restarted next time 1709 * queue_resume_timeout() is called. 1710 */ 1711 queue_suspend_timeout_locked(queue); 1712 1713 /* If there's no job pending, we consider it progress to avoid a 1714 * spurious timeout if the timeout handler and the sync update 1715 * handler raced. 1716 */ 1717 progress = true; 1718 } else if (!list_empty(&done_jobs)) { 1719 queue_reset_timeout_locked(queue); 1720 progress = true; 1721 } 1722 } 1723 dma_fence_end_signalling(cookie); 1724 1725 list_for_each_entry_safe(job, job_tmp, &done_jobs, node) { 1726 if (job->profiling.mask) 1727 update_fdinfo_stats(job); 1728 list_del_init(&job->node); 1729 panthor_job_put(&job->base); 1730 } 1731 1732 return progress; 1733 } 1734 1735 static void group_check_job_completion(struct panthor_group *group) 1736 { 1737 u32 queue_idx; 1738 bool cookie; 1739 1740 cookie = dma_fence_begin_signalling(); 1741 for (queue_idx = 0; queue_idx < group->queue_count; queue_idx++) { 1742 struct panthor_queue *queue = group->queues[queue_idx]; 1743 1744 if (!queue) 1745 continue; 1746 1747 queue_check_job_completion(queue); 1748 } 1749 dma_fence_end_signalling(cookie); 1750 } 1751 1752 static void csg_slot_sync_update_locked(struct panthor_device *ptdev, 1753 u32 csg_id) 1754 { 1755 struct panthor_csg_slot *csg_slot = &ptdev->scheduler->csg_slots[csg_id]; 1756 struct panthor_group *group = csg_slot->group; 1757 1758 lockdep_assert_held(&ptdev->scheduler->events_lock); 1759 1760 if (group) 1761 group_check_job_completion(group); 1762 1763 sched_queue_work(ptdev->scheduler, sync_upd); 1764 } 1765 1766 static void 1767 csg_slot_process_progress_timer_event_locked(struct panthor_device *ptdev, u32 csg_id) 1768 { 1769 struct panthor_scheduler *sched = ptdev->scheduler; 1770 struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id]; 1771 struct panthor_group *group = csg_slot->group; 1772 1773 lockdep_assert_held(&sched->events_lock); 1774 1775 group = csg_slot->group; 1776 if (!drm_WARN_ON(&ptdev->base, !group)) { 1777 drm_warn(&ptdev->base, "CSG_PROGRESS_TIMER_EVENT: pid=%d, comm=%s\n", 1778 group->task_info.pid, group->task_info.comm); 1779 1780 atomic_set(&group->timedout, true); 1781 } 1782 1783 drm_warn(&ptdev->base, "CSG slot %d progress timeout\n", csg_id); 1784 1785 sched_queue_delayed_work(sched, tick, 0); 1786 } 1787 1788 static void sched_process_csg_irq_locked(struct panthor_device *ptdev, u32 csg_id) 1789 { 1790 u32 req, ack, cs_irq_req, cs_irq_ack, cs_irqs, csg_events; 1791 struct panthor_fw_csg_iface *csg_iface; 1792 u32 ring_cs_db_mask = 0; 1793 1794 lockdep_assert_held(&ptdev->scheduler->events_lock); 1795 1796 if (drm_WARN_ON(&ptdev->base, csg_id >= ptdev->scheduler->csg_slot_count)) 1797 return; 1798 1799 csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); 1800 req = READ_ONCE(csg_iface->input->req); 1801 ack = READ_ONCE(csg_iface->output->ack); 1802 cs_irq_req = READ_ONCE(csg_iface->output->cs_irq_req); 1803 cs_irq_ack = READ_ONCE(csg_iface->input->cs_irq_ack); 1804 csg_events = (req ^ ack) & CSG_EVT_MASK; 1805 1806 /* There may not be any pending CSG/CS interrupts to process */ 1807 if (req == ack && cs_irq_req == cs_irq_ack) 1808 return; 1809 1810 /* Immediately set IRQ_ACK bits to be same as the IRQ_REQ bits before 1811 * examining the CS_ACK & CS_REQ bits. This would ensure that Host 1812 * doesn't miss an interrupt for the CS in the race scenario where 1813 * whilst Host is servicing an interrupt for the CS, firmware sends 1814 * another interrupt for that CS. 1815 */ 1816 csg_iface->input->cs_irq_ack = cs_irq_req; 1817 1818 panthor_fw_update_reqs(csg_iface, req, ack, 1819 CSG_SYNC_UPDATE | 1820 CSG_IDLE | 1821 CSG_PROGRESS_TIMER_EVENT); 1822 1823 if (csg_events & CSG_IDLE) 1824 csg_slot_process_idle_event_locked(ptdev, csg_id); 1825 1826 if (csg_events & CSG_PROGRESS_TIMER_EVENT) 1827 csg_slot_process_progress_timer_event_locked(ptdev, csg_id); 1828 1829 cs_irqs = cs_irq_req ^ cs_irq_ack; 1830 while (cs_irqs) { 1831 u32 cs_id = ffs(cs_irqs) - 1; 1832 1833 if (cs_slot_process_irq_locked(ptdev, csg_id, cs_id)) 1834 ring_cs_db_mask |= BIT(cs_id); 1835 1836 cs_irqs &= ~BIT(cs_id); 1837 } 1838 1839 if (csg_events & CSG_SYNC_UPDATE) 1840 csg_slot_sync_update_locked(ptdev, csg_id); 1841 1842 if (ring_cs_db_mask) 1843 panthor_fw_toggle_reqs(csg_iface, doorbell_req, doorbell_ack, ring_cs_db_mask); 1844 1845 panthor_fw_ring_csg_doorbells(ptdev, BIT(csg_id)); 1846 } 1847 1848 static void sched_process_idle_event_locked(struct panthor_device *ptdev) 1849 { 1850 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); 1851 1852 lockdep_assert_held(&ptdev->scheduler->events_lock); 1853 1854 /* Acknowledge the idle event and schedule a tick. */ 1855 panthor_fw_update_reqs(glb_iface, req, glb_iface->output->ack, GLB_IDLE); 1856 sched_queue_delayed_work(ptdev->scheduler, tick, 0); 1857 } 1858 1859 /** 1860 * sched_process_global_irq_locked() - Process the scheduling part of a global IRQ 1861 * @ptdev: Device. 1862 */ 1863 static void sched_process_global_irq_locked(struct panthor_device *ptdev) 1864 { 1865 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); 1866 u32 req, ack, evts; 1867 1868 lockdep_assert_held(&ptdev->scheduler->events_lock); 1869 1870 req = READ_ONCE(glb_iface->input->req); 1871 ack = READ_ONCE(glb_iface->output->ack); 1872 evts = (req ^ ack) & GLB_EVT_MASK; 1873 1874 if (evts & GLB_IDLE) 1875 sched_process_idle_event_locked(ptdev); 1876 } 1877 1878 /** 1879 * panthor_sched_report_fw_events() - Report FW events to the scheduler. 1880 * @ptdev: Device. 1881 * @events: Bitmask of pending FW events to report. 1882 */ 1883 void panthor_sched_report_fw_events(struct panthor_device *ptdev, u32 events) 1884 { 1885 if (!ptdev->scheduler) 1886 return; 1887 1888 guard(spinlock)(&ptdev->scheduler->events_lock); 1889 1890 if (events & JOB_INT_GLOBAL_IF) { 1891 sched_process_global_irq_locked(ptdev); 1892 events &= ~JOB_INT_GLOBAL_IF; 1893 } 1894 1895 while (events) { 1896 u32 csg_id = ffs(events) - 1; 1897 1898 sched_process_csg_irq_locked(ptdev, csg_id); 1899 events &= ~BIT(csg_id); 1900 } 1901 } 1902 1903 /** 1904 * group_bind_locked() - Bind a group to a group slot 1905 * @group: Group. 1906 * @csg_id: Slot. 1907 * 1908 * Return: 0 on success, a negative error code otherwise. 1909 */ 1910 static int 1911 group_bind_locked(struct panthor_group *group, u32 csg_id) 1912 { 1913 struct panthor_device *ptdev = group->ptdev; 1914 int ret; 1915 1916 lockdep_assert_held(&ptdev->scheduler->lock); 1917 1918 if (drm_WARN_ON(&ptdev->base, group->csg_id != -1 || csg_id >= MAX_CSGS || 1919 ptdev->scheduler->csg_slots[csg_id].group)) 1920 return -EINVAL; 1921 1922 ret = panthor_vm_active(group->vm); 1923 if (ret) 1924 return ret; 1925 1926 group_get(group); 1927 1928 /* Dummy doorbell allocation: doorbell is assigned to the group and 1929 * all queues use the same doorbell. 1930 * 1931 * TODO: Implement LRU-based doorbell assignment, so the most often 1932 * updated queues get their own doorbell, thus avoiding useless checks 1933 * on queues belonging to the same group that are rarely updated. 1934 */ 1935 for (u32 i = 0; i < group->queue_count; i++) 1936 group->queues[i]->doorbell_id = csg_id + 1; 1937 1938 scoped_guard(spinlock, &ptdev->scheduler->events_lock) { 1939 ptdev->scheduler->csg_slots[csg_id].group = group; 1940 group->csg_id = csg_id; 1941 } 1942 1943 return 0; 1944 } 1945 1946 /** 1947 * group_unbind_locked() - Unbind a group from a slot. 1948 * @group: Group to unbind. 1949 * 1950 * Return: 0 on success, a negative error code otherwise. 1951 */ 1952 static int 1953 group_unbind_locked(struct panthor_group *group) 1954 { 1955 struct panthor_device *ptdev = group->ptdev; 1956 1957 lockdep_assert_held(&ptdev->scheduler->lock); 1958 1959 if (drm_WARN_ON(&ptdev->base, group->csg_id < 0 || group->csg_id >= MAX_CSGS)) 1960 return -EINVAL; 1961 1962 if (drm_WARN_ON(&ptdev->base, group->state == PANTHOR_CS_GROUP_ACTIVE)) 1963 return -EINVAL; 1964 1965 scoped_guard(spinlock, &ptdev->scheduler->events_lock) { 1966 /* Process all pending IRQs before returning the slot. */ 1967 sched_process_csg_irq_locked(ptdev, group->csg_id); 1968 ptdev->scheduler->csg_slots[group->csg_id].group = NULL; 1969 group->csg_id = -1; 1970 } 1971 1972 panthor_vm_idle(group->vm); 1973 1974 /* Tiler OOM events will be re-issued next time the group is scheduled. */ 1975 atomic_set(&group->tiler_oom, 0); 1976 if (cancel_work(&group->tiler_oom_work)) 1977 group_put(group); 1978 1979 for (u32 i = 0; i < group->queue_count; i++) 1980 group->queues[i]->doorbell_id = -1; 1981 1982 group_put(group); 1983 return 0; 1984 } 1985 1986 static const char *fence_get_driver_name(struct dma_fence *fence) 1987 { 1988 return "panthor"; 1989 } 1990 1991 static const char *queue_fence_get_timeline_name(struct dma_fence *fence) 1992 { 1993 return "queue-fence"; 1994 } 1995 1996 static const struct dma_fence_ops panthor_queue_fence_ops = { 1997 .get_driver_name = fence_get_driver_name, 1998 .get_timeline_name = queue_fence_get_timeline_name, 1999 }; 2000 2001 struct panthor_csg_slots_upd_ctx { 2002 u32 update_mask; 2003 u32 timedout_mask; 2004 struct { 2005 u32 value; 2006 u32 mask; 2007 } requests[MAX_CSGS]; 2008 }; 2009 2010 static void csgs_upd_ctx_init(struct panthor_csg_slots_upd_ctx *ctx) 2011 { 2012 memset(ctx, 0, sizeof(*ctx)); 2013 } 2014 2015 static void csgs_upd_ctx_queue_reqs(struct panthor_device *ptdev, 2016 struct panthor_csg_slots_upd_ctx *ctx, 2017 u32 csg_id, u32 value, u32 mask) 2018 { 2019 if (drm_WARN_ON(&ptdev->base, !mask) || 2020 drm_WARN_ON(&ptdev->base, csg_id >= ptdev->scheduler->csg_slot_count)) 2021 return; 2022 2023 ctx->requests[csg_id].value = (ctx->requests[csg_id].value & ~mask) | (value & mask); 2024 ctx->requests[csg_id].mask |= mask; 2025 ctx->update_mask |= BIT(csg_id); 2026 } 2027 2028 static int csgs_upd_ctx_apply_locked(struct panthor_device *ptdev, 2029 struct panthor_csg_slots_upd_ctx *ctx) 2030 { 2031 struct panthor_scheduler *sched = ptdev->scheduler; 2032 u32 update_slots = ctx->update_mask; 2033 2034 lockdep_assert_held(&sched->lock); 2035 2036 if (!ctx->update_mask) 2037 return 0; 2038 2039 while (update_slots) { 2040 struct panthor_fw_csg_iface *csg_iface; 2041 u32 csg_id = ffs(update_slots) - 1; 2042 2043 update_slots &= ~BIT(csg_id); 2044 csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); 2045 panthor_fw_update_reqs(csg_iface, req, 2046 ctx->requests[csg_id].value, 2047 ctx->requests[csg_id].mask); 2048 } 2049 2050 panthor_fw_ring_csg_doorbells(ptdev, ctx->update_mask); 2051 2052 update_slots = ctx->update_mask; 2053 while (update_slots) { 2054 struct panthor_fw_csg_iface *csg_iface; 2055 u32 csg_id = ffs(update_slots) - 1; 2056 u32 req_mask = ctx->requests[csg_id].mask, acked; 2057 int ret; 2058 2059 update_slots &= ~BIT(csg_id); 2060 csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); 2061 2062 ret = panthor_fw_csg_wait_acks(ptdev, csg_id, req_mask, &acked, 100); 2063 2064 if (acked & CSG_ENDPOINT_CONFIG) 2065 csg_slot_sync_priority_locked(ptdev, csg_id); 2066 2067 if (acked & CSG_STATE_MASK) 2068 csg_slot_sync_state_locked(ptdev, csg_id); 2069 2070 if (acked & CSG_STATUS_UPDATE) 2071 csg_slot_sync_queues_state_locked(ptdev, csg_id); 2072 2073 if (ret && acked != req_mask && 2074 ((csg_iface->input->req ^ csg_iface->output->ack) & req_mask) != 0) { 2075 drm_err(&ptdev->base, "CSG %d update request timedout", csg_id); 2076 ctx->timedout_mask |= BIT(csg_id); 2077 } 2078 } 2079 2080 if (ctx->timedout_mask) 2081 return -ETIMEDOUT; 2082 2083 return 0; 2084 } 2085 2086 struct panthor_sched_tick_ctx { 2087 struct list_head old_groups[PANTHOR_CSG_PRIORITY_COUNT]; 2088 struct list_head groups[PANTHOR_CSG_PRIORITY_COUNT]; 2089 u32 idle_group_count; 2090 u32 group_count; 2091 struct panthor_vm *vms[MAX_CS_PER_CSG]; 2092 u32 as_count; 2093 bool immediate_tick; 2094 bool stop_tick; 2095 u32 csg_upd_failed_mask; 2096 }; 2097 2098 static bool 2099 tick_ctx_is_full(const struct panthor_scheduler *sched, 2100 const struct panthor_sched_tick_ctx *ctx) 2101 { 2102 return ctx->group_count == sched->csg_slot_count; 2103 } 2104 2105 static void 2106 tick_ctx_pick_groups_from_list(const struct panthor_scheduler *sched, 2107 struct panthor_sched_tick_ctx *ctx, 2108 struct list_head *queue, 2109 bool skip_idle_groups, 2110 bool owned_by_tick_ctx) 2111 { 2112 struct panthor_group *group, *tmp; 2113 2114 if (tick_ctx_is_full(sched, ctx)) 2115 return; 2116 2117 list_for_each_entry_safe(group, tmp, queue, run_node) { 2118 u32 i; 2119 2120 if (!group_can_run(group)) 2121 continue; 2122 2123 if (skip_idle_groups && group_is_idle(group)) 2124 continue; 2125 2126 for (i = 0; i < ctx->as_count; i++) { 2127 if (ctx->vms[i] == group->vm) 2128 break; 2129 } 2130 2131 if (i == ctx->as_count && ctx->as_count == sched->as_slot_count) 2132 continue; 2133 2134 if (!owned_by_tick_ctx) 2135 group_get(group); 2136 2137 ctx->group_count++; 2138 2139 /* If we have more than one active group with the same priority, 2140 * we need to keep ticking to rotate the CSG priority. 2141 */ 2142 if (group_is_idle(group)) 2143 ctx->idle_group_count++; 2144 else if (!list_empty(&ctx->groups[group->priority])) 2145 ctx->stop_tick = false; 2146 2147 list_move_tail(&group->run_node, &ctx->groups[group->priority]); 2148 2149 if (i == ctx->as_count) 2150 ctx->vms[ctx->as_count++] = group->vm; 2151 2152 if (tick_ctx_is_full(sched, ctx)) 2153 return; 2154 } 2155 } 2156 2157 static void 2158 tick_ctx_insert_old_group(struct panthor_scheduler *sched, 2159 struct panthor_sched_tick_ctx *ctx, 2160 struct panthor_group *group) 2161 { 2162 struct panthor_csg_slot *csg_slot = &sched->csg_slots[group->csg_id]; 2163 struct panthor_group *other_group; 2164 2165 /* Class groups in descending priority order so we can easily rotate. */ 2166 list_for_each_entry(other_group, 2167 &ctx->old_groups[csg_slot->group->priority], 2168 run_node) { 2169 struct panthor_csg_slot *other_csg_slot = &sched->csg_slots[other_group->csg_id]; 2170 2171 /* Our group has a higher prio than the one we're testing against, 2172 * place it just before. 2173 */ 2174 if (csg_slot->priority > other_csg_slot->priority) { 2175 list_add_tail(&group->run_node, &other_group->run_node); 2176 return; 2177 } 2178 } 2179 2180 list_add_tail(&group->run_node, &ctx->old_groups[group->priority]); 2181 } 2182 2183 static void 2184 tick_ctx_init(struct panthor_scheduler *sched, 2185 struct panthor_sched_tick_ctx *ctx) 2186 { 2187 struct panthor_device *ptdev = sched->ptdev; 2188 struct panthor_csg_slots_upd_ctx upd_ctx; 2189 int ret; 2190 u32 i; 2191 2192 memset(ctx, 0, sizeof(*ctx)); 2193 csgs_upd_ctx_init(&upd_ctx); 2194 2195 ctx->stop_tick = true; 2196 for (i = 0; i < ARRAY_SIZE(ctx->groups); i++) { 2197 INIT_LIST_HEAD(&ctx->groups[i]); 2198 INIT_LIST_HEAD(&ctx->old_groups[i]); 2199 } 2200 2201 for (i = 0; i < sched->csg_slot_count; i++) { 2202 struct panthor_csg_slot *csg_slot = &sched->csg_slots[i]; 2203 struct panthor_group *group = csg_slot->group; 2204 struct panthor_fw_csg_iface *csg_iface; 2205 2206 if (!group) 2207 continue; 2208 2209 csg_iface = panthor_fw_get_csg_iface(ptdev, i); 2210 group_get(group); 2211 2212 /* If there was unhandled faults on the VM, force processing of 2213 * CSG IRQs, so we can flag the faulty queue. 2214 */ 2215 if (panthor_vm_has_unhandled_faults(group->vm)) { 2216 scoped_guard(spinlock, &sched->events_lock) 2217 sched_process_csg_irq_locked(ptdev, i); 2218 2219 /* No fatal fault reported, flag all queues as faulty. */ 2220 atomic_cmpxchg(&group->fatal_queues, 0, 2221 GENMASK(group->queue_count - 1, 0)); 2222 } 2223 2224 tick_ctx_insert_old_group(sched, ctx, group); 2225 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, i, 2226 csg_iface->output->ack ^ CSG_STATUS_UPDATE, 2227 CSG_STATUS_UPDATE); 2228 } 2229 2230 ret = csgs_upd_ctx_apply_locked(ptdev, &upd_ctx); 2231 if (ret) { 2232 panthor_device_schedule_reset(ptdev); 2233 ctx->csg_upd_failed_mask |= upd_ctx.timedout_mask; 2234 } 2235 } 2236 2237 static void 2238 group_term_post_processing(struct panthor_group *group) 2239 { 2240 struct panthor_job *job, *tmp; 2241 LIST_HEAD(faulty_jobs); 2242 bool cookie; 2243 u32 i = 0; 2244 2245 if (drm_WARN_ON(&group->ptdev->base, group_can_run(group))) 2246 return; 2247 2248 cookie = dma_fence_begin_signalling(); 2249 for (i = 0; i < group->queue_count; i++) { 2250 struct panthor_queue *queue = group->queues[i]; 2251 struct panthor_syncobj_64b *syncobj; 2252 int err; 2253 2254 if (atomic_read(&group->fatal_queues) & BIT(i)) 2255 err = -EINVAL; 2256 else if (atomic_read(&group->timedout)) 2257 err = -ETIMEDOUT; 2258 else 2259 err = -ECANCELED; 2260 2261 if (!queue) 2262 continue; 2263 2264 scoped_guard(spinlock_irqsave, &queue->fence_ctx.lock) { 2265 list_for_each_entry_safe(job, tmp, &queue->fence_ctx.in_flight_jobs, node) { 2266 list_move_tail(&job->node, &faulty_jobs); 2267 dma_fence_set_error(job->done_fence, err); 2268 dma_fence_signal_locked(job->done_fence); 2269 } 2270 } 2271 2272 /* Manually update the syncobj seqno to unblock waiters. */ 2273 syncobj = group->syncobjs->kmap + (i * sizeof(*syncobj)); 2274 syncobj->status = ~0; 2275 syncobj->seqno = atomic64_read(&queue->fence_ctx.seqno); 2276 sched_queue_work(group->ptdev->scheduler, sync_upd); 2277 } 2278 dma_fence_end_signalling(cookie); 2279 2280 list_for_each_entry_safe(job, tmp, &faulty_jobs, node) { 2281 list_del_init(&job->node); 2282 panthor_job_put(&job->base); 2283 } 2284 } 2285 2286 static void group_term_work(struct work_struct *work) 2287 { 2288 struct panthor_group *group = 2289 container_of(work, struct panthor_group, term_work); 2290 2291 group_term_post_processing(group); 2292 group_put(group); 2293 } 2294 2295 static void 2296 tick_ctx_cleanup(struct panthor_scheduler *sched, 2297 struct panthor_sched_tick_ctx *ctx) 2298 { 2299 struct panthor_device *ptdev = sched->ptdev; 2300 struct panthor_group *group, *tmp; 2301 u32 i; 2302 2303 for (i = 0; i < ARRAY_SIZE(ctx->old_groups); i++) { 2304 list_for_each_entry_safe(group, tmp, &ctx->old_groups[i], run_node) { 2305 /* If everything went fine, we should only have groups 2306 * to be terminated in the old_groups lists. 2307 */ 2308 drm_WARN_ON(&ptdev->base, !ctx->csg_upd_failed_mask && 2309 group_can_run(group)); 2310 2311 if (!group_can_run(group)) { 2312 list_del_init(&group->run_node); 2313 list_del_init(&group->wait_node); 2314 group_queue_work(group, term); 2315 } else if (group->csg_id >= 0) { 2316 list_del_init(&group->run_node); 2317 } else { 2318 list_move(&group->run_node, 2319 group_is_idle(group) ? 2320 &sched->groups.idle[group->priority] : 2321 &sched->groups.runnable[group->priority]); 2322 } 2323 group_put(group); 2324 } 2325 } 2326 2327 for (i = 0; i < ARRAY_SIZE(ctx->groups); i++) { 2328 /* If everything went fine, the groups to schedule lists should 2329 * be empty. 2330 */ 2331 drm_WARN_ON(&ptdev->base, 2332 !ctx->csg_upd_failed_mask && !list_empty(&ctx->groups[i])); 2333 2334 list_for_each_entry_safe(group, tmp, &ctx->groups[i], run_node) { 2335 if (group->csg_id >= 0) { 2336 list_del_init(&group->run_node); 2337 } else { 2338 list_move(&group->run_node, 2339 group_is_idle(group) ? 2340 &sched->groups.idle[group->priority] : 2341 &sched->groups.runnable[group->priority]); 2342 } 2343 group_put(group); 2344 } 2345 } 2346 } 2347 2348 static void 2349 tick_ctx_apply(struct panthor_scheduler *sched, struct panthor_sched_tick_ctx *ctx) 2350 { 2351 struct panthor_group *group, *tmp; 2352 struct panthor_device *ptdev = sched->ptdev; 2353 struct panthor_csg_slot *csg_slot; 2354 int prio, new_csg_prio = MAX_CSG_PRIO, i; 2355 u32 free_csg_slots = 0; 2356 struct panthor_csg_slots_upd_ctx upd_ctx; 2357 int ret; 2358 2359 csgs_upd_ctx_init(&upd_ctx); 2360 2361 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; prio >= 0; prio--) { 2362 /* Suspend or terminate evicted groups. */ 2363 list_for_each_entry(group, &ctx->old_groups[prio], run_node) { 2364 bool term = !group_can_run(group); 2365 int csg_id = group->csg_id; 2366 2367 if (drm_WARN_ON(&ptdev->base, csg_id < 0)) 2368 continue; 2369 2370 csg_slot = &sched->csg_slots[csg_id]; 2371 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, 2372 term ? CSG_STATE_TERMINATE : CSG_STATE_SUSPEND, 2373 CSG_STATE_MASK); 2374 } 2375 2376 /* Update priorities on already running groups. */ 2377 list_for_each_entry(group, &ctx->groups[prio], run_node) { 2378 struct panthor_fw_csg_iface *csg_iface; 2379 int csg_id = group->csg_id; 2380 2381 if (csg_id < 0) { 2382 new_csg_prio--; 2383 continue; 2384 } 2385 2386 csg_slot = &sched->csg_slots[csg_id]; 2387 csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); 2388 if (csg_slot->priority == new_csg_prio) { 2389 new_csg_prio--; 2390 continue; 2391 } 2392 2393 panthor_fw_csg_endpoint_req_update(ptdev, csg_iface, 2394 CSG_EP_REQ_PRIORITY(new_csg_prio), 2395 CSG_EP_REQ_PRIORITY_MASK); 2396 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, 2397 csg_iface->output->ack ^ CSG_ENDPOINT_CONFIG, 2398 CSG_ENDPOINT_CONFIG); 2399 new_csg_prio--; 2400 } 2401 } 2402 2403 ret = csgs_upd_ctx_apply_locked(ptdev, &upd_ctx); 2404 if (ret) { 2405 panthor_device_schedule_reset(ptdev); 2406 ctx->csg_upd_failed_mask |= upd_ctx.timedout_mask; 2407 return; 2408 } 2409 2410 /* Unbind evicted groups. */ 2411 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; prio >= 0; prio--) { 2412 list_for_each_entry(group, &ctx->old_groups[prio], run_node) 2413 group_unbind_locked(group); 2414 } 2415 2416 for (i = 0; i < sched->csg_slot_count; i++) { 2417 if (!sched->csg_slots[i].group) 2418 free_csg_slots |= BIT(i); 2419 } 2420 2421 csgs_upd_ctx_init(&upd_ctx); 2422 new_csg_prio = MAX_CSG_PRIO; 2423 2424 /* Start new groups. */ 2425 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; prio >= 0; prio--) { 2426 list_for_each_entry(group, &ctx->groups[prio], run_node) { 2427 int csg_id = group->csg_id; 2428 struct panthor_fw_csg_iface *csg_iface; 2429 2430 if (csg_id >= 0) { 2431 new_csg_prio--; 2432 continue; 2433 } 2434 2435 csg_id = ffs(free_csg_slots) - 1; 2436 if (drm_WARN_ON(&ptdev->base, csg_id < 0)) 2437 break; 2438 2439 csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); 2440 csg_slot = &sched->csg_slots[csg_id]; 2441 ret = group_bind_locked(group, csg_id); 2442 if (ret) { 2443 panthor_device_schedule_reset(ptdev); 2444 ctx->csg_upd_failed_mask |= BIT(csg_id); 2445 return; 2446 } 2447 2448 csg_slot_prog_locked(ptdev, csg_id, new_csg_prio--); 2449 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, 2450 group->state == PANTHOR_CS_GROUP_SUSPENDED ? 2451 CSG_STATE_RESUME : CSG_STATE_START, 2452 CSG_STATE_MASK); 2453 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, 2454 csg_iface->output->ack ^ CSG_ENDPOINT_CONFIG, 2455 CSG_ENDPOINT_CONFIG); 2456 free_csg_slots &= ~BIT(csg_id); 2457 } 2458 } 2459 2460 ret = csgs_upd_ctx_apply_locked(ptdev, &upd_ctx); 2461 if (ret) { 2462 panthor_device_schedule_reset(ptdev); 2463 ctx->csg_upd_failed_mask |= upd_ctx.timedout_mask; 2464 return; 2465 } 2466 2467 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; prio >= 0; prio--) { 2468 list_for_each_entry_safe(group, tmp, &ctx->groups[prio], run_node) { 2469 list_del_init(&group->run_node); 2470 2471 /* If the group has been destroyed while we were 2472 * scheduling, ask for an immediate tick to 2473 * re-evaluate as soon as possible and get rid of 2474 * this dangling group. 2475 */ 2476 if (group->destroyed) 2477 ctx->immediate_tick = true; 2478 group_put(group); 2479 } 2480 2481 /* Return evicted groups to the idle or run queues. Groups 2482 * that can no longer be run (because they've been destroyed 2483 * or experienced an unrecoverable error) will be scheduled 2484 * for destruction in tick_ctx_cleanup(). 2485 */ 2486 list_for_each_entry_safe(group, tmp, &ctx->old_groups[prio], run_node) { 2487 if (!group_can_run(group)) 2488 continue; 2489 2490 if (group_is_idle(group)) 2491 list_move_tail(&group->run_node, &sched->groups.idle[prio]); 2492 else 2493 list_move_tail(&group->run_node, &sched->groups.runnable[prio]); 2494 group_put(group); 2495 } 2496 } 2497 2498 sched->used_csg_slot_count = ctx->group_count; 2499 sched->might_have_idle_groups = ctx->idle_group_count > 0; 2500 } 2501 2502 static u64 2503 tick_ctx_update_resched_target(struct panthor_scheduler *sched, 2504 const struct panthor_sched_tick_ctx *ctx) 2505 { 2506 u64 resched_target; 2507 2508 if (ctx->stop_tick) 2509 goto no_tick; 2510 2511 resched_target = sched->last_tick + sched->tick_period; 2512 2513 if (time_before64(sched->resched_target, sched->last_tick) || 2514 time_before64(resched_target, sched->resched_target)) 2515 sched->resched_target = resched_target; 2516 2517 return sched->resched_target - sched->last_tick; 2518 2519 no_tick: 2520 sched->resched_target = U64_MAX; 2521 return U64_MAX; 2522 } 2523 2524 static void tick_work(struct work_struct *work) 2525 { 2526 struct panthor_scheduler *sched = container_of(work, struct panthor_scheduler, 2527 tick_work.work); 2528 struct panthor_device *ptdev = sched->ptdev; 2529 struct panthor_sched_tick_ctx ctx; 2530 u64 resched_target = sched->resched_target; 2531 u64 remaining_jiffies = 0, resched_delay; 2532 u64 now = get_jiffies_64(); 2533 int prio, ret, cookie; 2534 bool full_tick; 2535 2536 if (!drm_dev_enter(&ptdev->base, &cookie)) 2537 return; 2538 2539 ret = panthor_device_resume_and_get(ptdev); 2540 if (drm_WARN_ON(&ptdev->base, ret)) 2541 goto out_dev_exit; 2542 2543 /* If the tick is stopped, calculate when the next tick would be */ 2544 if (resched_target == U64_MAX) 2545 resched_target = sched->last_tick + sched->tick_period; 2546 2547 if (time_before64(now, resched_target)) 2548 remaining_jiffies = resched_target - now; 2549 2550 full_tick = remaining_jiffies == 0; 2551 2552 mutex_lock(&sched->lock); 2553 if (panthor_device_reset_is_pending(sched->ptdev)) 2554 goto out_unlock; 2555 2556 tick_ctx_init(sched, &ctx); 2557 if (ctx.csg_upd_failed_mask) 2558 goto out_cleanup_ctx; 2559 2560 if (!full_tick) { 2561 /* Scheduling forced in the middle of a tick. Only RT groups 2562 * can preempt non-RT ones. Currently running RT groups can't be 2563 * preempted. 2564 */ 2565 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; 2566 prio >= 0 && !tick_ctx_is_full(sched, &ctx); 2567 prio--) { 2568 tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], 2569 true, true); 2570 if (prio == PANTHOR_CSG_PRIORITY_RT) { 2571 tick_ctx_pick_groups_from_list(sched, &ctx, 2572 &sched->groups.runnable[prio], 2573 true, false); 2574 } 2575 } 2576 } 2577 2578 /* First pick non-idle groups */ 2579 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; 2580 prio >= 0 && !tick_ctx_is_full(sched, &ctx); 2581 prio--) { 2582 struct panthor_group *old_highest_prio_group = 2583 list_first_entry_or_null(&ctx.old_groups[prio], 2584 struct panthor_group, run_node); 2585 2586 /* Pull out the group with the highest prio for rotation. */ 2587 if (old_highest_prio_group) 2588 list_del(&old_highest_prio_group->run_node); 2589 2590 /* Re-insert old active groups so they get a chance to run with higher prio. */ 2591 tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], true, true); 2592 2593 /* Fill the remaining slots with runnable groups. */ 2594 tick_ctx_pick_groups_from_list(sched, &ctx, &sched->groups.runnable[prio], 2595 true, false); 2596 2597 /* Re-insert the old group with the highest prio, and give it a chance to be 2598 * scheduled again (but with a lower prio) if there's room left. 2599 */ 2600 if (old_highest_prio_group) { 2601 list_add_tail(&old_highest_prio_group->run_node, &ctx.old_groups[prio]); 2602 tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], 2603 true, true); 2604 } 2605 } 2606 2607 /* If we have free CSG slots left, pick idle groups */ 2608 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; 2609 prio >= 0 && !tick_ctx_is_full(sched, &ctx); 2610 prio--) { 2611 /* Check the old_group queue first to avoid reprogramming the slots */ 2612 tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], false, true); 2613 tick_ctx_pick_groups_from_list(sched, &ctx, &sched->groups.idle[prio], 2614 false, false); 2615 } 2616 2617 tick_ctx_apply(sched, &ctx); 2618 if (ctx.csg_upd_failed_mask) 2619 goto out_cleanup_ctx; 2620 2621 if (ctx.idle_group_count == ctx.group_count) { 2622 panthor_devfreq_record_idle(sched->ptdev); 2623 if (sched->pm.has_ref) { 2624 pm_runtime_put_autosuspend(ptdev->base.dev); 2625 sched->pm.has_ref = false; 2626 } 2627 } else { 2628 panthor_devfreq_record_busy(sched->ptdev); 2629 if (!sched->pm.has_ref) { 2630 pm_runtime_get(ptdev->base.dev); 2631 sched->pm.has_ref = true; 2632 } 2633 } 2634 2635 sched->last_tick = now; 2636 resched_delay = tick_ctx_update_resched_target(sched, &ctx); 2637 if (ctx.immediate_tick) 2638 resched_delay = 0; 2639 2640 if (resched_delay != U64_MAX) 2641 sched_queue_delayed_work(sched, tick, resched_delay); 2642 2643 out_cleanup_ctx: 2644 tick_ctx_cleanup(sched, &ctx); 2645 2646 out_unlock: 2647 mutex_unlock(&sched->lock); 2648 pm_runtime_mark_last_busy(ptdev->base.dev); 2649 pm_runtime_put_autosuspend(ptdev->base.dev); 2650 2651 out_dev_exit: 2652 drm_dev_exit(cookie); 2653 } 2654 2655 static int panthor_queue_eval_syncwait(struct panthor_group *group, u8 queue_idx) 2656 { 2657 struct panthor_queue *queue = group->queues[queue_idx]; 2658 union { 2659 struct panthor_syncobj_64b sync64; 2660 struct panthor_syncobj_32b sync32; 2661 } *syncobj; 2662 bool result; 2663 u64 value; 2664 2665 syncobj = panthor_queue_get_syncwait_obj(group, queue); 2666 if (!syncobj) 2667 return -EINVAL; 2668 2669 value = queue->syncwait.sync64 ? 2670 syncobj->sync64.seqno : 2671 syncobj->sync32.seqno; 2672 2673 if (queue->syncwait.gt) 2674 result = value > queue->syncwait.ref; 2675 else 2676 result = value <= queue->syncwait.ref; 2677 2678 if (result) 2679 panthor_queue_put_syncwait_obj(queue); 2680 2681 return result; 2682 } 2683 2684 static void sync_upd_work(struct work_struct *work) 2685 { 2686 struct panthor_scheduler *sched = container_of(work, 2687 struct panthor_scheduler, 2688 sync_upd_work); 2689 struct panthor_group *group, *tmp; 2690 bool immediate_tick = false; 2691 2692 mutex_lock(&sched->lock); 2693 list_for_each_entry_safe(group, tmp, &sched->groups.waiting, wait_node) { 2694 u32 tested_queues = group->blocked_queues; 2695 u32 unblocked_queues = 0; 2696 2697 while (tested_queues) { 2698 u32 cs_id = ffs(tested_queues) - 1; 2699 int ret; 2700 2701 ret = panthor_queue_eval_syncwait(group, cs_id); 2702 drm_WARN_ON(&group->ptdev->base, ret < 0); 2703 if (ret) 2704 unblocked_queues |= BIT(cs_id); 2705 2706 tested_queues &= ~BIT(cs_id); 2707 } 2708 2709 if (unblocked_queues) { 2710 group->blocked_queues &= ~unblocked_queues; 2711 2712 if (group->csg_id < 0) { 2713 list_move(&group->run_node, 2714 &sched->groups.runnable[group->priority]); 2715 if (group->priority == PANTHOR_CSG_PRIORITY_RT) 2716 immediate_tick = true; 2717 } 2718 } 2719 2720 if (!group->blocked_queues) 2721 list_del_init(&group->wait_node); 2722 } 2723 mutex_unlock(&sched->lock); 2724 2725 if (immediate_tick) 2726 sched_queue_delayed_work(sched, tick, 0); 2727 } 2728 2729 static void sched_resume_tick(struct panthor_device *ptdev) 2730 { 2731 struct panthor_scheduler *sched = ptdev->scheduler; 2732 u64 delay_jiffies, now; 2733 2734 drm_WARN_ON(&ptdev->base, sched->resched_target != U64_MAX); 2735 2736 /* Scheduler tick was off, recalculate the resched_target based on the 2737 * last tick event, and queue the scheduler work. 2738 */ 2739 now = get_jiffies_64(); 2740 sched->resched_target = sched->last_tick + sched->tick_period; 2741 if (sched->used_csg_slot_count == sched->csg_slot_count && 2742 time_before64(now, sched->resched_target)) 2743 delay_jiffies = min_t(unsigned long, sched->resched_target - now, ULONG_MAX); 2744 else 2745 delay_jiffies = 0; 2746 2747 /* We schedule immediate ticks when we need to process events on CSGs, 2748 * but those don't change the resched_target because we want the other 2749 * groups to stay scheduled for the remaining of the GPU timeslot they 2750 * were given. Make sure those immediate ticks don't get overruled by 2751 * a sched_queue_delayed_work() that would delay the tick execution. 2752 */ 2753 if (!delayed_work_pending(&sched->tick_work)) 2754 sched_queue_delayed_work(sched, tick, delay_jiffies); 2755 } 2756 2757 static void group_schedule_locked(struct panthor_group *group, u32 queue_mask) 2758 { 2759 struct panthor_device *ptdev = group->ptdev; 2760 struct panthor_scheduler *sched = ptdev->scheduler; 2761 struct list_head *queue = &sched->groups.runnable[group->priority]; 2762 bool was_idle; 2763 2764 if (!group_can_run(group)) 2765 return; 2766 2767 /* All updated queues are blocked, no need to wake up the scheduler. */ 2768 if ((queue_mask & group->blocked_queues) == queue_mask) 2769 return; 2770 2771 was_idle = group_is_idle(group); 2772 group->idle_queues &= ~queue_mask; 2773 2774 /* Don't mess up with the lists if we're in a middle of a reset. */ 2775 if (atomic_read(&sched->reset.in_progress)) 2776 return; 2777 2778 if (was_idle && !group_is_idle(group)) 2779 list_move_tail(&group->run_node, queue); 2780 2781 /* RT groups are preemptive. */ 2782 if (group->priority == PANTHOR_CSG_PRIORITY_RT) { 2783 sched_queue_delayed_work(sched, tick, 0); 2784 return; 2785 } 2786 2787 /* Some groups might be idle, force an immediate tick to 2788 * re-evaluate. 2789 */ 2790 if (sched->might_have_idle_groups) { 2791 sched_queue_delayed_work(sched, tick, 0); 2792 return; 2793 } 2794 2795 /* Scheduler is ticking, nothing to do. */ 2796 if (sched->resched_target != U64_MAX) { 2797 /* If there are free slots, force immediating ticking. */ 2798 if (sched->used_csg_slot_count < sched->csg_slot_count) 2799 sched_queue_delayed_work(sched, tick, 0); 2800 2801 return; 2802 } 2803 2804 /* Scheduler tick was off, recalculate the resched_target based on the 2805 * last tick event, and queue the scheduler work. 2806 */ 2807 sched_resume_tick(ptdev); 2808 } 2809 2810 static void queue_stop(struct panthor_queue *queue, 2811 struct panthor_job *bad_job) 2812 { 2813 disable_delayed_work_sync(&queue->timeout.work); 2814 drm_sched_stop(&queue->scheduler, bad_job ? &bad_job->base : NULL); 2815 } 2816 2817 static void queue_start(struct panthor_queue *queue) 2818 { 2819 struct panthor_job *job; 2820 2821 /* Re-assign the parent fences. */ 2822 list_for_each_entry(job, &queue->scheduler.pending_list, base.list) 2823 job->base.s_fence->parent = dma_fence_get(job->done_fence); 2824 2825 enable_delayed_work(&queue->timeout.work); 2826 drm_sched_start(&queue->scheduler, 0); 2827 } 2828 2829 static void panthor_group_stop(struct panthor_group *group) 2830 { 2831 struct panthor_scheduler *sched = group->ptdev->scheduler; 2832 2833 lockdep_assert_held(&sched->reset.lock); 2834 2835 for (u32 i = 0; i < group->queue_count; i++) 2836 queue_stop(group->queues[i], NULL); 2837 2838 group_get(group); 2839 list_move_tail(&group->run_node, &sched->reset.stopped_groups); 2840 } 2841 2842 static void panthor_group_start(struct panthor_group *group) 2843 { 2844 struct panthor_scheduler *sched = group->ptdev->scheduler; 2845 2846 lockdep_assert_held(&group->ptdev->scheduler->reset.lock); 2847 2848 for (u32 i = 0; i < group->queue_count; i++) 2849 queue_start(group->queues[i]); 2850 2851 if (group_can_run(group)) { 2852 list_move_tail(&group->run_node, 2853 group_is_idle(group) ? 2854 &sched->groups.idle[group->priority] : 2855 &sched->groups.runnable[group->priority]); 2856 } else { 2857 list_del_init(&group->run_node); 2858 list_del_init(&group->wait_node); 2859 group_queue_work(group, term); 2860 } 2861 2862 group_put(group); 2863 } 2864 2865 /** 2866 * panthor_sched_report_mmu_fault() - Report MMU faults to the scheduler. 2867 * @ptdev: Device. 2868 */ 2869 void panthor_sched_report_mmu_fault(struct panthor_device *ptdev) 2870 { 2871 /* Force a tick to immediately kill faulty groups. */ 2872 if (ptdev->scheduler) 2873 sched_queue_delayed_work(ptdev->scheduler, tick, 0); 2874 } 2875 2876 void panthor_sched_prepare_for_vm_destruction(struct panthor_device *ptdev) 2877 { 2878 /* FW can write out internal state, like the heap context, during CSG 2879 * suspend. It is therefore important that the scheduler has fully 2880 * evicted any pending and related groups before VM destruction can 2881 * safely continue. Failure to do so can lead to GPU page faults. 2882 * A controlled termination of a Panthor instance involves destroying 2883 * the group(s) before the VM. This means any relevant group eviction 2884 * has already been initiated by this point, and we just need to 2885 * ensure that any pending tick_work() has been completed. 2886 */ 2887 flush_work(&ptdev->scheduler->tick_work.work); 2888 } 2889 2890 void panthor_sched_resume(struct panthor_device *ptdev) 2891 { 2892 /* Force a tick to re-evaluate after a resume. */ 2893 sched_queue_delayed_work(ptdev->scheduler, tick, 0); 2894 } 2895 2896 void panthor_sched_suspend(struct panthor_device *ptdev) 2897 { 2898 struct panthor_scheduler *sched = ptdev->scheduler; 2899 struct panthor_csg_slots_upd_ctx upd_ctx; 2900 u32 suspended_slots; 2901 u32 i; 2902 2903 mutex_lock(&sched->lock); 2904 csgs_upd_ctx_init(&upd_ctx); 2905 for (i = 0; i < sched->csg_slot_count; i++) { 2906 struct panthor_csg_slot *csg_slot = &sched->csg_slots[i]; 2907 2908 if (csg_slot->group) { 2909 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, i, 2910 group_can_run(csg_slot->group) ? 2911 CSG_STATE_SUSPEND : CSG_STATE_TERMINATE, 2912 CSG_STATE_MASK); 2913 } 2914 } 2915 2916 suspended_slots = upd_ctx.update_mask; 2917 2918 csgs_upd_ctx_apply_locked(ptdev, &upd_ctx); 2919 suspended_slots &= ~upd_ctx.timedout_mask; 2920 2921 if (upd_ctx.timedout_mask) { 2922 u32 slot_mask = upd_ctx.timedout_mask; 2923 2924 drm_err(&ptdev->base, "CSG suspend failed, escalating to termination"); 2925 csgs_upd_ctx_init(&upd_ctx); 2926 while (slot_mask) { 2927 u32 csg_id = ffs(slot_mask) - 1; 2928 struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id]; 2929 2930 /* If the group was still usable before that point, we consider 2931 * it innocent. 2932 */ 2933 if (group_can_run(csg_slot->group)) 2934 csg_slot->group->innocent = true; 2935 2936 /* We consider group suspension failures as fatal and flag the 2937 * group as unusable by setting timedout=true. 2938 */ 2939 atomic_set(&csg_slot->group->timedout, true); 2940 2941 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, 2942 CSG_STATE_TERMINATE, 2943 CSG_STATE_MASK); 2944 slot_mask &= ~BIT(csg_id); 2945 } 2946 2947 csgs_upd_ctx_apply_locked(ptdev, &upd_ctx); 2948 2949 slot_mask = upd_ctx.timedout_mask; 2950 while (slot_mask) { 2951 u32 csg_id = ffs(slot_mask) - 1; 2952 struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id]; 2953 struct panthor_group *group = csg_slot->group; 2954 2955 /* Terminate command timedout, but the soft-reset will 2956 * automatically terminate all active groups, so let's 2957 * force the state to halted here. 2958 */ 2959 if (group->state != PANTHOR_CS_GROUP_TERMINATED) { 2960 group->state = PANTHOR_CS_GROUP_TERMINATED; 2961 2962 /* Reset the queue slots manually if the termination 2963 * request failed. 2964 */ 2965 for (i = 0; i < group->queue_count; i++) { 2966 if (group->queues[i]) 2967 cs_slot_reset_locked(ptdev, csg_id, i); 2968 } 2969 } 2970 slot_mask &= ~BIT(csg_id); 2971 } 2972 } 2973 2974 /* Flush L2 and LSC caches to make sure suspend state is up-to-date. 2975 * If the flush fails, flag all queues for termination. 2976 */ 2977 if (suspended_slots) { 2978 bool flush_caches_failed = false; 2979 u32 slot_mask = suspended_slots; 2980 2981 if (panthor_gpu_flush_caches(ptdev, CACHE_CLEAN, CACHE_CLEAN, 0)) 2982 flush_caches_failed = true; 2983 2984 while (slot_mask) { 2985 u32 csg_id = ffs(slot_mask) - 1; 2986 struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id]; 2987 2988 if (flush_caches_failed) { 2989 csg_slot->group->state = PANTHOR_CS_GROUP_TERMINATED; 2990 } else { 2991 guard(spinlock)(&sched->events_lock); 2992 csg_slot_sync_update_locked(ptdev, csg_id); 2993 } 2994 2995 slot_mask &= ~BIT(csg_id); 2996 } 2997 } 2998 2999 for (i = 0; i < sched->csg_slot_count; i++) { 3000 struct panthor_csg_slot *csg_slot = &sched->csg_slots[i]; 3001 struct panthor_group *group = csg_slot->group; 3002 3003 if (!group) 3004 continue; 3005 3006 group_get(group); 3007 group_unbind_locked(group); 3008 3009 drm_WARN_ON(&group->ptdev->base, !list_empty(&group->run_node)); 3010 3011 if (group_can_run(group)) { 3012 list_add(&group->run_node, 3013 &sched->groups.idle[group->priority]); 3014 } else { 3015 /* We don't bother stopping the scheduler if the group is 3016 * faulty, the group termination work will finish the job. 3017 */ 3018 list_del_init(&group->wait_node); 3019 group_queue_work(group, term); 3020 } 3021 group_put(group); 3022 } 3023 mutex_unlock(&sched->lock); 3024 } 3025 3026 void panthor_sched_pre_reset(struct panthor_device *ptdev) 3027 { 3028 struct panthor_scheduler *sched = ptdev->scheduler; 3029 struct panthor_group *group, *group_tmp; 3030 u32 i; 3031 3032 mutex_lock(&sched->reset.lock); 3033 atomic_set(&sched->reset.in_progress, true); 3034 3035 /* Cancel all scheduler works. Once this is done, these works can't be 3036 * scheduled again until the reset operation is complete. 3037 */ 3038 cancel_work_sync(&sched->sync_upd_work); 3039 cancel_delayed_work_sync(&sched->tick_work); 3040 3041 panthor_sched_suspend(ptdev); 3042 3043 /* Stop all groups that might still accept jobs, so we don't get passed 3044 * new jobs while we're resetting. 3045 */ 3046 for (i = 0; i < ARRAY_SIZE(sched->groups.runnable); i++) { 3047 list_for_each_entry_safe(group, group_tmp, &sched->groups.runnable[i], run_node) 3048 panthor_group_stop(group); 3049 } 3050 3051 for (i = 0; i < ARRAY_SIZE(sched->groups.idle); i++) { 3052 list_for_each_entry_safe(group, group_tmp, &sched->groups.idle[i], run_node) 3053 panthor_group_stop(group); 3054 } 3055 3056 mutex_unlock(&sched->reset.lock); 3057 } 3058 3059 void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed) 3060 { 3061 struct panthor_scheduler *sched = ptdev->scheduler; 3062 struct panthor_group *group, *group_tmp; 3063 3064 mutex_lock(&sched->reset.lock); 3065 3066 list_for_each_entry_safe(group, group_tmp, &sched->reset.stopped_groups, run_node) { 3067 /* Consider all previously running group as terminated if the 3068 * reset failed. 3069 */ 3070 if (reset_failed) 3071 group->state = PANTHOR_CS_GROUP_TERMINATED; 3072 3073 panthor_group_start(group); 3074 } 3075 3076 /* We're done resetting the GPU, clear the reset.in_progress bit so we can 3077 * kick the scheduler. 3078 */ 3079 atomic_set(&sched->reset.in_progress, false); 3080 mutex_unlock(&sched->reset.lock); 3081 3082 /* No need to queue a tick and update syncs if the reset failed. */ 3083 if (!reset_failed) { 3084 sched_queue_delayed_work(sched, tick, 0); 3085 sched_queue_work(sched, sync_upd); 3086 } 3087 } 3088 3089 void panthor_fdinfo_gather_group_samples(struct panthor_file *pfile) 3090 { 3091 struct panthor_group_pool *gpool = pfile->groups; 3092 struct panthor_group *group; 3093 unsigned long i; 3094 3095 if (IS_ERR_OR_NULL(gpool)) 3096 return; 3097 3098 xa_lock(&gpool->xa); 3099 xa_for_each_marked(&gpool->xa, i, group, GROUP_REGISTERED) { 3100 guard(spinlock)(&group->fdinfo.lock); 3101 pfile->stats.cycles += group->fdinfo.data.cycles; 3102 pfile->stats.time += group->fdinfo.data.time; 3103 group->fdinfo.data.cycles = 0; 3104 group->fdinfo.data.time = 0; 3105 } 3106 xa_unlock(&gpool->xa); 3107 } 3108 3109 struct panthor_job_ringbuf_instrs { 3110 u64 buffer[MAX_INSTRS_PER_JOB]; 3111 u32 count; 3112 }; 3113 3114 struct panthor_job_instr { 3115 u32 profile_mask; 3116 u64 instr; 3117 }; 3118 3119 #define JOB_INSTR(__prof, __instr) \ 3120 { \ 3121 .profile_mask = __prof, \ 3122 .instr = __instr, \ 3123 } 3124 3125 static void 3126 copy_instrs_to_ringbuf(struct panthor_queue *queue, 3127 struct panthor_job *job, 3128 struct panthor_job_ringbuf_instrs *instrs) 3129 { 3130 u64 ringbuf_size = panthor_kernel_bo_size(queue->ringbuf); 3131 u64 start = job->ringbuf.start & (ringbuf_size - 1); 3132 u64 size, written; 3133 3134 /* 3135 * We need to write a whole slot, including any trailing zeroes 3136 * that may come at the end of it. Also, because instrs.buffer has 3137 * been zero-initialised, there's no need to pad it with 0's 3138 */ 3139 instrs->count = ALIGN(instrs->count, NUM_INSTRS_PER_CACHE_LINE); 3140 size = instrs->count * sizeof(u64); 3141 WARN_ON(size > ringbuf_size); 3142 written = min(ringbuf_size - start, size); 3143 3144 memcpy(queue->ringbuf->kmap + start, instrs->buffer, written); 3145 3146 if (written < size) 3147 memcpy(queue->ringbuf->kmap, 3148 &instrs->buffer[written / sizeof(u64)], 3149 size - written); 3150 } 3151 3152 struct panthor_job_cs_params { 3153 u32 profile_mask; 3154 u64 addr_reg; u64 val_reg; 3155 u64 cycle_reg; u64 time_reg; 3156 u64 sync_addr; u64 times_addr; 3157 u64 cs_start; u64 cs_size; 3158 u32 last_flush; u32 waitall_mask; 3159 }; 3160 3161 static void 3162 get_job_cs_params(struct panthor_job *job, struct panthor_job_cs_params *params) 3163 { 3164 struct panthor_group *group = job->group; 3165 struct panthor_queue *queue = group->queues[job->queue_idx]; 3166 struct panthor_device *ptdev = group->ptdev; 3167 struct panthor_scheduler *sched = ptdev->scheduler; 3168 3169 params->addr_reg = ptdev->csif_info.cs_reg_count - 3170 ptdev->csif_info.unpreserved_cs_reg_count; 3171 params->val_reg = params->addr_reg + 2; 3172 params->cycle_reg = params->addr_reg; 3173 params->time_reg = params->val_reg; 3174 3175 params->sync_addr = panthor_kernel_bo_gpuva(group->syncobjs) + 3176 job->queue_idx * sizeof(struct panthor_syncobj_64b); 3177 params->times_addr = panthor_kernel_bo_gpuva(queue->profiling.slots) + 3178 (job->profiling.slot * sizeof(struct panthor_job_profiling_data)); 3179 params->waitall_mask = GENMASK(sched->sb_slot_count - 1, 0); 3180 3181 params->cs_start = job->call_info.start; 3182 params->cs_size = job->call_info.size; 3183 params->last_flush = job->call_info.latest_flush; 3184 3185 params->profile_mask = job->profiling.mask; 3186 } 3187 3188 #define JOB_INSTR_ALWAYS(instr) \ 3189 JOB_INSTR(PANTHOR_DEVICE_PROFILING_DISABLED, (instr)) 3190 #define JOB_INSTR_TIMESTAMP(instr) \ 3191 JOB_INSTR(PANTHOR_DEVICE_PROFILING_TIMESTAMP, (instr)) 3192 #define JOB_INSTR_CYCLES(instr) \ 3193 JOB_INSTR(PANTHOR_DEVICE_PROFILING_CYCLES, (instr)) 3194 3195 static void 3196 prepare_job_instrs(const struct panthor_job_cs_params *params, 3197 struct panthor_job_ringbuf_instrs *instrs) 3198 { 3199 const struct panthor_job_instr instr_seq[] = { 3200 /* MOV32 rX+2, cs.latest_flush */ 3201 JOB_INSTR_ALWAYS((2ull << 56) | (params->val_reg << 48) | params->last_flush), 3202 /* FLUSH_CACHE2.clean_inv_all.no_wait.signal(0) rX+2 */ 3203 JOB_INSTR_ALWAYS((36ull << 56) | (0ull << 48) | (params->val_reg << 40) | 3204 (0 << 16) | 0x233), 3205 /* MOV48 rX:rX+1, cycles_offset */ 3206 JOB_INSTR_CYCLES((1ull << 56) | (params->cycle_reg << 48) | 3207 (params->times_addr + 3208 offsetof(struct panthor_job_profiling_data, cycles.before))), 3209 /* STORE_STATE cycles */ 3210 JOB_INSTR_CYCLES((40ull << 56) | (params->cycle_reg << 40) | (1ll << 32)), 3211 /* MOV48 rX:rX+1, time_offset */ 3212 JOB_INSTR_TIMESTAMP((1ull << 56) | (params->time_reg << 48) | 3213 (params->times_addr + 3214 offsetof(struct panthor_job_profiling_data, time.before))), 3215 /* STORE_STATE timer */ 3216 JOB_INSTR_TIMESTAMP((40ull << 56) | (params->time_reg << 40) | (0ll << 32)), 3217 /* MOV48 rX:rX+1, cs.start */ 3218 JOB_INSTR_ALWAYS((1ull << 56) | (params->addr_reg << 48) | params->cs_start), 3219 /* MOV32 rX+2, cs.size */ 3220 JOB_INSTR_ALWAYS((2ull << 56) | (params->val_reg << 48) | params->cs_size), 3221 /* WAIT(0) => waits for FLUSH_CACHE2 instruction */ 3222 JOB_INSTR_ALWAYS((3ull << 56) | (1 << 16)), 3223 /* CALL rX:rX+1, rX+2 */ 3224 JOB_INSTR_ALWAYS((32ull << 56) | (params->addr_reg << 40) | 3225 (params->val_reg << 32)), 3226 /* MOV48 rX:rX+1, cycles_offset */ 3227 JOB_INSTR_CYCLES((1ull << 56) | (params->cycle_reg << 48) | 3228 (params->times_addr + 3229 offsetof(struct panthor_job_profiling_data, cycles.after))), 3230 /* STORE_STATE cycles */ 3231 JOB_INSTR_CYCLES((40ull << 56) | (params->cycle_reg << 40) | (1ll << 32)), 3232 /* MOV48 rX:rX+1, time_offset */ 3233 JOB_INSTR_TIMESTAMP((1ull << 56) | (params->time_reg << 48) | 3234 (params->times_addr + 3235 offsetof(struct panthor_job_profiling_data, time.after))), 3236 /* STORE_STATE timer */ 3237 JOB_INSTR_TIMESTAMP((40ull << 56) | (params->time_reg << 40) | (0ll << 32)), 3238 /* MOV48 rX:rX+1, sync_addr */ 3239 JOB_INSTR_ALWAYS((1ull << 56) | (params->addr_reg << 48) | params->sync_addr), 3240 /* MOV48 rX+2, #1 */ 3241 JOB_INSTR_ALWAYS((1ull << 56) | (params->val_reg << 48) | 1), 3242 /* WAIT(all) */ 3243 JOB_INSTR_ALWAYS((3ull << 56) | (params->waitall_mask << 16)), 3244 /* SYNC_ADD64.system_scope.propage_err.nowait rX:rX+1, rX+2*/ 3245 JOB_INSTR_ALWAYS((51ull << 56) | (0ull << 48) | (params->addr_reg << 40) | 3246 (params->val_reg << 32) | (0 << 16) | 1), 3247 /* ERROR_BARRIER, so we can recover from faults at job boundaries. */ 3248 JOB_INSTR_ALWAYS((47ull << 56)), 3249 }; 3250 u32 pad; 3251 3252 instrs->count = 0; 3253 3254 /* NEED to be cacheline aligned to please the prefetcher. */ 3255 static_assert(sizeof(instrs->buffer) % 64 == 0, 3256 "panthor_job_ringbuf_instrs::buffer is not aligned on a cacheline"); 3257 3258 /* Make sure we have enough storage to store the whole sequence. */ 3259 static_assert(ALIGN(ARRAY_SIZE(instr_seq), NUM_INSTRS_PER_CACHE_LINE) == 3260 ARRAY_SIZE(instrs->buffer), 3261 "instr_seq vs panthor_job_ringbuf_instrs::buffer size mismatch"); 3262 3263 for (u32 i = 0; i < ARRAY_SIZE(instr_seq); i++) { 3264 /* If the profile mask of this instruction is not enabled, skip it. */ 3265 if (instr_seq[i].profile_mask && 3266 !(instr_seq[i].profile_mask & params->profile_mask)) 3267 continue; 3268 3269 instrs->buffer[instrs->count++] = instr_seq[i].instr; 3270 } 3271 3272 pad = ALIGN(instrs->count, NUM_INSTRS_PER_CACHE_LINE); 3273 memset(&instrs->buffer[instrs->count], 0, 3274 (pad - instrs->count) * sizeof(instrs->buffer[0])); 3275 instrs->count = pad; 3276 } 3277 3278 static u32 calc_job_credits(u32 profile_mask) 3279 { 3280 struct panthor_job_ringbuf_instrs instrs; 3281 struct panthor_job_cs_params params = { 3282 .profile_mask = profile_mask, 3283 }; 3284 3285 prepare_job_instrs(¶ms, &instrs); 3286 return instrs.count; 3287 } 3288 3289 static struct dma_fence * 3290 queue_run_job(struct drm_sched_job *sched_job) 3291 { 3292 struct panthor_job *job = container_of(sched_job, struct panthor_job, base); 3293 struct panthor_group *group = job->group; 3294 struct panthor_queue *queue = group->queues[job->queue_idx]; 3295 struct panthor_device *ptdev = group->ptdev; 3296 struct panthor_scheduler *sched = ptdev->scheduler; 3297 struct panthor_job_ringbuf_instrs instrs; 3298 struct panthor_job_cs_params cs_params; 3299 struct dma_fence *done_fence; 3300 int ret; 3301 3302 /* Stream size is zero, nothing to do except making sure all previously 3303 * submitted jobs are done before we signal the 3304 * drm_sched_job::s_fence::finished fence. 3305 */ 3306 if (!job->call_info.size) { 3307 job->done_fence = dma_fence_get(queue->fence_ctx.last_fence); 3308 return dma_fence_get(job->done_fence); 3309 } 3310 3311 ret = panthor_device_resume_and_get(ptdev); 3312 if (drm_WARN_ON(&ptdev->base, ret)) 3313 return ERR_PTR(ret); 3314 3315 mutex_lock(&sched->lock); 3316 if (!group_can_run(group)) { 3317 done_fence = ERR_PTR(-ECANCELED); 3318 goto out_unlock; 3319 } 3320 3321 dma_fence_init(job->done_fence, 3322 &panthor_queue_fence_ops, 3323 &queue->fence_ctx.lock, 3324 queue->fence_ctx.id, 3325 atomic64_inc_return(&queue->fence_ctx.seqno)); 3326 3327 job->profiling.slot = queue->profiling.seqno++; 3328 if (queue->profiling.seqno == queue->profiling.slot_count) 3329 queue->profiling.seqno = 0; 3330 3331 job->ringbuf.start = queue->iface.input->insert; 3332 3333 get_job_cs_params(job, &cs_params); 3334 prepare_job_instrs(&cs_params, &instrs); 3335 copy_instrs_to_ringbuf(queue, job, &instrs); 3336 3337 job->ringbuf.end = job->ringbuf.start + (instrs.count * sizeof(u64)); 3338 3339 panthor_job_get(&job->base); 3340 scoped_guard(spinlock_irqsave, &queue->fence_ctx.lock) 3341 list_add_tail(&job->node, &queue->fence_ctx.in_flight_jobs); 3342 3343 /* Make sure the ring buffer is updated before the INSERT 3344 * register. 3345 */ 3346 wmb(); 3347 3348 queue->iface.input->extract = queue->iface.output->extract; 3349 queue->iface.input->insert = job->ringbuf.end; 3350 3351 if (group->csg_id < 0) { 3352 group_schedule_locked(group, BIT(job->queue_idx)); 3353 } else { 3354 u32 queue_mask = BIT(job->queue_idx); 3355 bool resume_tick = group_is_idle(group) && 3356 (group->idle_queues & queue_mask) && 3357 !(group->blocked_queues & queue_mask) && 3358 sched->resched_target == U64_MAX; 3359 3360 /* We just added something to the queue, so it's no longer idle. */ 3361 group->idle_queues &= ~queue_mask; 3362 3363 if (resume_tick) 3364 sched_resume_tick(ptdev); 3365 3366 panthor_fw_ring_doorbell(ptdev, queue->doorbell_id); 3367 if (!sched->pm.has_ref && 3368 !(group->blocked_queues & BIT(job->queue_idx))) { 3369 pm_runtime_get(ptdev->base.dev); 3370 sched->pm.has_ref = true; 3371 } 3372 queue_resume_timeout(queue); 3373 panthor_devfreq_record_busy(sched->ptdev); 3374 } 3375 3376 /* Update the last fence. */ 3377 dma_fence_put(queue->fence_ctx.last_fence); 3378 queue->fence_ctx.last_fence = dma_fence_get(job->done_fence); 3379 3380 done_fence = dma_fence_get(job->done_fence); 3381 3382 out_unlock: 3383 mutex_unlock(&sched->lock); 3384 pm_runtime_mark_last_busy(ptdev->base.dev); 3385 pm_runtime_put_autosuspend(ptdev->base.dev); 3386 3387 return done_fence; 3388 } 3389 3390 static enum drm_gpu_sched_stat 3391 queue_timedout_job(struct drm_sched_job *sched_job) 3392 { 3393 struct panthor_job *job = container_of(sched_job, struct panthor_job, base); 3394 struct panthor_group *group = job->group; 3395 struct panthor_device *ptdev = group->ptdev; 3396 struct panthor_scheduler *sched = ptdev->scheduler; 3397 struct panthor_queue *queue = group->queues[job->queue_idx]; 3398 3399 drm_warn(&ptdev->base, "job timeout: pid=%d, comm=%s, seqno=%llu\n", 3400 group->task_info.pid, group->task_info.comm, job->done_fence->seqno); 3401 3402 drm_WARN_ON(&ptdev->base, atomic_read(&sched->reset.in_progress)); 3403 3404 queue_stop(queue, job); 3405 3406 mutex_lock(&sched->lock); 3407 atomic_set(&group->timedout, true); 3408 if (group->csg_id >= 0) { 3409 sched_queue_delayed_work(ptdev->scheduler, tick, 0); 3410 } else { 3411 /* Remove from the run queues, so the scheduler can't 3412 * pick the group on the next tick. 3413 */ 3414 list_del_init(&group->run_node); 3415 list_del_init(&group->wait_node); 3416 3417 group_queue_work(group, term); 3418 } 3419 mutex_unlock(&sched->lock); 3420 3421 queue_start(queue); 3422 return DRM_GPU_SCHED_STAT_RESET; 3423 } 3424 3425 static void queue_free_job(struct drm_sched_job *sched_job) 3426 { 3427 panthor_job_put(sched_job); 3428 } 3429 3430 static const struct drm_sched_backend_ops panthor_queue_sched_ops = { 3431 .run_job = queue_run_job, 3432 .timedout_job = queue_timedout_job, 3433 .free_job = queue_free_job, 3434 }; 3435 3436 static u32 calc_profiling_ringbuf_num_slots(struct panthor_device *ptdev, 3437 u32 cs_ringbuf_size) 3438 { 3439 u32 min_profiled_job_instrs = U32_MAX; 3440 u32 last_flag = fls(PANTHOR_DEVICE_PROFILING_ALL); 3441 3442 /* 3443 * We want to calculate the minimum size of a profiled job's CS, 3444 * because since they need additional instructions for the sampling 3445 * of performance metrics, they might take up further slots in 3446 * the queue's ringbuffer. This means we might not need as many job 3447 * slots for keeping track of their profiling information. What we 3448 * need is the maximum number of slots we should allocate to this end, 3449 * which matches the maximum number of profiled jobs we can place 3450 * simultaneously in the queue's ring buffer. 3451 * That has to be calculated separately for every single job profiling 3452 * flag, but not in the case job profiling is disabled, since unprofiled 3453 * jobs don't need to keep track of this at all. 3454 */ 3455 for (u32 i = 0; i < last_flag; i++) { 3456 min_profiled_job_instrs = 3457 min(min_profiled_job_instrs, calc_job_credits(BIT(i))); 3458 } 3459 3460 return DIV_ROUND_UP(cs_ringbuf_size, min_profiled_job_instrs * sizeof(u64)); 3461 } 3462 3463 static void queue_timeout_work(struct work_struct *work) 3464 { 3465 struct panthor_queue *queue = container_of(work, struct panthor_queue, 3466 timeout.work.work); 3467 bool progress; 3468 3469 progress = queue_check_job_completion(queue); 3470 if (!progress) 3471 drm_sched_fault(&queue->scheduler); 3472 } 3473 3474 static struct panthor_queue * 3475 group_create_queue(struct panthor_group *group, 3476 const struct drm_panthor_queue_create *args, 3477 u64 drm_client_id, u32 gid, u32 qid) 3478 { 3479 struct drm_sched_init_args sched_args = { 3480 .ops = &panthor_queue_sched_ops, 3481 .submit_wq = group->ptdev->scheduler->wq, 3482 .num_rqs = 1, 3483 /* 3484 * The credit limit argument tells us the total number of 3485 * instructions across all CS slots in the ringbuffer, with 3486 * some jobs requiring twice as many as others, depending on 3487 * their profiling status. 3488 */ 3489 .credit_limit = args->ringbuf_size / sizeof(u64), 3490 .timeout = MAX_SCHEDULE_TIMEOUT, 3491 .timeout_wq = group->ptdev->reset.wq, 3492 .dev = group->ptdev->base.dev, 3493 }; 3494 struct drm_gpu_scheduler *drm_sched; 3495 struct panthor_queue *queue; 3496 int ret; 3497 3498 if (args->pad[0] || args->pad[1] || args->pad[2]) 3499 return ERR_PTR(-EINVAL); 3500 3501 if (args->ringbuf_size < SZ_4K || args->ringbuf_size > SZ_64K || 3502 !is_power_of_2(args->ringbuf_size)) 3503 return ERR_PTR(-EINVAL); 3504 3505 if (args->priority > CSF_MAX_QUEUE_PRIO) 3506 return ERR_PTR(-EINVAL); 3507 3508 queue = kzalloc_obj(*queue); 3509 if (!queue) 3510 return ERR_PTR(-ENOMEM); 3511 3512 queue->timeout.remaining = msecs_to_jiffies(JOB_TIMEOUT_MS); 3513 INIT_DELAYED_WORK(&queue->timeout.work, queue_timeout_work); 3514 queue->fence_ctx.id = dma_fence_context_alloc(1); 3515 spin_lock_init(&queue->fence_ctx.lock); 3516 INIT_LIST_HEAD(&queue->fence_ctx.in_flight_jobs); 3517 3518 queue->priority = args->priority; 3519 3520 queue->ringbuf = panthor_kernel_bo_create(group->ptdev, group->vm, 3521 args->ringbuf_size, 3522 DRM_PANTHOR_BO_NO_MMAP, 3523 DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | 3524 DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED, 3525 PANTHOR_VM_KERNEL_AUTO_VA, 3526 "CS ring buffer"); 3527 if (IS_ERR(queue->ringbuf)) { 3528 ret = PTR_ERR(queue->ringbuf); 3529 goto err_free_queue; 3530 } 3531 3532 ret = panthor_kernel_bo_vmap(queue->ringbuf); 3533 if (ret) 3534 goto err_free_queue; 3535 3536 queue->iface.mem = panthor_fw_alloc_queue_iface_mem(group->ptdev, 3537 &queue->iface.input, 3538 &queue->iface.output, 3539 &queue->iface.input_fw_va, 3540 &queue->iface.output_fw_va); 3541 if (IS_ERR(queue->iface.mem)) { 3542 ret = PTR_ERR(queue->iface.mem); 3543 goto err_free_queue; 3544 } 3545 3546 queue->profiling.slot_count = 3547 calc_profiling_ringbuf_num_slots(group->ptdev, args->ringbuf_size); 3548 3549 queue->profiling.slots = 3550 panthor_kernel_bo_create(group->ptdev, group->vm, 3551 queue->profiling.slot_count * 3552 sizeof(struct panthor_job_profiling_data), 3553 DRM_PANTHOR_BO_NO_MMAP, 3554 DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | 3555 DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED, 3556 PANTHOR_VM_KERNEL_AUTO_VA, 3557 "Group job stats"); 3558 3559 if (IS_ERR(queue->profiling.slots)) { 3560 ret = PTR_ERR(queue->profiling.slots); 3561 goto err_free_queue; 3562 } 3563 3564 ret = panthor_kernel_bo_vmap(queue->profiling.slots); 3565 if (ret) 3566 goto err_free_queue; 3567 3568 /* assign a unique name */ 3569 queue->name = kasprintf(GFP_KERNEL, "panthor-queue-%llu-%u-%u", drm_client_id, gid, qid); 3570 if (!queue->name) { 3571 ret = -ENOMEM; 3572 goto err_free_queue; 3573 } 3574 3575 sched_args.name = queue->name; 3576 3577 ret = drm_sched_init(&queue->scheduler, &sched_args); 3578 if (ret) 3579 goto err_free_queue; 3580 3581 drm_sched = &queue->scheduler; 3582 ret = drm_sched_entity_init(&queue->entity, 0, &drm_sched, 1, NULL); 3583 if (ret) 3584 goto err_free_queue; 3585 3586 return queue; 3587 3588 err_free_queue: 3589 group_free_queue(group, queue); 3590 return ERR_PTR(ret); 3591 } 3592 3593 static void group_init_task_info(struct panthor_group *group) 3594 { 3595 struct task_struct *task = current->group_leader; 3596 3597 group->task_info.pid = task->pid; 3598 get_task_comm(group->task_info.comm, task); 3599 } 3600 3601 static void add_group_kbo_sizes(struct panthor_device *ptdev, 3602 struct panthor_group *group) 3603 { 3604 struct panthor_queue *queue; 3605 int i; 3606 3607 if (drm_WARN_ON(&ptdev->base, IS_ERR_OR_NULL(group))) 3608 return; 3609 if (drm_WARN_ON(&ptdev->base, ptdev != group->ptdev)) 3610 return; 3611 3612 group->fdinfo.kbo_sizes += group->suspend_buf->obj->size; 3613 group->fdinfo.kbo_sizes += group->protm_suspend_buf->obj->size; 3614 group->fdinfo.kbo_sizes += group->syncobjs->obj->size; 3615 3616 for (i = 0; i < group->queue_count; i++) { 3617 queue = group->queues[i]; 3618 group->fdinfo.kbo_sizes += queue->ringbuf->obj->size; 3619 group->fdinfo.kbo_sizes += queue->iface.mem->obj->size; 3620 group->fdinfo.kbo_sizes += queue->profiling.slots->obj->size; 3621 } 3622 } 3623 3624 #define MAX_GROUPS_PER_POOL 128 3625 3626 int panthor_group_create(struct panthor_file *pfile, 3627 const struct drm_panthor_group_create *group_args, 3628 const struct drm_panthor_queue_create *queue_args, 3629 u64 drm_client_id) 3630 { 3631 struct panthor_device *ptdev = pfile->ptdev; 3632 struct panthor_group_pool *gpool = pfile->groups; 3633 struct panthor_scheduler *sched = ptdev->scheduler; 3634 struct panthor_fw_csg_iface *csg_iface = panthor_fw_get_csg_iface(ptdev, 0); 3635 struct panthor_group *group = NULL; 3636 u32 gid, i, suspend_size; 3637 int ret; 3638 3639 if (group_args->pad) 3640 return -EINVAL; 3641 3642 if (group_args->priority >= PANTHOR_CSG_PRIORITY_COUNT) 3643 return -EINVAL; 3644 3645 if ((group_args->compute_core_mask & ~ptdev->gpu_info.shader_present) || 3646 (group_args->fragment_core_mask & ~ptdev->gpu_info.shader_present) || 3647 (group_args->tiler_core_mask & ~ptdev->gpu_info.tiler_present)) 3648 return -EINVAL; 3649 3650 if (hweight64(group_args->compute_core_mask) < group_args->max_compute_cores || 3651 hweight64(group_args->fragment_core_mask) < group_args->max_fragment_cores || 3652 hweight64(group_args->tiler_core_mask) < group_args->max_tiler_cores) 3653 return -EINVAL; 3654 3655 if (group_args->queues.count > sched->cs_slot_count) 3656 return -EINVAL; 3657 3658 group = kzalloc_obj(*group); 3659 if (!group) 3660 return -ENOMEM; 3661 3662 kref_init(&group->refcount); 3663 group->state = PANTHOR_CS_GROUP_CREATED; 3664 group->csg_id = -1; 3665 3666 group->ptdev = ptdev; 3667 group->max_compute_cores = group_args->max_compute_cores; 3668 group->compute_core_mask = group_args->compute_core_mask; 3669 group->max_fragment_cores = group_args->max_fragment_cores; 3670 group->fragment_core_mask = group_args->fragment_core_mask; 3671 group->max_tiler_cores = group_args->max_tiler_cores; 3672 group->tiler_core_mask = group_args->tiler_core_mask; 3673 group->priority = group_args->priority; 3674 3675 INIT_LIST_HEAD(&group->wait_node); 3676 INIT_LIST_HEAD(&group->run_node); 3677 INIT_WORK(&group->term_work, group_term_work); 3678 INIT_WORK(&group->tiler_oom_work, group_tiler_oom_work); 3679 INIT_WORK(&group->release_work, group_release_work); 3680 3681 group->vm = panthor_vm_pool_get_vm(pfile->vms, group_args->vm_id); 3682 if (!group->vm) { 3683 ret = -EINVAL; 3684 goto err_put_group; 3685 } 3686 3687 suspend_size = csg_iface->control->suspend_size; 3688 group->suspend_buf = panthor_fw_alloc_suspend_buf_mem(ptdev, suspend_size); 3689 if (IS_ERR(group->suspend_buf)) { 3690 ret = PTR_ERR(group->suspend_buf); 3691 group->suspend_buf = NULL; 3692 goto err_put_group; 3693 } 3694 3695 suspend_size = csg_iface->control->protm_suspend_size; 3696 group->protm_suspend_buf = panthor_fw_alloc_suspend_buf_mem(ptdev, suspend_size); 3697 if (IS_ERR(group->protm_suspend_buf)) { 3698 ret = PTR_ERR(group->protm_suspend_buf); 3699 group->protm_suspend_buf = NULL; 3700 goto err_put_group; 3701 } 3702 3703 group->syncobjs = panthor_kernel_bo_create(ptdev, group->vm, 3704 group_args->queues.count * 3705 sizeof(struct panthor_syncobj_64b), 3706 DRM_PANTHOR_BO_NO_MMAP, 3707 DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | 3708 DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED, 3709 PANTHOR_VM_KERNEL_AUTO_VA, 3710 "Group sync objects"); 3711 if (IS_ERR(group->syncobjs)) { 3712 ret = PTR_ERR(group->syncobjs); 3713 goto err_put_group; 3714 } 3715 3716 ret = panthor_kernel_bo_vmap(group->syncobjs); 3717 if (ret) 3718 goto err_put_group; 3719 3720 memset(group->syncobjs->kmap, 0, 3721 group_args->queues.count * sizeof(struct panthor_syncobj_64b)); 3722 3723 ret = xa_alloc(&gpool->xa, &gid, group, XA_LIMIT(1, MAX_GROUPS_PER_POOL), GFP_KERNEL); 3724 if (ret) 3725 goto err_put_group; 3726 3727 for (i = 0; i < group_args->queues.count; i++) { 3728 group->queues[i] = group_create_queue(group, &queue_args[i], drm_client_id, gid, i); 3729 if (IS_ERR(group->queues[i])) { 3730 ret = PTR_ERR(group->queues[i]); 3731 group->queues[i] = NULL; 3732 goto err_erase_gid; 3733 } 3734 3735 group->queue_count++; 3736 } 3737 3738 group->idle_queues = GENMASK(group->queue_count - 1, 0); 3739 3740 mutex_lock(&sched->reset.lock); 3741 if (atomic_read(&sched->reset.in_progress)) { 3742 panthor_group_stop(group); 3743 } else { 3744 mutex_lock(&sched->lock); 3745 list_add_tail(&group->run_node, 3746 &sched->groups.idle[group->priority]); 3747 mutex_unlock(&sched->lock); 3748 } 3749 mutex_unlock(&sched->reset.lock); 3750 3751 add_group_kbo_sizes(group->ptdev, group); 3752 spin_lock_init(&group->fdinfo.lock); 3753 3754 group_init_task_info(group); 3755 3756 xa_set_mark(&gpool->xa, gid, GROUP_REGISTERED); 3757 3758 return gid; 3759 3760 err_erase_gid: 3761 xa_erase(&gpool->xa, gid); 3762 3763 err_put_group: 3764 group_put(group); 3765 return ret; 3766 } 3767 3768 int panthor_group_destroy(struct panthor_file *pfile, u32 group_handle) 3769 { 3770 struct panthor_group_pool *gpool = pfile->groups; 3771 struct panthor_device *ptdev = pfile->ptdev; 3772 struct panthor_scheduler *sched = ptdev->scheduler; 3773 struct panthor_group *group = NULL; 3774 3775 /* 3776 * Check the mark and erase the entry atomically, so a concurrent 3777 * destroy + create can't make us erase a group that's still being 3778 * initialized and happens to reuse the same handle. 3779 */ 3780 xa_lock(&gpool->xa); 3781 if (xa_get_mark(&gpool->xa, group_handle, GROUP_REGISTERED)) 3782 group = __xa_erase(&gpool->xa, group_handle); 3783 xa_unlock(&gpool->xa); 3784 3785 if (!group) 3786 return -EINVAL; 3787 3788 mutex_lock(&sched->reset.lock); 3789 mutex_lock(&sched->lock); 3790 group->destroyed = true; 3791 if (group->csg_id >= 0) { 3792 sched_queue_delayed_work(sched, tick, 0); 3793 } else if (!atomic_read(&sched->reset.in_progress)) { 3794 /* Remove from the run queues, so the scheduler can't 3795 * pick the group on the next tick. 3796 */ 3797 list_del_init(&group->run_node); 3798 list_del_init(&group->wait_node); 3799 group_queue_work(group, term); 3800 } 3801 mutex_unlock(&sched->lock); 3802 mutex_unlock(&sched->reset.lock); 3803 3804 group_put(group); 3805 return 0; 3806 } 3807 3808 static struct panthor_group *group_from_handle(struct panthor_group_pool *pool, 3809 unsigned long group_handle) 3810 { 3811 struct panthor_group *group; 3812 3813 xa_lock(&pool->xa); 3814 group = group_get(xa_find(&pool->xa, &group_handle, group_handle, GROUP_REGISTERED)); 3815 xa_unlock(&pool->xa); 3816 3817 return group; 3818 } 3819 3820 int panthor_group_get_state(struct panthor_file *pfile, 3821 struct drm_panthor_group_get_state *get_state) 3822 { 3823 struct panthor_group_pool *gpool = pfile->groups; 3824 struct panthor_device *ptdev = pfile->ptdev; 3825 struct panthor_scheduler *sched = ptdev->scheduler; 3826 struct panthor_group *group; 3827 3828 if (get_state->pad) 3829 return -EINVAL; 3830 3831 group = group_from_handle(gpool, get_state->group_handle); 3832 if (!group) 3833 return -EINVAL; 3834 3835 memset(get_state, 0, sizeof(*get_state)); 3836 3837 mutex_lock(&sched->lock); 3838 if (atomic_read(&group->timedout)) 3839 get_state->state |= DRM_PANTHOR_GROUP_STATE_TIMEDOUT; 3840 3841 get_state->fatal_queues = atomic_read(&group->fatal_queues); 3842 if (get_state->fatal_queues) 3843 get_state->state |= DRM_PANTHOR_GROUP_STATE_FATAL_FAULT; 3844 3845 if (group->innocent) 3846 get_state->state |= DRM_PANTHOR_GROUP_STATE_INNOCENT; 3847 mutex_unlock(&sched->lock); 3848 3849 group_put(group); 3850 return 0; 3851 } 3852 3853 int panthor_group_pool_create(struct panthor_file *pfile) 3854 { 3855 struct panthor_group_pool *gpool; 3856 3857 gpool = kzalloc_obj(*gpool); 3858 if (!gpool) 3859 return -ENOMEM; 3860 3861 xa_init_flags(&gpool->xa, XA_FLAGS_ALLOC1); 3862 pfile->groups = gpool; 3863 return 0; 3864 } 3865 3866 void panthor_group_pool_destroy(struct panthor_file *pfile) 3867 { 3868 struct panthor_group_pool *gpool = pfile->groups; 3869 struct panthor_group *group; 3870 unsigned long i; 3871 3872 if (IS_ERR_OR_NULL(gpool)) 3873 return; 3874 3875 xa_for_each(&gpool->xa, i, group) 3876 panthor_group_destroy(pfile, i); 3877 3878 xa_destroy(&gpool->xa); 3879 kfree(gpool); 3880 pfile->groups = NULL; 3881 } 3882 3883 /** 3884 * panthor_fdinfo_gather_group_mem_info() - Retrieve aggregate size of all private kernel BO's 3885 * belonging to all the groups owned by an open Panthor file 3886 * @pfile: File. 3887 * @stats: Memory statistics to be updated. 3888 * 3889 */ 3890 void 3891 panthor_fdinfo_gather_group_mem_info(struct panthor_file *pfile, 3892 struct drm_memory_stats *stats) 3893 { 3894 struct panthor_group_pool *gpool = pfile->groups; 3895 struct panthor_group *group; 3896 unsigned long i; 3897 3898 if (IS_ERR_OR_NULL(gpool)) 3899 return; 3900 3901 xa_lock(&gpool->xa); 3902 xa_for_each_marked(&gpool->xa, i, group, GROUP_REGISTERED) { 3903 stats->resident += group->fdinfo.kbo_sizes; 3904 if (group->csg_id >= 0) 3905 stats->active += group->fdinfo.kbo_sizes; 3906 } 3907 xa_unlock(&gpool->xa); 3908 } 3909 3910 static void job_release(struct kref *ref) 3911 { 3912 struct panthor_job *job = container_of(ref, struct panthor_job, refcount); 3913 3914 drm_WARN_ON(&job->group->ptdev->base, !list_empty(&job->node)); 3915 3916 if (job->base.s_fence) 3917 drm_sched_job_cleanup(&job->base); 3918 3919 if (dma_fence_was_initialized(job->done_fence)) 3920 dma_fence_put(job->done_fence); 3921 else 3922 dma_fence_free(job->done_fence); 3923 3924 group_put(job->group); 3925 3926 kfree(job); 3927 } 3928 3929 struct drm_sched_job *panthor_job_get(struct drm_sched_job *sched_job) 3930 { 3931 if (sched_job) { 3932 struct panthor_job *job = container_of(sched_job, struct panthor_job, base); 3933 3934 kref_get(&job->refcount); 3935 } 3936 3937 return sched_job; 3938 } 3939 3940 void panthor_job_put(struct drm_sched_job *sched_job) 3941 { 3942 struct panthor_job *job = container_of(sched_job, struct panthor_job, base); 3943 3944 if (sched_job) 3945 kref_put(&job->refcount, job_release); 3946 } 3947 3948 struct panthor_vm *panthor_job_vm(struct drm_sched_job *sched_job) 3949 { 3950 struct panthor_job *job = container_of(sched_job, struct panthor_job, base); 3951 3952 return job->group->vm; 3953 } 3954 3955 struct drm_sched_job * 3956 panthor_job_create(struct panthor_file *pfile, 3957 u16 group_handle, 3958 const struct drm_panthor_queue_submit *qsubmit, 3959 u64 drm_client_id) 3960 { 3961 struct panthor_group_pool *gpool = pfile->groups; 3962 struct panthor_job *job; 3963 u32 credits; 3964 int ret; 3965 3966 if (qsubmit->pad) 3967 return ERR_PTR(-EINVAL); 3968 3969 /* If stream_addr is zero, so stream_size should be. */ 3970 if ((qsubmit->stream_size == 0) != (qsubmit->stream_addr == 0)) 3971 return ERR_PTR(-EINVAL); 3972 3973 /* Make sure the address is aligned on 64-byte (cacheline) and the size is 3974 * aligned on 8-byte (instruction size). 3975 */ 3976 if ((qsubmit->stream_addr & 63) || (qsubmit->stream_size & 7)) 3977 return ERR_PTR(-EINVAL); 3978 3979 /* bits 24:30 must be zero. */ 3980 if (qsubmit->latest_flush & GENMASK(30, 24)) 3981 return ERR_PTR(-EINVAL); 3982 3983 job = kzalloc_obj(*job); 3984 if (!job) 3985 return ERR_PTR(-ENOMEM); 3986 3987 kref_init(&job->refcount); 3988 job->queue_idx = qsubmit->queue_index; 3989 job->call_info.size = qsubmit->stream_size; 3990 job->call_info.start = qsubmit->stream_addr; 3991 job->call_info.latest_flush = qsubmit->latest_flush; 3992 INIT_LIST_HEAD(&job->node); 3993 3994 job->group = group_from_handle(gpool, group_handle); 3995 if (!job->group) { 3996 ret = -EINVAL; 3997 goto err_put_job; 3998 } 3999 4000 if (!group_can_run(job->group)) { 4001 ret = -EINVAL; 4002 goto err_put_job; 4003 } 4004 4005 if (job->queue_idx >= job->group->queue_count || 4006 !job->group->queues[job->queue_idx]) { 4007 ret = -EINVAL; 4008 goto err_put_job; 4009 } 4010 4011 /* Empty command streams don't need a fence, they'll pick the one from 4012 * the previously submitted job. 4013 */ 4014 if (job->call_info.size) { 4015 job->done_fence = kzalloc_obj(*job->done_fence); 4016 if (!job->done_fence) { 4017 ret = -ENOMEM; 4018 goto err_put_job; 4019 } 4020 } 4021 4022 job->profiling.mask = pfile->ptdev->profile_mask; 4023 credits = calc_job_credits(job->profiling.mask); 4024 if (credits == 0) { 4025 ret = -EINVAL; 4026 goto err_put_job; 4027 } 4028 4029 ret = drm_sched_job_init(&job->base, 4030 &job->group->queues[job->queue_idx]->entity, 4031 credits, job->group, drm_client_id); 4032 if (ret) 4033 goto err_put_job; 4034 4035 return &job->base; 4036 4037 err_put_job: 4038 panthor_job_put(&job->base); 4039 return ERR_PTR(ret); 4040 } 4041 4042 void panthor_job_update_resvs(struct drm_exec *exec, struct drm_sched_job *sched_job) 4043 { 4044 struct panthor_job *job = container_of(sched_job, struct panthor_job, base); 4045 4046 panthor_vm_update_resvs(job->group->vm, exec, &sched_job->s_fence->finished, 4047 DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_BOOKKEEP); 4048 } 4049 4050 void panthor_sched_unplug(struct panthor_device *ptdev) 4051 { 4052 struct panthor_scheduler *sched = ptdev->scheduler; 4053 4054 disable_delayed_work_sync(&sched->tick_work); 4055 disable_work_sync(&sched->sync_upd_work); 4056 4057 mutex_lock(&sched->lock); 4058 if (sched->pm.has_ref) { 4059 pm_runtime_put(ptdev->base.dev); 4060 sched->pm.has_ref = false; 4061 } 4062 mutex_unlock(&sched->lock); 4063 } 4064 4065 static void panthor_sched_fini(struct drm_device *ddev, void *res) 4066 { 4067 struct panthor_scheduler *sched = res; 4068 int prio; 4069 4070 if (!sched || !sched->csg_slot_count) 4071 return; 4072 4073 if (sched->wq) 4074 destroy_workqueue(sched->wq); 4075 4076 if (sched->heap_alloc_wq) 4077 destroy_workqueue(sched->heap_alloc_wq); 4078 4079 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; prio >= 0; prio--) { 4080 drm_WARN_ON(ddev, !list_empty(&sched->groups.runnable[prio])); 4081 drm_WARN_ON(ddev, !list_empty(&sched->groups.idle[prio])); 4082 } 4083 4084 drm_WARN_ON(ddev, !list_empty(&sched->groups.waiting)); 4085 } 4086 4087 int panthor_sched_init(struct panthor_device *ptdev) 4088 { 4089 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); 4090 struct panthor_fw_csg_iface *csg_iface = panthor_fw_get_csg_iface(ptdev, 0); 4091 struct panthor_fw_cs_iface *cs_iface = panthor_fw_get_cs_iface(ptdev, 0, 0); 4092 struct panthor_scheduler *sched; 4093 u32 gpu_as_count, num_groups; 4094 int prio, ret; 4095 4096 sched = drmm_kzalloc(&ptdev->base, sizeof(*sched), GFP_KERNEL); 4097 if (!sched) 4098 return -ENOMEM; 4099 4100 /* The highest bit in JOB_INT_* is reserved for globabl IRQs. That 4101 * leaves 31 bits for CSG IRQs, hence the MAX_CSGS clamp here. 4102 */ 4103 num_groups = min_t(u32, MAX_CSGS, glb_iface->control->group_num); 4104 4105 /* The FW-side scheduler might deadlock if two groups with the same 4106 * priority try to access a set of resources that overlaps, with part 4107 * of the resources being allocated to one group and the other part to 4108 * the other group, both groups waiting for the remaining resources to 4109 * be allocated. To avoid that, it is recommended to assign each CSG a 4110 * different priority. In theory we could allow several groups to have 4111 * the same CSG priority if they don't request the same resources, but 4112 * that makes the scheduling logic more complicated, so let's clamp 4113 * the number of CSG slots to MAX_CSG_PRIO + 1 for now. 4114 */ 4115 num_groups = min_t(u32, MAX_CSG_PRIO + 1, num_groups); 4116 4117 /* We need at least one AS for the MCU and one for the GPU contexts. */ 4118 gpu_as_count = hweight32(ptdev->gpu_info.as_present & GENMASK(31, 1)); 4119 if (!gpu_as_count) { 4120 drm_err(&ptdev->base, "Not enough AS (%d, expected at least 2)", 4121 gpu_as_count + 1); 4122 return -EINVAL; 4123 } 4124 4125 sched->ptdev = ptdev; 4126 sched->sb_slot_count = CS_FEATURES_SCOREBOARDS(cs_iface->control->features); 4127 sched->csg_slot_count = num_groups; 4128 sched->cs_slot_count = csg_iface->control->stream_num; 4129 sched->as_slot_count = gpu_as_count; 4130 ptdev->csif_info.csg_slot_count = sched->csg_slot_count; 4131 ptdev->csif_info.cs_slot_count = sched->cs_slot_count; 4132 ptdev->csif_info.scoreboard_slot_count = sched->sb_slot_count; 4133 4134 sched->last_tick = 0; 4135 sched->resched_target = U64_MAX; 4136 sched->tick_period = msecs_to_jiffies(10); 4137 INIT_DELAYED_WORK(&sched->tick_work, tick_work); 4138 INIT_WORK(&sched->sync_upd_work, sync_upd_work); 4139 4140 spin_lock_init(&sched->events_lock); 4141 4142 ret = drmm_mutex_init(&ptdev->base, &sched->lock); 4143 if (ret) 4144 return ret; 4145 4146 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; prio >= 0; prio--) { 4147 INIT_LIST_HEAD(&sched->groups.runnable[prio]); 4148 INIT_LIST_HEAD(&sched->groups.idle[prio]); 4149 } 4150 INIT_LIST_HEAD(&sched->groups.waiting); 4151 4152 ret = drmm_mutex_init(&ptdev->base, &sched->reset.lock); 4153 if (ret) 4154 return ret; 4155 4156 INIT_LIST_HEAD(&sched->reset.stopped_groups); 4157 4158 /* sched->heap_alloc_wq will be used for heap chunk allocation on 4159 * tiler OOM events, which means we can't use the same workqueue for 4160 * the scheduler because works queued by the scheduler are in 4161 * the dma-signalling path. Allocate a dedicated heap_alloc_wq to 4162 * work around this limitation. 4163 * 4164 * FIXME: Ultimately, what we need is a failable/non-blocking GEM 4165 * allocation path that we can call when a heap OOM is reported. The 4166 * FW is smart enough to fall back on other methods if the kernel can't 4167 * allocate memory, and fail the tiling job if none of these 4168 * countermeasures worked. 4169 * 4170 * Set WQ_MEM_RECLAIM on sched->wq to unblock the situation when the 4171 * system is running out of memory. 4172 */ 4173 sched->heap_alloc_wq = alloc_workqueue("panthor-heap-alloc", WQ_UNBOUND, 0); 4174 sched->wq = alloc_workqueue("panthor-csf-sched", WQ_MEM_RECLAIM | WQ_UNBOUND, 0); 4175 if (!sched->wq || !sched->heap_alloc_wq) { 4176 panthor_sched_fini(&ptdev->base, sched); 4177 drm_err(&ptdev->base, "Failed to allocate the workqueues"); 4178 return -ENOMEM; 4179 } 4180 4181 ret = drmm_add_action_or_reset(&ptdev->base, panthor_sched_fini, sched); 4182 if (ret) 4183 return ret; 4184 4185 ptdev->scheduler = sched; 4186 return 0; 4187 } 4188 4189 #ifdef CONFIG_DEBUG_FS 4190 4191 static const char * 4192 panthor_sched_prio_str(enum panthor_csg_priority prio) 4193 { 4194 switch (prio) { 4195 case PANTHOR_CSG_PRIORITY_LOW: 4196 return "LOW"; 4197 case PANTHOR_CSG_PRIORITY_MEDIUM: 4198 return "MEDIUM"; 4199 case PANTHOR_CSG_PRIORITY_HIGH: 4200 return "HIGH"; 4201 case PANTHOR_CSG_PRIORITY_RT: 4202 return "REAL-TIME"; 4203 default: 4204 return "UNKNOWN"; 4205 } 4206 } 4207 4208 static int show_file_groups(struct drm_file *file, struct seq_file *m) 4209 { 4210 struct panthor_file *pfile = file->driver_priv; 4211 struct panthor_group *group; 4212 unsigned long i; 4213 4214 if (IS_ERR_OR_NULL(pfile->groups)) 4215 return -ENOENT; 4216 4217 xa_lock(&pfile->groups->xa); 4218 xa_for_each_marked(&pfile->groups->xa, i, group, GROUP_REGISTERED) { 4219 seq_printf(m, "client_id %8llu pid %8d command %s: group %2lu priority %s queue count %u\n", 4220 file->client_id, group->task_info.pid, group->task_info.comm, i, 4221 panthor_sched_prio_str(group->priority), group->queue_count); 4222 } 4223 xa_unlock(&pfile->groups->xa); 4224 4225 return 0; 4226 } 4227 4228 static int show_each_file(struct seq_file *m, void *arg) 4229 { 4230 struct drm_info_node *node = (struct drm_info_node *)m->private; 4231 struct drm_device *ddev = node->minor->dev; 4232 int (*show)(struct drm_file *, struct seq_file *) = 4233 node->info_ent->data; 4234 struct drm_file *file; 4235 int ret; 4236 4237 scoped_cond_guard(mutex_intr, return -EINTR, &ddev->filelist_mutex) { 4238 list_for_each_entry(file, &ddev->filelist, lhead) { 4239 ret = show(file, m); 4240 if (ret < 0) 4241 return ret; 4242 } 4243 } 4244 4245 return 0; 4246 } 4247 4248 static struct drm_info_list panthor_sched_debugfs_list[] = { 4249 { "sched_groups", show_each_file, 0, show_file_groups }, 4250 }; 4251 4252 void panthor_sched_debugfs_init(struct drm_minor *minor) 4253 { 4254 drm_debugfs_create_files(panthor_sched_debugfs_list, 4255 ARRAY_SIZE(panthor_sched_debugfs_list), 4256 minor->debugfs_root, minor); 4257 } 4258 4259 #endif /* CONFIG_DEBUG_FS */ 4260