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