All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/amdkfd: Ensure gpu_id is unique
@ 2024-05-03 22:06 Harish Kasiviswanathan
  2024-05-06 20:30 ` Felix Kuehling
  2024-05-07  5:52 ` Lazar, Lijo
  0 siblings, 2 replies; 8+ messages in thread
From: Harish Kasiviswanathan @ 2024-05-03 22:06 UTC (permalink / raw)
  To: amd-gfx; +Cc: Harish Kasiviswanathan

gpu_id needs to be unique for user space to identify GPUs via KFD
interface. In the current implementation there is a very small
probability of having non unique gpu_ids.

v2: Add check to confirm if gpu_id is unique. If not unique, find one
    Changed commit header to reflect the above

Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 26 ++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index b93913934b03..01d4c2e10c6d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -1095,6 +1095,8 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
 	uint32_t hashout;
 	uint32_t buf[8];
 	uint64_t local_mem_size;
+	struct kfd_topology_device *dev;
+	bool is_unique;
 	int i;
 
 	if (!gpu)
@@ -1115,6 +1117,28 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
 	for (i = 0, hashout = 0; i < 8; i++)
 		hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
 
+	/* hash generated could be non-unique. Check if it is unique.
+	 * If not unique increment till unique one is found. In case
+	 * of overflow, restart from 1
+	*/
+	down_read(&topology_lock);
+	do {
+		is_unique = true;
+		list_for_each_entry(dev, &topology_device_list, list) {
+			if (dev->gpu && dev->gpu_id == hashout) {
+				is_unique = false;
+				break;
+			}
+		}
+		if (unlikely(!is_unique)) {
+			hashout = (hashout + 1) &
+				  ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
+			if (!hashout)
+				hashout = 1;
+		}
+	} while (!is_unique);
+	up_read(&topology_lock);
+
 	return hashout;
 }
 /* kfd_assign_gpu - Attach @gpu to the correct kfd topology device. If
@@ -1946,7 +1970,6 @@ int kfd_topology_add_device(struct kfd_node *gpu)
 	struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config;
 	struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info;
 
-	gpu_id = kfd_generate_gpu_id(gpu);
 	if (gpu->xcp && !gpu->xcp->ddev) {
 		dev_warn(gpu->adev->dev,
 			 "Won't add GPU to topology since it has no drm node assigned.");
@@ -1969,6 +1992,7 @@ int kfd_topology_add_device(struct kfd_node *gpu)
 	if (res)
 		return res;
 
+	gpu_id = kfd_generate_gpu_id(gpu);
 	dev->gpu_id = gpu_id;
 	gpu->id = gpu_id;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/amdkfd: Ensure gpu_id is unique
  2024-05-03 22:06 [PATCH] drm/amdkfd: Ensure gpu_id is unique Harish Kasiviswanathan
@ 2024-05-06 20:30 ` Felix Kuehling
  2024-05-06 21:10   ` Harish Kasiviswanathan
  2024-05-07  5:52 ` Lazar, Lijo
  1 sibling, 1 reply; 8+ messages in thread
From: Felix Kuehling @ 2024-05-06 20:30 UTC (permalink / raw)
  To: Harish Kasiviswanathan, amd-gfx


On 2024-05-03 18:06, Harish Kasiviswanathan wrote:
> gpu_id needs to be unique for user space to identify GPUs via KFD
> interface. In the current implementation there is a very small
> probability of having non unique gpu_ids.
>
> v2: Add check to confirm if gpu_id is unique. If not unique, find one
>      Changed commit header to reflect the above
>
> Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
> ---
>   drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 26 ++++++++++++++++++++++-
>   1 file changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> index b93913934b03..01d4c2e10c6d 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> @@ -1095,6 +1095,8 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>   	uint32_t hashout;
>   	uint32_t buf[8];
>   	uint64_t local_mem_size;
> +	struct kfd_topology_device *dev;
> +	bool is_unique;
>   	int i;
>   
>   	if (!gpu)
> @@ -1115,6 +1117,28 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>   	for (i = 0, hashout = 0; i < 8; i++)
>   		hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
>   
> +	/* hash generated could be non-unique. Check if it is unique.
> +	 * If not unique increment till unique one is found. In case
> +	 * of overflow, restart from 1
> +	*/
> +	down_read(&topology_lock);
> +	do {
> +		is_unique = true;
> +		list_for_each_entry(dev, &topology_device_list, list) {
> +			if (dev->gpu && dev->gpu_id == hashout) {
> +				is_unique = false;
> +				break;
> +			}
> +		}
> +		if (unlikely(!is_unique)) {
> +			hashout = (hashout + 1) &
> +				  ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
> +			if (!hashout)
> +				hashout = 1;

This doesn't catch the case that hashout was 0 before incrementing it, 
and was found to be unique.

Regards,
   Felix


> +		}
> +	} while (!is_unique);
> +	up_read(&topology_lock);
> +
>   	return hashout;
>   }
>   /* kfd_assign_gpu - Attach @gpu to the correct kfd topology device. If
> @@ -1946,7 +1970,6 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>   	struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config;
>   	struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info;
>   
> -	gpu_id = kfd_generate_gpu_id(gpu);
>   	if (gpu->xcp && !gpu->xcp->ddev) {
>   		dev_warn(gpu->adev->dev,
>   			 "Won't add GPU to topology since it has no drm node assigned.");
> @@ -1969,6 +1992,7 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>   	if (res)
>   		return res;
>   
> +	gpu_id = kfd_generate_gpu_id(gpu);
>   	dev->gpu_id = gpu_id;
>   	gpu->id = gpu_id;
>   

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/amdkfd: Ensure gpu_id is unique
  2024-05-06 20:30 ` Felix Kuehling
@ 2024-05-06 21:10   ` Harish Kasiviswanathan
  2024-05-06 22:14     ` Felix Kuehling
  0 siblings, 1 reply; 8+ messages in thread
From: Harish Kasiviswanathan @ 2024-05-06 21:10 UTC (permalink / raw)
  To: Felix Kuehling, amd-gfx



On 2024-05-06 16:30, Felix Kuehling wrote:
> 
> On 2024-05-03 18:06, Harish Kasiviswanathan wrote:
>> gpu_id needs to be unique for user space to identify GPUs via KFD
>> interface. In the current implementation there is a very small
>> probability of having non unique gpu_ids.
>>
>> v2: Add check to confirm if gpu_id is unique. If not unique, find one
>>      Changed commit header to reflect the above
>>
>> Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 26 ++++++++++++++++++++++-
>>   1 file changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
>> index b93913934b03..01d4c2e10c6d 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
>> @@ -1095,6 +1095,8 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>>       uint32_t hashout;
>>       uint32_t buf[8];
>>       uint64_t local_mem_size;
>> +    struct kfd_topology_device *dev;
>> +    bool is_unique;
>>       int i;
>>         if (!gpu)
>> @@ -1115,6 +1117,28 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>>       for (i = 0, hashout = 0; i < 8; i++)
>>           hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
>>   +    /* hash generated could be non-unique. Check if it is unique.
>> +     * If not unique increment till unique one is found. In case
>> +     * of overflow, restart from 1
>> +    */
>> +    down_read(&topology_lock);
>> +    do {
>> +        is_unique = true;
>> +        list_for_each_entry(dev, &topology_device_list, list) {
>> +            if (dev->gpu && dev->gpu_id == hashout) {
>> +                is_unique = false;
>> +                break;
>> +            }
>> +        }
>> +        if (unlikely(!is_unique)) {
>> +            hashout = (hashout + 1) &
>> +                  ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
>> +            if (!hashout)
>> +                hashout = 1;
> 
> This doesn't catch the case that hashout was 0 before incrementing it, and was found to be unique.

I didn't actively think about this case when I sent the patch out. However, we don't have gpu_id to be 0. There are places where gpu_id=0 means it is CPU node

> 
> Regards,
>   Felix
> 
> 
>> +        }
>> +    } while (!is_unique);
>> +    up_read(&topology_lock);
>> +
>>       return hashout;
>>   }
>>   /* kfd_assign_gpu - Attach @gpu to the correct kfd topology device. If
>> @@ -1946,7 +1970,6 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>>       struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config;
>>       struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info;
>>   -    gpu_id = kfd_generate_gpu_id(gpu);
>>       if (gpu->xcp && !gpu->xcp->ddev) {
>>           dev_warn(gpu->adev->dev,
>>                "Won't add GPU to topology since it has no drm node assigned.");
>> @@ -1969,6 +1992,7 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>>       if (res)
>>           return res;
>>   +    gpu_id = kfd_generate_gpu_id(gpu);
>>       dev->gpu_id = gpu_id;
>>       gpu->id = gpu_id;
>>   

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/amdkfd: Ensure gpu_id is unique
  2024-05-06 21:10   ` Harish Kasiviswanathan
@ 2024-05-06 22:14     ` Felix Kuehling
  0 siblings, 0 replies; 8+ messages in thread
From: Felix Kuehling @ 2024-05-06 22:14 UTC (permalink / raw)
  To: Harish Kasiviswanathan, amd-gfx

On 2024-05-06 17:10, Harish Kasiviswanathan wrote:
> On 2024-05-06 16:30, Felix Kuehling wrote:
>> On 2024-05-03 18:06, Harish Kasiviswanathan wrote:
>>> gpu_id needs to be unique for user space to identify GPUs via KFD
>>> interface. In the current implementation there is a very small
>>> probability of having non unique gpu_ids.
>>>
>>> v2: Add check to confirm if gpu_id is unique. If not unique, find one
>>>       Changed commit header to reflect the above
>>>
>>> Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
>>> ---
>>>    drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 26 ++++++++++++++++++++++-
>>>    1 file changed, 25 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
>>> index b93913934b03..01d4c2e10c6d 100644
>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
>>> @@ -1095,6 +1095,8 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>>>        uint32_t hashout;
>>>        uint32_t buf[8];
>>>        uint64_t local_mem_size;
>>> +    struct kfd_topology_device *dev;
>>> +    bool is_unique;
>>>        int i;
>>>          if (!gpu)
>>> @@ -1115,6 +1117,28 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>>>        for (i = 0, hashout = 0; i < 8; i++)
>>>            hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
>>>    +    /* hash generated could be non-unique. Check if it is unique.
>>> +     * If not unique increment till unique one is found. In case
>>> +     * of overflow, restart from 1
>>> +    */
>>> +    down_read(&topology_lock);
>>> +    do {
>>> +        is_unique = true;
>>> +        list_for_each_entry(dev, &topology_device_list, list) {
>>> +            if (dev->gpu && dev->gpu_id == hashout) {
>>> +                is_unique = false;
>>> +                break;
>>> +            }
>>> +        }
>>> +        if (unlikely(!is_unique)) {
>>> +            hashout = (hashout + 1) &
>>> +                  ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
>>> +            if (!hashout)
>>> +                hashout = 1;
>> This doesn't catch the case that hashout was 0 before incrementing it, and was found to be unique.
> I didn't actively think about this case when I sent the patch out. However, we don't have gpu_id to be 0. There are places where gpu_id=0 means it is CPU node

I think we make that assumption in a few places, both in kernel mode and 
user mode, e.g.:

struct kfd_process_device *kfd_process_device_data_by_id(struct kfd_process *p, uint32_t gpu_id)
{
         int i;

         if (gpu_id) {
                 for (i = 0; i < p->n_pdds; i++) {
                         struct kfd_process_device *pdd = p->pdds[i];

                         if (pdd->user_gpu_id == gpu_id)
                                 return pdd;
                 }
         }
         return NULL;
}

Or in the Thunk in hsaKmtGetNodeProperties:

         /* For CPU only node don't add any additional GPU memory banks. */
         if (gpu_id) {
                 uint64_t base, limit;
                 if (is_dgpu)
                         NodeProperties->NumMemoryBanks += NUM_OF_DGPU_HEAPS;
                 else
                         NodeProperties->NumMemoryBanks += NUM_OF_IGPU_HEAPS;
                 if (fmm_get_aperture_base_and_limit(FMM_MMIO, gpu_id, &base,
                                 &limit) == HSAKMT_STATUS_SUCCESS)
                         NodeProperties->NumMemoryBanks += 1;
         }

Regards,
   Felix


>
>> Regards,
>>    Felix
>>
>>
>>> +        }
>>> +    } while (!is_unique);
>>> +    up_read(&topology_lock);
>>> +
>>>        return hashout;
>>>    }
>>>    /* kfd_assign_gpu - Attach @gpu to the correct kfd topology device. If
>>> @@ -1946,7 +1970,6 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>>>        struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config;
>>>        struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info;
>>>    -    gpu_id = kfd_generate_gpu_id(gpu);
>>>        if (gpu->xcp && !gpu->xcp->ddev) {
>>>            dev_warn(gpu->adev->dev,
>>>                 "Won't add GPU to topology since it has no drm node assigned.");
>>> @@ -1969,6 +1992,7 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>>>        if (res)
>>>            return res;
>>>    +    gpu_id = kfd_generate_gpu_id(gpu);
>>>        dev->gpu_id = gpu_id;
>>>        gpu->id = gpu_id;
>>>    

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/amdkfd: Ensure gpu_id is unique
  2024-05-03 22:06 [PATCH] drm/amdkfd: Ensure gpu_id is unique Harish Kasiviswanathan
  2024-05-06 20:30 ` Felix Kuehling
@ 2024-05-07  5:52 ` Lazar, Lijo
  1 sibling, 0 replies; 8+ messages in thread
From: Lazar, Lijo @ 2024-05-07  5:52 UTC (permalink / raw)
  To: Harish Kasiviswanathan, amd-gfx



On 5/4/2024 3:36 AM, Harish Kasiviswanathan wrote:
> gpu_id needs to be unique for user space to identify GPUs via KFD
> interface. In the current implementation there is a very small
> probability of having non unique gpu_ids.
> 
> v2: Add check to confirm if gpu_id is unique. If not unique, find one
>     Changed commit header to reflect the above
> 
> Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
> ---
>  drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 26 ++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> index b93913934b03..01d4c2e10c6d 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> @@ -1095,6 +1095,8 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>  	uint32_t hashout;
>  	uint32_t buf[8];
>  	uint64_t local_mem_size;
> +	struct kfd_topology_device *dev;
> +	bool is_unique;
>  	int i;
>  
>  	if (!gpu)
> @@ -1115,6 +1117,28 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>  	for (i = 0, hashout = 0; i < 8; i++)
>  		hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);

Instead of this, suggest to replace this with crc16(). That has a better
chance to avoid collision as it takes into account the whole contents of
the buffer. It may work better than combining hashes with XOR.

Thanks,
Lijo

>  
> +	/* hash generated could be non-unique. Check if it is unique.
> +	 * If not unique increment till unique one is found. In case
> +	 * of overflow, restart from 1
> +	*/
> +	down_read(&topology_lock);
> +	do {
> +		is_unique = true;
> +		list_for_each_entry(dev, &topology_device_list, list) {
> +			if (dev->gpu && dev->gpu_id == hashout) {
> +				is_unique = false;
> +				break;
> +			}
> +		}
> +		if (unlikely(!is_unique)) {
> +			hashout = (hashout + 1) &
> +				  ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
> +			if (!hashout)
> +				hashout = 1;
> +		}
> +	} while (!is_unique);
> +	up_read(&topology_lock);
> +
>  	return hashout;
>  }
>  /* kfd_assign_gpu - Attach @gpu to the correct kfd topology device. If
> @@ -1946,7 +1970,6 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>  	struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config;
>  	struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info;
>  
> -	gpu_id = kfd_generate_gpu_id(gpu);
>  	if (gpu->xcp && !gpu->xcp->ddev) {
>  		dev_warn(gpu->adev->dev,
>  			 "Won't add GPU to topology since it has no drm node assigned.");
> @@ -1969,6 +1992,7 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>  	if (res)
>  		return res;
>  
> +	gpu_id = kfd_generate_gpu_id(gpu);
>  	dev->gpu_id = gpu_id;
>  	gpu->id = gpu_id;
>  

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] drm/amdkfd: Ensure gpu_id is unique
@ 2024-05-09 20:06 Harish Kasiviswanathan
  2024-05-10 13:06 ` Lazar, Lijo
  2024-05-10 20:57 ` Felix Kuehling
  0 siblings, 2 replies; 8+ messages in thread
From: Harish Kasiviswanathan @ 2024-05-09 20:06 UTC (permalink / raw)
  To: amd-gfx; +Cc: Harish Kasiviswanathan

gpu_id needs to be unique for user space to identify GPUs via KFD
interface. In the current implementation there is a very small
probability of having non unique gpu_ids.

v2: Add check to confirm if gpu_id is unique. If not unique, find one
    Changed commit header to reflect the above
v3: Use crc16 as suggested-by: Lijo Lazar <lijo.lazar@amd.com>
    Ensure that gpu_id != 0

Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 40 +++++++++++++++++++----
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 219dcf504f24..4954a3021f70 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -31,6 +31,7 @@
 #include <linux/log2.h>
 #include <linux/dmi.h>
 #include <linux/atomic.h>
+#include <linux/crc16.h>
 
 #include "kfd_priv.h"
 #include "kfd_crat.h"
@@ -1091,14 +1092,17 @@ void kfd_topology_shutdown(void)
 
 static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
 {
-	uint32_t hashout;
+	uint32_t gpu_id;
 	uint32_t buf[8];
 	uint64_t local_mem_size;
-	int i;
+	struct kfd_topology_device *dev;
+	bool is_unique;
+	uint8_t *crc_buf;
 
 	if (!gpu)
 		return 0;
 
+	crc_buf = (uint8_t*)&buf;
 	local_mem_size = gpu->local_mem_info.local_mem_size_private +
 			gpu->local_mem_info.local_mem_size_public;
 	buf[0] = gpu->adev->pdev->devfn;
@@ -1111,10 +1115,34 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
 	buf[6] = upper_32_bits(local_mem_size);
 	buf[7] = (ffs(gpu->xcc_mask) - 1) | (NUM_XCC(gpu->xcc_mask) << 16);
 
-	for (i = 0, hashout = 0; i < 8; i++)
-		hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
+	gpu_id = crc16(0, crc_buf, sizeof(buf)) &
+		 ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
 
-	return hashout;
+	/* There is a very small possibility when generating a
+	 * 16 (KFD_GPU_ID_HASH_WIDTH) bit value from 8 word buffer
+	 * that the value could be 0 or non-unique. So, check if
+	 * it is unique and non-zero. If not unique increment till
+	 * unique one is found. In case of overflow, restart from 1
+	 */
+
+	down_read(&topology_lock);
+	do {
+		is_unique = true;
+		if (!gpu_id)
+			gpu_id = 1;
+		list_for_each_entry(dev, &topology_device_list, list) {
+			if (dev->gpu && dev->gpu_id == gpu_id) {
+				is_unique = false;
+				break;
+			}
+		}
+		if (unlikely(!is_unique))
+			gpu_id = (gpu_id + 1) &
+				  ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
+	} while (!is_unique);
+	up_read(&topology_lock);
+
+	return gpu_id;
 }
 /* kfd_assign_gpu - Attach @gpu to the correct kfd topology device. If
  *		the GPU device is not already present in the topology device
@@ -1945,7 +1973,6 @@ int kfd_topology_add_device(struct kfd_node *gpu)
 	struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config;
 	struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info;
 
-	gpu_id = kfd_generate_gpu_id(gpu);
 	if (gpu->xcp && !gpu->xcp->ddev) {
 		dev_warn(gpu->adev->dev,
 			 "Won't add GPU to topology since it has no drm node assigned.");
@@ -1968,6 +1995,7 @@ int kfd_topology_add_device(struct kfd_node *gpu)
 	if (res)
 		return res;
 
+	gpu_id = kfd_generate_gpu_id(gpu);
 	dev->gpu_id = gpu_id;
 	gpu->id = gpu_id;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/amdkfd: Ensure gpu_id is unique
  2024-05-09 20:06 Harish Kasiviswanathan
@ 2024-05-10 13:06 ` Lazar, Lijo
  2024-05-10 20:57 ` Felix Kuehling
  1 sibling, 0 replies; 8+ messages in thread
From: Lazar, Lijo @ 2024-05-10 13:06 UTC (permalink / raw)
  To: Harish Kasiviswanathan, amd-gfx



On 5/10/2024 1:36 AM, Harish Kasiviswanathan wrote:
> gpu_id needs to be unique for user space to identify GPUs via KFD
> interface. In the current implementation there is a very small
> probability of having non unique gpu_ids.
> 
> v2: Add check to confirm if gpu_id is unique. If not unique, find one
>     Changed commit header to reflect the above
> v3: Use crc16 as suggested-by: Lijo Lazar <lijo.lazar@amd.com>
>     Ensure that gpu_id != 0
> 
> Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>

Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>

Thanks,
Lijo

> ---
>  drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 40 +++++++++++++++++++----
>  1 file changed, 34 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> index 219dcf504f24..4954a3021f70 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> @@ -31,6 +31,7 @@
>  #include <linux/log2.h>
>  #include <linux/dmi.h>
>  #include <linux/atomic.h>
> +#include <linux/crc16.h>
>  
>  #include "kfd_priv.h"
>  #include "kfd_crat.h"
> @@ -1091,14 +1092,17 @@ void kfd_topology_shutdown(void)
>  
>  static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>  {
> -	uint32_t hashout;
> +	uint32_t gpu_id;
>  	uint32_t buf[8];
>  	uint64_t local_mem_size;
> -	int i;
> +	struct kfd_topology_device *dev;
> +	bool is_unique;
> +	uint8_t *crc_buf;
>  
>  	if (!gpu)
>  		return 0;
>  
> +	crc_buf = (uint8_t*)&buf;
>  	local_mem_size = gpu->local_mem_info.local_mem_size_private +
>  			gpu->local_mem_info.local_mem_size_public;
>  	buf[0] = gpu->adev->pdev->devfn;
> @@ -1111,10 +1115,34 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>  	buf[6] = upper_32_bits(local_mem_size);
>  	buf[7] = (ffs(gpu->xcc_mask) - 1) | (NUM_XCC(gpu->xcc_mask) << 16);
>  
> -	for (i = 0, hashout = 0; i < 8; i++)
> -		hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
> +	gpu_id = crc16(0, crc_buf, sizeof(buf)) &
> +		 ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
>  
> -	return hashout;
> +	/* There is a very small possibility when generating a
> +	 * 16 (KFD_GPU_ID_HASH_WIDTH) bit value from 8 word buffer
> +	 * that the value could be 0 or non-unique. So, check if
> +	 * it is unique and non-zero. If not unique increment till
> +	 * unique one is found. In case of overflow, restart from 1
> +	 */
> +
> +	down_read(&topology_lock);
> +	do {
> +		is_unique = true;
> +		if (!gpu_id)
> +			gpu_id = 1;
> +		list_for_each_entry(dev, &topology_device_list, list) {
> +			if (dev->gpu && dev->gpu_id == gpu_id) {
> +				is_unique = false;
> +				break;
> +			}
> +		}
> +		if (unlikely(!is_unique))
> +			gpu_id = (gpu_id + 1) &
> +				  ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
> +	} while (!is_unique);
> +	up_read(&topology_lock);
> +
> +	return gpu_id;
>  }
>  /* kfd_assign_gpu - Attach @gpu to the correct kfd topology device. If
>   *		the GPU device is not already present in the topology device
> @@ -1945,7 +1973,6 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>  	struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config;
>  	struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info;
>  
> -	gpu_id = kfd_generate_gpu_id(gpu);
>  	if (gpu->xcp && !gpu->xcp->ddev) {
>  		dev_warn(gpu->adev->dev,
>  			 "Won't add GPU to topology since it has no drm node assigned.");
> @@ -1968,6 +1995,7 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>  	if (res)
>  		return res;
>  
> +	gpu_id = kfd_generate_gpu_id(gpu);
>  	dev->gpu_id = gpu_id;
>  	gpu->id = gpu_id;
>  

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/amdkfd: Ensure gpu_id is unique
  2024-05-09 20:06 Harish Kasiviswanathan
  2024-05-10 13:06 ` Lazar, Lijo
@ 2024-05-10 20:57 ` Felix Kuehling
  1 sibling, 0 replies; 8+ messages in thread
From: Felix Kuehling @ 2024-05-10 20:57 UTC (permalink / raw)
  To: Harish Kasiviswanathan, amd-gfx


On 2024-05-09 16:06, Harish Kasiviswanathan wrote:
> gpu_id needs to be unique for user space to identify GPUs via KFD
> interface. In the current implementation there is a very small
> probability of having non unique gpu_ids.
>
> v2: Add check to confirm if gpu_id is unique. If not unique, find one
>      Changed commit header to reflect the above
> v3: Use crc16 as suggested-by: Lijo Lazar <lijo.lazar@amd.com>
>      Ensure that gpu_id != 0
>
> Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>

Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>


> ---
>   drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 40 +++++++++++++++++++----
>   1 file changed, 34 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> index 219dcf504f24..4954a3021f70 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
> @@ -31,6 +31,7 @@
>   #include <linux/log2.h>
>   #include <linux/dmi.h>
>   #include <linux/atomic.h>
> +#include <linux/crc16.h>
>   
>   #include "kfd_priv.h"
>   #include "kfd_crat.h"
> @@ -1091,14 +1092,17 @@ void kfd_topology_shutdown(void)
>   
>   static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>   {
> -	uint32_t hashout;
> +	uint32_t gpu_id;
>   	uint32_t buf[8];
>   	uint64_t local_mem_size;
> -	int i;
> +	struct kfd_topology_device *dev;
> +	bool is_unique;
> +	uint8_t *crc_buf;
>   
>   	if (!gpu)
>   		return 0;
>   
> +	crc_buf = (uint8_t*)&buf;
>   	local_mem_size = gpu->local_mem_info.local_mem_size_private +
>   			gpu->local_mem_info.local_mem_size_public;
>   	buf[0] = gpu->adev->pdev->devfn;
> @@ -1111,10 +1115,34 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
>   	buf[6] = upper_32_bits(local_mem_size);
>   	buf[7] = (ffs(gpu->xcc_mask) - 1) | (NUM_XCC(gpu->xcc_mask) << 16);
>   
> -	for (i = 0, hashout = 0; i < 8; i++)
> -		hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
> +	gpu_id = crc16(0, crc_buf, sizeof(buf)) &
> +		 ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
>   
> -	return hashout;
> +	/* There is a very small possibility when generating a
> +	 * 16 (KFD_GPU_ID_HASH_WIDTH) bit value from 8 word buffer
> +	 * that the value could be 0 or non-unique. So, check if
> +	 * it is unique and non-zero. If not unique increment till
> +	 * unique one is found. In case of overflow, restart from 1
> +	 */
> +
> +	down_read(&topology_lock);
> +	do {
> +		is_unique = true;
> +		if (!gpu_id)
> +			gpu_id = 1;
> +		list_for_each_entry(dev, &topology_device_list, list) {
> +			if (dev->gpu && dev->gpu_id == gpu_id) {
> +				is_unique = false;
> +				break;
> +			}
> +		}
> +		if (unlikely(!is_unique))
> +			gpu_id = (gpu_id + 1) &
> +				  ((1 << KFD_GPU_ID_HASH_WIDTH) - 1);
> +	} while (!is_unique);
> +	up_read(&topology_lock);
> +
> +	return gpu_id;
>   }
>   /* kfd_assign_gpu - Attach @gpu to the correct kfd topology device. If
>    *		the GPU device is not already present in the topology device
> @@ -1945,7 +1973,6 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>   	struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config;
>   	struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info;
>   
> -	gpu_id = kfd_generate_gpu_id(gpu);
>   	if (gpu->xcp && !gpu->xcp->ddev) {
>   		dev_warn(gpu->adev->dev,
>   			 "Won't add GPU to topology since it has no drm node assigned.");
> @@ -1968,6 +1995,7 @@ int kfd_topology_add_device(struct kfd_node *gpu)
>   	if (res)
>   		return res;
>   
> +	gpu_id = kfd_generate_gpu_id(gpu);
>   	dev->gpu_id = gpu_id;
>   	gpu->id = gpu_id;
>   

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-05-10 20:57 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-03 22:06 [PATCH] drm/amdkfd: Ensure gpu_id is unique Harish Kasiviswanathan
2024-05-06 20:30 ` Felix Kuehling
2024-05-06 21:10   ` Harish Kasiviswanathan
2024-05-06 22:14     ` Felix Kuehling
2024-05-07  5:52 ` Lazar, Lijo
  -- strict thread matches above, loose matches on Subject: below --
2024-05-09 20:06 Harish Kasiviswanathan
2024-05-10 13:06 ` Lazar, Lijo
2024-05-10 20:57 ` Felix Kuehling

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.