On 6/30/26 15:43, Srinivasan Shanmugam wrote:
> AMDGPU already has a global PASID xarray used by the PASID allocator.
> 
> Currently allocated PASIDs store a dummy value in that xarray.
> 
> Add helper functions so DRM-owned PASIDs can store and retrieve their
> owning DRM file-private object.
> 
> This prepares for using:
> 
>       PASID -> fpriv -> vm
> 
> instead of the separate per-device:
> 
>       PASID -> vm
> 
> mapping.
> 
> Cc: Alex Deucher <[email protected]>
> Suggested-by: Christian König <[email protected]>
> Signed-off-by: Srinivasan Shanmugam <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 91 +++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h | 13 ++++
>  2 files changed, 104 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
> index 684f40fce73f..f65d57b4cc04 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
> @@ -78,6 +78,97 @@ int amdgpu_pasid_alloc(unsigned int bits)
>       return pasid;
>  }
>  
> +int amdgpu_pasid_set_fpriv(u32 pasid,
> +                        struct amdgpu_fpriv *fpriv)

What exactly is the reason that this isn't part of the amdgpu_pasid_alloc() 
function?

Regards,
Christian.

> +{
> +     unsigned long flags;
> +     void *entry;
> +     int r = 0;
> +
> +     if (!pasid || !fpriv)
> +             return -EINVAL;
> +
> +     xa_lock_irqsave(&amdgpu_pasid_xa, flags);
> +
> +     entry = xa_load(&amdgpu_pasid_xa, pasid);
> +
> +     if (!entry) {
> +             r = -ENOENT;
> +             goto unlock;
> +     }
> +
> +     if (!xa_is_value(entry)) {
> +             r = -EBUSY;
> +             goto unlock;
> +     }
> +
> +     entry = __xa_store(&amdgpu_pasid_xa, pasid,
> +                        fpriv, GFP_ATOMIC);
> +     r = xa_err(entry);
> +
> +unlock:
> +     xa_unlock_irqrestore(&amdgpu_pasid_xa, flags);
> +
> +     return r;
> +}
> +
> +void amdgpu_pasid_clear_fpriv(u32 pasid,
> +                           struct amdgpu_fpriv *fpriv)
> +{
> +     unsigned long flags;
> +     void *entry;
> +
> +     if (!pasid || !fpriv)
> +             return;
> +
> +     xa_lock_irqsave(&amdgpu_pasid_xa, flags);
> +
> +     entry = xa_load(&amdgpu_pasid_xa, pasid);
> +
> +     if (entry == fpriv)
> +             __xa_store(&amdgpu_pasid_xa,
> +                        pasid,
> +                        xa_mk_value(0),
> +                        GFP_ATOMIC);
> +
> +     xa_unlock_irqrestore(&amdgpu_pasid_xa, flags);
> +}
> +
> +void amdgpu_pasid_lock(unsigned long *flags)
> +{
> +     xa_lock_irqsave(&amdgpu_pasid_xa, *flags);
> +}
> +
> +void amdgpu_pasid_unlock(unsigned long flags)
> +{
> +     xa_unlock_irqrestore(&amdgpu_pasid_xa, flags);
> +}
> +
> +/**
> + * amdgpu_pasid_get_fpriv_locked - get fpriv from PASID
> + * @pasid: PASID to resolve
> + *
> + * Caller must hold the PASID XA lock.
> + *
> + * The returned pointer is only protected by the PASID XA lock.
> + * Callers must not continue using it after dropping the lock
> + * unless additional lifetime protection exists.
> + *
> + * This intentionally does not add kref/RCU lifetime handling.
> + */
> +     struct amdgpu_fpriv *
> +amdgpu_pasid_get_fpriv_locked(u32 pasid)
> +{
> +     void *entry;
> +
> +     entry = xa_load(&amdgpu_pasid_xa, pasid);
> +
> +     if (!entry || xa_is_value(entry))
> +             return NULL;
> +
> +     return entry;
> +}
> +
>  /**
>   * amdgpu_pasid_free - Free a PASID
>   * @pasid: PASID to free
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
> index a57919478d3b..220a0ba0cfb6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
> @@ -38,6 +38,7 @@ struct amdgpu_vm;
>  struct amdgpu_ring;
>  struct amdgpu_sync;
>  struct amdgpu_job;
> +struct amdgpu_fpriv;
>  
>  struct amdgpu_vmid {
>       struct list_head        list;
> @@ -92,4 +93,16 @@ void amdgpu_vmid_reset_all(struct amdgpu_device *adev);
>  void amdgpu_vmid_mgr_init(struct amdgpu_device *adev);
>  void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev);
>  
> +int amdgpu_pasid_set_fpriv(u32 pasid,
> +                        struct amdgpu_fpriv *fpriv);
> +
> +void amdgpu_pasid_clear_fpriv(u32 pasid,
> +                           struct amdgpu_fpriv *fpriv);
> +
> +void amdgpu_pasid_lock(unsigned long *flags);
> +void amdgpu_pasid_unlock(unsigned long flags);
> +
> +struct amdgpu_fpriv *
> +amdgpu_pasid_get_fpriv_locked(u32 pasid);
> +
>  #endif

Reply via email to