On 2025-08-04 7:05, Zhu Lingshan wrote: > This commit introduces a new id field for > struct kfd process, which helps identify > a kfd process among multiple contexts that > all belong to a single user space program. > > The sysfs entry of a secondary kfd process > is placed under the sysfs entry folder of > its primary kfd process. > > The naming format of the sysfs entry of a secondary > kfd process is "context_%u" where %u is the process id. > > Signed-off-by: Zhu Lingshan <lingshan....@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehl...@amd.com> > --- > drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 6 ++ > drivers/gpu/drm/amd/amdkfd/kfd_process.c | 83 +++++++++++++++++++++++- > 2 files changed, 86 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h > b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h > index d1436f1f527d..d140463e221b 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h > @@ -998,6 +998,9 @@ struct kfd_process { > /* Tracks debug per-vmid request for debug flags */ > u32 dbg_flags; > > + /* kfd process id */ > + u16 id; > + > atomic_t poison; > /* Queues are in paused stated because we are in the process of doing a > CRIU checkpoint */ > bool queues_paused; > @@ -1012,6 +1015,9 @@ struct kfd_process { > > /* indicating whether this is a primary kfd_process */ > bool primary; > + > + /* The primary kfd_process allocating IDs for its secondary > kfd_process, 0 for primary kfd_process */ > + struct ida id_table; > }; > > #define KFD_PROCESS_TABLE_SIZE 8 /* bits: 256 entries */ > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c > b/drivers/gpu/drm/amd/amdkfd/kfd_process.c > index 5d59a4d994d5..8e498fd35b8c 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c > @@ -54,6 +54,9 @@ DEFINE_MUTEX(kfd_processes_mutex); > > DEFINE_SRCU(kfd_processes_srcu); > > +#define KFD_PROCESS_ID_MIN 1 > +#define KFD_PROCESS_ID_WIDTH 16 > + > /* For process termination handling */ > static struct workqueue_struct *kfd_process_wq; > > @@ -827,6 +830,7 @@ static void kfd_process_device_destroy_ib_mem(struct > kfd_process_device *pdd) > > int kfd_create_process_sysfs(struct kfd_process *process) > { > + struct kfd_process *primary_process; > int ret; > > if (process->kobj) { > @@ -839,9 +843,22 @@ int kfd_create_process_sysfs(struct kfd_process *process) > pr_warn("Creating procfs kobject failed"); > return -ENOMEM; > } > - ret = kobject_init_and_add(process->kobj, &procfs_type, > - procfs.kobj, "%d", > - (int)process->lead_thread->pid); > + > + if (process->primary) > + ret = kobject_init_and_add(process->kobj, &procfs_type, > + procfs.kobj, "%d", > + (int)process->lead_thread->pid); > + else { > + primary_process = > kfd_lookup_process_by_mm(process->lead_thread->mm); > + if (!primary_process) > + return -ESRCH; > + > + ret = kobject_init_and_add(process->kobj, &procfs_type, > + primary_process->kobj, "context_%u", > + process->id); > + kfd_unref_process(primary_process); > + } > + > if (ret) { > pr_warn("Creating procfs pid directory failed"); > kobject_put(process->kobj); > @@ -863,6 +880,51 @@ int kfd_create_process_sysfs(struct kfd_process *process) > return 0; > } > > +static int kfd_process_alloc_id(struct kfd_process *process) > +{ > + int ret; > + struct kfd_process *primary_process; > + > + if (process->primary) { > + process->id = 0; > + > + return 0; > + } > + > + primary_process = kfd_lookup_process_by_mm(process->lead_thread->mm); > + if (!primary_process) > + return -ESRCH; > + > + ret = ida_alloc_range(&primary_process->id_table, KFD_PROCESS_ID_MIN, > + (1 << KFD_PROCESS_ID_WIDTH) - 1, GFP_KERNEL); > + if (ret < 0) > + goto out; > + > + process->id = ret; > + ret = 0; > + > +out: > + kfd_unref_process(primary_process); > + > + return ret; > +} > + > +static void kfd_process_free_id(struct kfd_process *process) > +{ > + struct kfd_process *primary_process; > + > + if (process->primary) > + return; > + > + primary_process = kfd_lookup_process_by_mm(process->lead_thread->mm); > + if (!primary_process) > + return; > + > + ida_free(&primary_process->id_table, process->id); > + > + kfd_unref_process(primary_process); > +} > + > struct kfd_process *kfd_create_process(struct task_struct *thread) > { > struct kfd_process *process; > @@ -1193,6 +1255,11 @@ static void kfd_process_wq_release(struct work_struct > *work) > if (ef) > dma_fence_signal(ef); > > + if (!p->primary) > + kfd_process_free_id(p); > + else > + ida_destroy(&p->id_table); > + > kfd_process_remove_sysfs(p); > kfd_debugfs_remove_process(p); > > @@ -1549,6 +1616,12 @@ static struct kfd_process *create_process(const struct > task_struct *thread, bool > process->queues_paused = false; > process->primary = primary; > > + err = kfd_process_alloc_id(process); > + if (err) { > + pr_err("Creating kfd process: failed to alloc an id\n"); > + goto err_alloc_id; > + } > + > 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(); > @@ -1599,6 +1672,8 @@ static struct kfd_process *create_process(const struct > task_struct *thread, bool > goto err_register_notifier; > } > BUG_ON(mn != &process->mmu_notifier); > + > + ida_init(&process->id_table); > } > > kfd_unref_process(process); > @@ -1619,6 +1694,8 @@ static struct kfd_process *create_process(const struct > task_struct *thread, bool > err_process_pqm_init: > kfd_event_free_process(process); > err_event_init: > + kfd_process_free_id(process); > +err_alloc_id: > mutex_destroy(&process->mutex); > kfree(process); > err_alloc_process: