* [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.