aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4254-drm-amdkfd-CMA-Remove-diff.-device-restriction.patch
blob: bb79eff3b01737d5f9b57a1a50b858ea47d488bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
From ce3bd835c235507674e471acc612104da3eeec45 Mon Sep 17 00:00:00 2001
From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Date: Fri, 6 Apr 2018 18:07:25 -0400
Subject: [PATCH 4254/5725] drm/amdkfd: CMA: Remove diff. device restriction

CMA is supported in certain situations if the BOs are registered to differnt
devices. They are -

a) If both source and destination are userptr then device doens't matter
as CPU is used to copy.
b) If one of them is a userptr, then the shadow system BO will be created
on the other device. So the copy will done by that device.

The non supported cases are -

a) The system BOs are always registered to the first device. So if one
BO is system and the other BO is a local memory in different device then
it is not supported currently.
b) If both BOs are in local memory of different devices then it is not
supported.

BUG:SWDEV-146559

Change-Id: I0ff5426402c147dd19ec15abafd18807ecca25fe
Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index d1a18c9..a216225 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -2118,6 +2118,7 @@ static int kfd_copy_bos(struct cma_iter *si, struct cma_iter *di,
 	struct kfd_bo *dst_bo = di->cur_bo, *src_bo = si->cur_bo;
 	uint64_t src_offset = si->bo_offset, dst_offset = di->bo_offset;
 	struct kgd_mem *src_mem = src_bo->mem, *dst_mem = dst_bo->mem;
+	struct kfd_dev *dev = dst_bo->dev;
 
 	*copied = 0;
 	if (f)
@@ -2129,11 +2130,14 @@ static int kfd_copy_bos(struct cma_iter *si, struct cma_iter *di,
 	 * by using the underlying userptr BO pages. Then use this shadow
 	 * BO for copy. src_offset & dst_offset are adjusted because the new BO
 	 * is only created for the window (offset, size) requested.
+	 * The shadow BO is created on the other device. This means if the
+	 * other BO is a device memory, the copy will be using that device.
 	 * The BOs are stored in cma_list for deferred cleanup. This minimizes
 	 * fence waiting just to the last fence.
 	 */
 	if (src_bo->cpuva) {
-		err = kfd_create_cma_system_bo(dst_bo->dev, src_bo, &size,
+		dev = dst_bo->dev;
+		err = kfd_create_cma_system_bo(dev, src_bo, &size,
 					       si->bo_offset, cma_write,
 					       si->p, si->mm, si->task,
 					       &si->cma_bo);
@@ -2141,7 +2145,8 @@ static int kfd_copy_bos(struct cma_iter *si, struct cma_iter *di,
 		src_offset = si->bo_offset & (PAGE_SIZE - 1);
 		list_add_tail(&si->cma_bo->list, &si->cma_list);
 	} else if (dst_bo->cpuva) {
-		err = kfd_create_cma_system_bo(src_bo->dev, dst_bo, &size,
+		dev = src_bo->dev;
+		err = kfd_create_cma_system_bo(dev, dst_bo, &size,
 					       di->bo_offset, cma_write,
 					       di->p, di->mm, di->task,
 					       &di->cma_bo);
@@ -2150,15 +2155,15 @@ static int kfd_copy_bos(struct cma_iter *si, struct cma_iter *di,
 		list_add_tail(&di->cma_bo->list, &di->cma_list);
 	} else if (src_bo->dev->kgd != dst_bo->dev->kgd) {
 		pr_err("CMA %d fail. Not same dev\n", cma_write);
-		err = -EINVAL;
+		return -EINVAL;
 	}
 
 	if (err) {
 		pr_err("Failed to create system BO %d", err);
-		err = -EINVAL;
+		return -EINVAL;
 	}
 
-	err = dst_bo->dev->kfd2kgd->copy_mem_to_mem(src_bo->dev->kgd, src_mem,
+	err = dst_bo->dev->kfd2kgd->copy_mem_to_mem(dev->kgd, src_mem,
 						     src_offset, dst_mem,
 						     dst_offset, size, f,
 						     copied);
@@ -2193,12 +2198,6 @@ static int kfd_copy_single_range(struct cma_iter *si, struct cma_iter *di,
 
 		copy_size = min(size, (di->array->size - di->offset));
 
-		/* Check both BOs belong to same device */
-		if (src_bo->dev->kgd != dst_bo->dev->kgd) {
-			pr_err("CMA fail. Not same dev\n");
-			return -EINVAL;
-		}
-
 		err = kfd_copy_bos(si, di, cma_write, copy_size, &fence, &n);
 		if (err) {
 			pr_err("CMA %d failed\n", err);
-- 
2.7.4