From: Zhu Lingshan Date: Mon, 21 Apr 2025 07:47:54 +0000 (+0800) Subject: amdkfd: mark the first kfd_process as the primary one X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3272cd887f2bc27825a6c053ca174dbb6eabc636;p=thirdparty%2Fkernel%2Flinux.git amdkfd: mark the first kfd_process as the primary one The first kfd_process is created through open(), this commit marks it as the primary kfd_process by assigning a primary id for its context_id. Only the primary process should register the mmu_notifier. Signed-off-by: Zhu Lingshan Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index ced5a84c4328..c29e085dcef7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -1017,9 +1017,14 @@ struct kfd_process { /* if gpu page fault sent to KFD */ bool gpu_page_fault; + + /*kfd context id */ + u16 context_id; }; #define KFD_PROCESS_TABLE_SIZE 8 /* bits: 256 entries */ +#define KFD_CONTEXT_ID_PRIMARY 0xFFFF + extern DECLARE_HASHTABLE(kfd_processes_table, KFD_PROCESS_TABLE_SIZE); extern struct srcu_struct kfd_processes_srcu; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index a085faac9fe1..307cf4ccc2a3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -68,7 +68,7 @@ static struct workqueue_struct *kfd_restore_wq; static struct kfd_process *find_process(const struct task_struct *thread, bool ref); static void kfd_process_ref_release(struct kref *ref); -static struct kfd_process *create_process(const struct task_struct *thread); +static struct kfd_process *create_process(const struct task_struct *thread, bool primary); static void evict_process_worker(struct work_struct *work); static void restore_process_worker(struct work_struct *work); @@ -867,7 +867,7 @@ struct kfd_process *kfd_create_process(struct task_struct *thread) if (process) { pr_debug("Process already found\n"); } else { - process = create_process(thread); + process = create_process(thread, true); if (IS_ERR(process)) goto out; @@ -1516,7 +1516,7 @@ void kfd_process_set_trap_debug_flag(struct qcm_process_device *qpd, * On return the kfd_process is fully operational and will be freed when the * mm is released */ -static struct kfd_process *create_process(const struct task_struct *thread) +static struct kfd_process *create_process(const struct task_struct *thread, bool primary) { struct kfd_process *process; struct mmu_notifier *mn; @@ -1532,6 +1532,7 @@ static struct kfd_process *create_process(const struct task_struct *thread) process->lead_thread = thread->group_leader; process->n_pdds = 0; process->queues_paused = false; + INIT_DELAYED_WORK(&process->eviction_work, evict_process_worker); INIT_DELAYED_WORK(&process->restore_work, restore_process_worker); process->last_restore_timestamp = get_jiffies_64(); @@ -1575,12 +1576,15 @@ static struct kfd_process *create_process(const struct task_struct *thread) * After this point, mmu_notifier_put will trigger the cleanup by * dropping the last process reference in the free_notifier. */ - mn = mmu_notifier_get(&kfd_process_mmu_notifier_ops, process->mm); - if (IS_ERR(mn)) { - err = PTR_ERR(mn); - goto err_register_notifier; + if (primary) { + process->context_id = KFD_CONTEXT_ID_PRIMARY; + mn = mmu_notifier_get(&kfd_process_mmu_notifier_ops, process->mm); + if (IS_ERR(mn)) { + err = PTR_ERR(mn); + goto err_register_notifier; + } + BUG_ON(mn != &process->mmu_notifier); } - BUG_ON(mn != &process->mmu_notifier); kfd_unref_process(process); get_task_struct(process->lead_thread);