libhsakmt: fix multiple threads register userptr race v2

After calling ioctl to create userptr obj, take aperture lock, check if
there is same userptr obj created after finding object, to catch the
race that multiple threads register same userptr to multiple GPUs.

If same userptr obj exist, then increase userptr registeration_count,
and free the newly create obj.

Change-Id: I63ae3a4f54da8aedd11c124d8d53ebe727b8203a
Signed-off-by: Philip Yang <Philip.Yang@amd.com>


[ROCm/ROCR-Runtime commit: 8f7443494a]
This commit is contained in:
Philip Yang
2021-09-10 12:33:48 -04:00
parent 35f00d04ff
commit a6335e1ae2
+19 -7
View File
@@ -3008,7 +3008,7 @@ static HSAKMT_STATUS fmm_register_user_memory(void *addr, HSAuint64 size,
HSAuint64 aligned_size = PAGE_ALIGN_UP(page_offset + size);
void *svm_addr;
HSAuint32 gpu_id;
vm_object_t *obj;
vm_object_t *obj, *exist_obj;
/* Find first GPU for creating the userptr BO */
if (!g_first_gpu_mem)
@@ -3029,20 +3029,32 @@ static HSAKMT_STATUS fmm_register_user_memory(void *addr, HSAuint64 size,
if (!svm_addr)
return HSAKMT_STATUS_ERROR;
if (obj) {
pthread_mutex_lock(&aperture->fmm_mutex);
if (!obj)
return HSAKMT_STATUS_ERROR;
pthread_mutex_lock(&aperture->fmm_mutex);
/* catch the race condition where some other thread added the userptr
* object already after the vm_find_object.
*/
exist_obj = vm_find_object_by_userptr(aperture, addr, size);
if (exist_obj) {
++exist_obj->registration_count;
} else {
obj->userptr = addr;
gpuid_to_nodeid(gpu_id, &obj->node_id);
obj->userptr_size = size;
obj->registration_count = 1;
obj->user_node.key = rbtree_key((unsigned long)addr, size);
rbtree_insert(&aperture->user_tree, &obj->user_node);
pthread_mutex_unlock(&aperture->fmm_mutex);
} else
return HSAKMT_STATUS_ERROR;
}
pthread_mutex_unlock(&aperture->fmm_mutex);
if (exist_obj)
__fmm_release(obj, aperture);
if (obj_ret)
*obj_ret = obj;
*obj_ret = exist_obj ? exist_obj : obj;
return HSAKMT_STATUS_SUCCESS;
}