<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Drop this patch series, as Felix pointed out, the forked process
takes svm_bo device pages ref, svm_bo->pdd could refer to the
process that doesn't exist any more.</p>
<p>Regards,</p>
<p>Philip<br>
</p>
On 2024-10-11 11:00, Philip Yang wrote:<br>
<blockquote type="cite" cite="mid:20241011150007.26310-1-Philip.Yang@amd.com">
<pre class="moz-quote-pre" wrap="">KFD process device data pdd will be used for VRAM usage accounting, save
pdd to svm_bo to avoid searching pdd for every accounting, and get KFD
node from pdd->dev.
svm_bo->pdd will always be valid because KFD process release free all
svm_bo first, then destroy process pdds.
Signed-off-by: Philip Yang <a class="moz-txt-link-rfc2396E" href="mailto:Philip.Yang@amd.com"><Philip.Yang@amd.com></a>
---
drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 27 +++++++++++++++++----------
drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 2 +-
2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 857ec6f23bba..d40f6fb803df 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -180,7 +180,7 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange,
page = hmm_pfn_to_page(hmm_pfns[i]);
if (is_zone_device_page(page)) {
- struct amdgpu_device *bo_adev = prange->svm_bo->node->adev;
+ struct amdgpu_device *bo_adev = prange->svm_bo->pdd->dev->adev;
addr[i] = (hmm_pfns[i] << PAGE_SHIFT) +
bo_adev->vm_manager.vram_base_offset -
@@ -457,11 +457,11 @@ svm_range_validate_svm_bo(struct kfd_node *node, struct svm_range *prange)
}
if (svm_bo_ref_unless_zero(prange->svm_bo)) {
/*
- * Migrate from GPU to GPU, remove range from source svm_bo->node
+ * Migrate from GPU to GPU, remove range from source svm_bo node
* range list, and return false to allocate svm_bo from destination
* node.
*/
- if (prange->svm_bo->node != node) {
+ if (prange->svm_bo->pdd->dev != node) {
mutex_unlock(&prange->lock);
spin_lock(&prange->svm_bo->list_lock);
@@ -532,6 +532,7 @@ int
svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
bool clear)
{
+ struct kfd_process_device *pdd;
struct amdgpu_bo_param bp;
struct svm_range_bo *svm_bo;
struct amdgpu_bo_user *ubo;
@@ -548,17 +549,22 @@ svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
return 0;
svm_bo = svm_range_bo_new();
- if (!svm_bo) {
- pr_debug("failed to alloc svm bo\n");
+ if (!svm_bo)
return -ENOMEM;
+
+ pdd = svm_range_get_pdd_by_node(prange, node);
+ if (!pdd) {
+ r = -ESRCH;
+ goto out_free;
}
+ svm_bo->pdd = pdd;
+
mm = get_task_mm(p->lead_thread);
if (!mm) {
pr_debug("failed to get mm\n");
- kfree(svm_bo);
- return -ESRCH;
+ r = -ESRCH;
+ goto out_free;
}
- svm_bo->node = node;
svm_bo->eviction_fence =
amdgpu_amdkfd_fence_create(dma_fence_context_alloc(1),
mm,
@@ -629,6 +635,7 @@ svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
amdgpu_bo_unref(&bo);
create_bo_failed:
dma_fence_put(&svm_bo->eviction_fence->base);
+out_free:
kfree(svm_bo);
prange->ttm_res = NULL;
@@ -1176,7 +1183,7 @@ svm_range_get_pte_flags(struct kfd_node *node,
unsigned int mtype_local;
if (domain == SVM_RANGE_VRAM_DOMAIN)
- bo_node = prange->svm_bo->node;
+ bo_node = prange->svm_bo->pdd->dev;
switch (amdgpu_ip_version(node->adev, GC_HWIP, 0)) {
case IP_VERSION(9, 4, 1):
@@ -1440,7 +1447,7 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset,
int r = 0;
if (prange->svm_bo && prange->ttm_res)
- bo_adev = prange->svm_bo->node->adev;
+ bo_adev = prange->svm_bo->pdd->dev->adev;
p = container_of(prange->svms, struct kfd_process, svms);
for_each_set_bit(gpuidx, bitmap, MAX_GPU_INSTANCE) {
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index bddd24f04669..fad2d6d2223a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -48,7 +48,7 @@ struct svm_range_bo {
struct work_struct eviction_work;
uint32_t evicting;
struct work_struct release_work;
- struct kfd_node *node;
+ struct kfd_process_device *pdd;
};
enum svm_work_list_ops {
</pre>
</blockquote>
</body>
</html>