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

Merge branch 'drm-fixes-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

- Fix an ordering issue in DC with respect to atomic flips that could result
in a crash
- Fix incorrect use of process->mm in KFD

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1538668374-22334-1-git-send-email-alexander.deucher@amd.com

+37 -10
+29 -8
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
··· 358 358 struct queue *q, 359 359 struct qcm_process_device *qpd) 360 360 { 361 - int retval; 362 361 struct mqd_manager *mqd_mgr; 362 + int retval; 363 363 364 364 mqd_mgr = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE); 365 365 if (!mqd_mgr) ··· 387 387 if (!q->properties.is_active) 388 388 return 0; 389 389 390 - retval = mqd_mgr->load_mqd(mqd_mgr, q->mqd, q->pipe, q->queue, 391 - &q->properties, q->process->mm); 390 + if (WARN(q->process->mm != current->mm, 391 + "should only run in user thread")) 392 + retval = -EFAULT; 393 + else 394 + retval = mqd_mgr->load_mqd(mqd_mgr, q->mqd, q->pipe, q->queue, 395 + &q->properties, current->mm); 392 396 if (retval) 393 397 goto out_uninit_mqd; 394 398 ··· 549 545 retval = map_queues_cpsch(dqm); 550 546 else if (q->properties.is_active && 551 547 (q->properties.type == KFD_QUEUE_TYPE_COMPUTE || 552 - q->properties.type == KFD_QUEUE_TYPE_SDMA)) 553 - retval = mqd_mgr->load_mqd(mqd_mgr, q->mqd, q->pipe, q->queue, 554 - &q->properties, q->process->mm); 548 + q->properties.type == KFD_QUEUE_TYPE_SDMA)) { 549 + if (WARN(q->process->mm != current->mm, 550 + "should only run in user thread")) 551 + retval = -EFAULT; 552 + else 553 + retval = mqd_mgr->load_mqd(mqd_mgr, q->mqd, 554 + q->pipe, q->queue, 555 + &q->properties, current->mm); 556 + } 555 557 556 558 out_unlock: 557 559 dqm_unlock(dqm); ··· 663 653 static int restore_process_queues_nocpsch(struct device_queue_manager *dqm, 664 654 struct qcm_process_device *qpd) 665 655 { 656 + struct mm_struct *mm = NULL; 666 657 struct queue *q; 667 658 struct mqd_manager *mqd_mgr; 668 659 struct kfd_process_device *pdd; ··· 697 686 kfd_flush_tlb(pdd); 698 687 } 699 688 689 + /* Take a safe reference to the mm_struct, which may otherwise 690 + * disappear even while the kfd_process is still referenced. 691 + */ 692 + mm = get_task_mm(pdd->process->lead_thread); 693 + if (!mm) { 694 + retval = -EFAULT; 695 + goto out; 696 + } 697 + 700 698 /* activate all active queues on the qpd */ 701 699 list_for_each_entry(q, &qpd->queues_list, list) { 702 700 if (!q->properties.is_evicted) ··· 720 700 q->properties.is_evicted = false; 721 701 q->properties.is_active = true; 722 702 retval = mqd_mgr->load_mqd(mqd_mgr, q->mqd, q->pipe, 723 - q->queue, &q->properties, 724 - q->process->mm); 703 + q->queue, &q->properties, mm); 725 704 if (retval) 726 705 goto out; 727 706 dqm->queue_count++; 728 707 } 729 708 qpd->evicted = 0; 730 709 out: 710 + if (mm) 711 + mmput(mm); 731 712 dqm_unlock(dqm); 732 713 return retval; 733 714 }
+8 -2
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 4633 4633 } 4634 4634 spin_unlock_irqrestore(&adev->ddev->event_lock, flags); 4635 4635 4636 - /* Signal HW programming completion */ 4637 - drm_atomic_helper_commit_hw_done(state); 4638 4636 4639 4637 if (wait_for_vblank) 4640 4638 drm_atomic_helper_wait_for_flip_done(dev, state); 4639 + 4640 + /* 4641 + * FIXME: 4642 + * Delay hw_done() until flip_done() is signaled. This is to block 4643 + * another commit from freeing the CRTC state while we're still 4644 + * waiting on flip_done. 4645 + */ 4646 + drm_atomic_helper_commit_hw_done(state); 4641 4647 4642 4648 drm_atomic_helper_cleanup_planes(dev, state); 4643 4649