<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <pre>On 7/29/2025 3:59 AM, Felix Kuehling wrote:</pre>
    <blockquote type="cite" cite="mid:88f528e6-ab31-4864-8bda-60889a186059@amd.com">On
      2025-07-24 22:43, Zhu Lingshan wrote:
      <br>
      <blockquote type="cite">This commit implemetns a new ioctl
        AMDKFD_IOC_CREATE_PROCESS
        <br>
        that creates a new secondary kfd_progress on the FD.
        <br>
      </blockquote>
      <br>
      To add a new ioctl upstream, do you have a link to the
      corresponding user mode changes? <br>
    </blockquote>
    <pre>I have tested the code locally and we are developing kfdtest for multiple contexts.
This new ioctl will not break any current use cases.

I will post my local test program for this ioctl in the cover letter.

Thanks
Lingshan</pre>
    <blockquote type="cite" cite="mid:88f528e6-ab31-4864-8bda-60889a186059@amd.com"><br>
      Other than that, this patch looks good to me.
      <br>
      <br>
      Regards,
      <br>
        Felix
      <br>
      <br>
      <br>
      <blockquote type="cite">
        <br>
        To keep backward compatibility, userspace programs need to
        invoke
        <br>
        this ioctl explicitly on a FD to create a secondary
        <br>
        kfd_process which replacing its primary kfd_process.
        <br>
        <br>
        This commit bumps ioctl minor version.
        <br>
        <br>
        Signed-off-by: Zhu Lingshan <a class="moz-txt-link-rfc2396E" href="mailto:lingshan.zhu@amd.com"><lingshan.zhu@amd.com></a>
        <br>
        ---
        <br>
          drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 41
        ++++++++++++++++++++++++
        <br>
          drivers/gpu/drm/amd/amdkfd/kfd_priv.h    |  1 +
        <br>
          drivers/gpu/drm/amd/amdkfd/kfd_process.c |  3 +-
        <br>
          include/uapi/linux/kfd_ioctl.h           |  8 +++--
        <br>
          4 files changed, 49 insertions(+), 4 deletions(-)
        <br>
        <br>
        diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
        b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
        <br>
        index 5b22e1c47b2e..f9c43ff8a89f 100644
        <br>
        --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
        <br>
        +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
        <br>
        @@ -3136,6 +3136,44 @@ static int
        kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process
        *p, v
        <br>
              return r;
        <br>
          }
        <br>
          +/* userspace programs need to invoke this ioctl explicitly on
        a FD to
        <br>
        + * create a secondary kfd_process which replacing its primary
        kfd_process
        <br>
        + */
        <br>
        +static int kfd_ioctl_create_process(struct file *filep, struct
        kfd_process *p, void *data)
        <br>
        +{
        <br>
        +    struct kfd_process *process;
        <br>
        +    int ret;
        <br>
        +
        <br>
        +    if (!filep->private_data || !p)
        <br>
        +        return -EINVAL;
        <br>
        +
        <br>
        +    if (p != filep->private_data)
        <br>
        +        return -EINVAL;
        <br>
        +
        <br>
        +    /* Each FD owns only one kfd_process */
        <br>
        +    if (!p->primary)
        <br>
        +        return -EINVAL;
        <br>
        +
        <br>
        +    mutex_lock(&kfd_processes_mutex);
        <br>
        +    process = create_process(current, false);
        <br>
        +    mutex_unlock(&kfd_processes_mutex);
        <br>
        +
        <br>
        +    if (IS_ERR(process))
        <br>
        +        return PTR_ERR(process);
        <br>
        +
        <br>
        +    /* Each open() increases kref of the primary kfd_process,
        <br>
        +     * so we need to reduce it here before we create a new
        secondary process replacing it
        <br>
        +     */
        <br>
        +    kfd_unref_process(p);
        <br>
        +
        <br>
        +    filep->private_data = process;
        <br>
        +    ret = kfd_create_process_sysfs(process);
        <br>
        +    if (ret)
        <br>
        +        pr_warn("Failed to create sysfs entry for the
        kfd_process");
        <br>
        +
        <br>
        +    return 0;
        <br>
        +}
        <br>
        +
        <br>
          #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
        <br>
              [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags =
        _flags, \
        <br>
                          .cmd_drv = 0, .name = #ioctl}
        <br>
        @@ -3254,6 +3292,9 @@ static const struct amdkfd_ioctl_desc
        amdkfd_ioctls[] = {
        <br>
                AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_TRAP,
        <br>
                      kfd_ioctl_set_debug_trap, 0),
        <br>
        +
        <br>
        +    AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_PROCESS,
        <br>
        +            kfd_ioctl_create_process, 0),
        <br>
          };
        <br>
            #define AMDKFD_CORE_IOCTL_COUNT    ARRAY_SIZE(amdkfd_ioctls)
        <br>
        diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
        b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
        <br>
        index a6e12c705734..a2b5081fbfc0 100644
        <br>
        --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
        <br>
        +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
        <br>
        @@ -1051,6 +1051,7 @@ struct kfd_process *kfd_get_process(const
        struct task_struct *task);
        <br>
          struct kfd_process *kfd_lookup_process_by_pasid(u32 pasid,
        <br>
                                   struct kfd_process_device **pdd);
        <br>
          struct kfd_process *kfd_lookup_process_by_mm(const struct
        mm_struct *mm);
        <br>
        +struct kfd_process *create_process(const struct task_struct
        *thread, bool primary);
        <br>
            int kfd_process_gpuidx_from_gpuid(struct kfd_process *p,
        uint32_t gpu_id);
        <br>
          int kfd_process_gpuid_from_node(struct kfd_process *p, struct
        kfd_node *node,
        <br>
        diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
        b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
        <br>
        index e1ba9015bb83..15a8de2275f4 100644
        <br>
        --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
        <br>
        +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
        <br>
        @@ -71,7 +71,6 @@ static struct workqueue_struct
        *kfd_restore_wq;
        <br>
          static struct kfd_process *find_process(const struct
        task_struct *thread,
        <br>
                              bool ref);
        <br>
          static void kfd_process_ref_release(struct kref *ref);
        <br>
        -static struct kfd_process *create_process(const struct
        task_struct *thread, bool primary);
        <br>
            static void evict_process_worker(struct work_struct *work);
        <br>
          static void restore_process_worker(struct work_struct *work);
        <br>
        @@ -1598,7 +1597,7 @@ void
        kfd_process_set_trap_debug_flag(struct qcm_process_device *qpd,
        <br>
           * On return the kfd_process is fully operational and will be
        freed when the
        <br>
           * mm is released
        <br>
           */
        <br>
        -static struct kfd_process *create_process(const struct
        task_struct *thread, bool primary)
        <br>
        +struct kfd_process *create_process(const struct task_struct
        *thread, bool primary)
        <br>
          {
        <br>
              struct kfd_process *process;
        <br>
              struct mmu_notifier *mn;
        <br>
        diff --git a/include/uapi/linux/kfd_ioctl.h
        b/include/uapi/linux/kfd_ioctl.h
        <br>
        index 04c7d283dc7d..1d206ecc831e 100644
        <br>
        --- a/include/uapi/linux/kfd_ioctl.h
        <br>
        +++ b/include/uapi/linux/kfd_ioctl.h
        <br>
        @@ -44,9 +44,10 @@
        <br>
           * - 1.16 - Add contiguous VRAM allocation flag
        <br>
           * - 1.17 - Add SDMA queue creation with target SDMA engine ID
        <br>
           * - 1.18 - Rename pad in set_memory_policy_args to
        misc_process_flag
        <br>
        + * - 1.19 - Add a new ioctl to craete secondary kfd processes
        <br>
           */
        <br>
          #define KFD_IOCTL_MAJOR_VERSION 1
        <br>
        -#define KFD_IOCTL_MINOR_VERSION 18
        <br>
        +#define KFD_IOCTL_MINOR_VERSION 19
        <br>
            struct kfd_ioctl_get_version_args {
        <br>
              __u32 major_version;    /* from KFD */
        <br>
        @@ -1671,7 +1672,10 @@ struct kfd_ioctl_dbg_trap_args {
        <br>
          #define AMDKFD_IOC_DBG_TRAP            \
        <br>
                  AMDKFD_IOWR(0x26, struct kfd_ioctl_dbg_trap_args)
        <br>
          +#define AMDKFD_IOC_CREATE_PROCESS        \
        <br>
        +        AMDKFD_IO(0x27)
        <br>
        +
        <br>
          #define AMDKFD_COMMAND_START        0x01
        <br>
        -#define AMDKFD_COMMAND_END        0x27
        <br>
        +#define AMDKFD_COMMAND_END        0x28
        <br>
            #endif
        <br>
      </blockquote>
    </blockquote>
  </body>
</html>