[PATCH 5/8] drm/amdkfd: Use PASID manager from KGD

Oded Gabbay oded.gabbay at gmail.com
Sun Sep 3 11:54:03 UTC 2017


On Wed, Aug 30, 2017 at 1:25 AM, Felix Kuehling <Felix.Kuehling at amd.com> wrote:
> Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
> ---
>  drivers/gpu/drm/amd/amdkfd/kfd_module.c |  6 ---
>  drivers/gpu/drm/amd/amdkfd/kfd_pasid.c  | 90 ++++++++++++++-------------------
>  2 files changed, 38 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
> index 0d73bea..6c5a9ca 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
> @@ -103,10 +103,6 @@ static int __init kfd_module_init(void)
>                 return -1;
>         }
>
> -       err = kfd_pasid_init();
> -       if (err < 0)
> -               return err;
> -
>         err = kfd_chardev_init();
>         if (err < 0)
>                 goto err_ioctl;
> @@ -126,7 +122,6 @@ static int __init kfd_module_init(void)
>  err_topology:
>         kfd_chardev_exit();
>  err_ioctl:
> -       kfd_pasid_exit();
>         return err;
>  }
>
> @@ -137,7 +132,6 @@ static void __exit kfd_module_exit(void)
>         kfd_process_destroy_wq();
>         kfd_topology_shutdown();
>         kfd_chardev_exit();
> -       kfd_pasid_exit();
>         dev_info(kfd_device, "Removed module\n");
>  }
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
> index 1e06de0..d6a7961 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
> @@ -20,78 +20,64 @@
>   * OTHER DEALINGS IN THE SOFTWARE.
>   */
>
> -#include <linux/slab.h>
>  #include <linux/types.h>
>  #include "kfd_priv.h"
>
> -static unsigned long *pasid_bitmap;
> -static unsigned int pasid_limit;
> -static DEFINE_MUTEX(pasid_mutex);
> -
> -int kfd_pasid_init(void)
> -{
> -       pasid_limit = KFD_MAX_NUM_OF_PROCESSES;
> -
> -       pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long),
> -                               GFP_KERNEL);
> -       if (!pasid_bitmap)
> -               return -ENOMEM;
> -
> -       set_bit(0, pasid_bitmap); /* PASID 0 is reserved. */
> -
> -       return 0;
> -}
> -
> -void kfd_pasid_exit(void)
> -{
> -       kfree(pasid_bitmap);
> -}
> +static unsigned int pasid_bits = 16;
> +static const struct kfd2kgd_calls *kfd2kgd;
>
>  bool kfd_set_pasid_limit(unsigned int new_limit)
>  {
> -       if (new_limit < pasid_limit) {
> -               bool ok;
> -
> -               mutex_lock(&pasid_mutex);
> -
> -               /* ensure that no pasids >= new_limit are in-use */
> -               ok = (find_next_bit(pasid_bitmap, pasid_limit, new_limit) ==
> -                                                               pasid_limit);
> -               if (ok)
> -                       pasid_limit = new_limit;
> -
> -               mutex_unlock(&pasid_mutex);
> -
> -               return ok;
> +       if (new_limit < 2)
> +               return false;
> +
> +       if (new_limit < (1U << pasid_bits)) {
> +               if (kfd2kgd)
> +                       /* We've already allocated user PASIDs, too late to
> +                        * change the limit
> +                        */
> +                       return false;
> +
> +               while (new_limit < (1U << pasid_bits))
> +                       pasid_bits--;
>         }
>
>         return true;
>  }
>
> -inline unsigned int kfd_get_pasid_limit(void)
> +unsigned int kfd_get_pasid_limit(void)
>  {
> -       return pasid_limit;
> +       return 1U << pasid_bits;
>  }
>
>  unsigned int kfd_pasid_alloc(void)
>  {
> -       unsigned int found;
> -
> -       mutex_lock(&pasid_mutex);
> -
> -       found = find_first_zero_bit(pasid_bitmap, pasid_limit);
> -       if (found == pasid_limit)
> -               found = 0;
> -       else
> -               set_bit(found, pasid_bitmap);
> +       int r;
> +
> +       /* Find the first best KFD device for calling KGD */
> +       if (!kfd2kgd) {
> +               struct kfd_dev *dev = NULL;
> +               unsigned int i = 0;
> +
> +               while ((dev = kfd_topology_enum_kfd_devices(i)) != NULL) {
> +                       if (dev && dev->kfd2kgd) {
> +                               kfd2kgd = dev->kfd2kgd;
> +                               break;
> +                       }
> +                       i++;
> +               }
> +
> +               if (!kfd2kgd)
> +                       return false;
> +       }

Don't you need to allocate PASID on all possible devices ?
If so, does it need to be the same on all devices ?


>
> -       mutex_unlock(&pasid_mutex);
> +       r = kfd2kgd->alloc_pasid(pasid_bits);
>
> -       return found;
> +       return r > 0 ? r : 0;
>  }
>
>  void kfd_pasid_free(unsigned int pasid)
>  {
> -       if (!WARN_ON(pasid == 0 || pasid >= pasid_limit))
> -               clear_bit(pasid, pasid_bitmap);
> +       if (kfd2kgd)
> +               kfd2kgd->free_pasid(pasid);
>  }
> --
> 2.7.4
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list