On 2025-10-22 03:30, Zhu Lingshan wrote:
This commit implemetns a new ioctl AMDKFD_IOC_CREATE_PROCESS
that creates a new secondary kfd_progress on the FD.

To keep backward compatibility, userspace programs need to invoke
this ioctl explicitly on a FD to create a secondary
kfd_process which replacing its primary kfd_process.

This commit bumps ioctl minor version.

Signed-off-by: Zhu Lingshan <[email protected]>
---
  drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 46 ++++++++++++++++++++++++
  drivers/gpu/drm/amd/amdkfd/kfd_priv.h    |  1 +
  drivers/gpu/drm/amd/amdkfd/kfd_process.c |  3 +-
  include/uapi/linux/kfd_ioctl.h           |  8 +++--
  4 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index ad5ca3fd847c..04862fa820f9 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -3146,6 +3146,49 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, 
struct kfd_process *p, v
        return r;
  }
+/* userspace programs need to invoke this ioctl explicitly on a FD to
+ * create a secondary kfd_process which replacing its primary kfd_process
+ */
+static int kfd_ioctl_create_process(struct file *filep, struct kfd_process *p, 
void *data)
+{
+       struct kfd_process *process;
+       int ret;
+
+       if (!filep->private_data || !p)
+               return -EINVAL;
+
+       mutex_lock(&kfd_processes_mutex);
+       if (p != filep->private_data) {
+               mutex_unlock(&kfd_processes_mutex);
+               return -EINVAL;
+       }
+
+       /* Each FD owns only one kfd_process */
+       if (p->context_id != KFD_CONTEXT_ID_PRIMARY) {

This check can be done before taking the lock because we never change the context_id of a process after creating it.


+               mutex_unlock(&kfd_processes_mutex);
+               return -EINVAL;
+       }
+
+       process = create_process(current, false);
+       if (IS_ERR(process)) {
+               mutex_unlock(&kfd_processes_mutex);
+               return PTR_ERR(process);
+       }
+
+       filep->private_data = process;
+       ret = kfd_create_process_sysfs(process);

The kfd_create_process_sysfs call can be outside the lock. With these to changes, the patch is good to go.

Still no Reviewed-by for the uAPI change because we don't have the user mode changes in a publicly visible place.

Regards,
  Felix


+       if (ret)
+               pr_warn("Failed to create sysfs entry for the kfd_process");
+       mutex_unlock(&kfd_processes_mutex);
+
+       /* Each open() increases kref of the primary kfd_process,
+        * so we need to reduce it here when we create a new secondary process 
replacing it
+        */
+       kfd_unref_process(p);
+
+       return 0;
+}
+
  #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
        [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
                            .cmd_drv = 0, .name = #ioctl}
@@ -3264,6 +3307,9 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_TRAP,
                        kfd_ioctl_set_debug_trap, 0),
+
+       AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_PROCESS,
+                       kfd_ioctl_create_process, 0),
  };
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 44ecdaf02657..02def4f830b2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1054,6 +1054,7 @@ struct amdkfd_ioctl_desc {
  };
  bool kfd_dev_is_large_bar(struct kfd_node *dev);
+struct kfd_process *create_process(const struct task_struct *thread, bool primary);
  int kfd_process_create_wq(void);
  void kfd_process_destroy_wq(void);
  void kfd_cleanup_processes(void);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 4350552e9648..236015993902 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -68,7 +68,6 @@ 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, 
bool primary);
static void evict_process_worker(struct work_struct *work);
  static void restore_process_worker(struct work_struct *work);
@@ -1578,7 +1577,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, 
bool primary)
+struct kfd_process *create_process(const struct task_struct *thread, bool 
primary)
  {
        struct kfd_process *process;
        struct mmu_notifier *mn;
diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h
index 5d1727a6d040..84aa24c02715 100644
--- a/include/uapi/linux/kfd_ioctl.h
+++ b/include/uapi/linux/kfd_ioctl.h
@@ -44,9 +44,10 @@
   * - 1.16 - Add contiguous VRAM allocation flag
   * - 1.17 - Add SDMA queue creation with target SDMA engine ID
   * - 1.18 - Rename pad in set_memory_policy_args to misc_process_flag
+ * - 1.19 - Add a new ioctl to craete secondary kfd processes
   */
  #define KFD_IOCTL_MAJOR_VERSION 1
-#define KFD_IOCTL_MINOR_VERSION 18
+#define KFD_IOCTL_MINOR_VERSION 19
struct kfd_ioctl_get_version_args {
        __u32 major_version;    /* from KFD */
@@ -1671,7 +1672,10 @@ struct kfd_ioctl_dbg_trap_args {
  #define AMDKFD_IOC_DBG_TRAP                   \
                AMDKFD_IOWR(0x26, struct kfd_ioctl_dbg_trap_args)
+#define AMDKFD_IOC_CREATE_PROCESS \
+               AMDKFD_IO(0x27)
+
  #define AMDKFD_COMMAND_START          0x01
-#define AMDKFD_COMMAND_END             0x27
+#define AMDKFD_COMMAND_END             0x28
#endif

Reply via email to