hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
....@@ -22,14 +22,12 @@
2222 * Authors: Christian König
2323 */
2424
25
-#include <drm/drmP.h>
2625 #include "amdgpu.h"
2726
28
-struct amdgpu_gtt_mgr {
29
- struct drm_mm mm;
30
- spinlock_t lock;
31
- atomic64_t available;
32
-};
27
+static inline struct amdgpu_gtt_mgr *to_gtt_mgr(struct ttm_resource_manager *man)
28
+{
29
+ return container_of(man, struct amdgpu_gtt_mgr, manager);
30
+}
3331
3432 struct amdgpu_gtt_node {
3533 struct drm_mm_node node;
....@@ -37,50 +35,120 @@
3735 };
3836
3937 /**
38
+ * DOC: mem_info_gtt_total
39
+ *
40
+ * The amdgpu driver provides a sysfs API for reporting current total size of
41
+ * the GTT.
42
+ * The file mem_info_gtt_total is used for this, and returns the total size of
43
+ * the GTT block, in bytes
44
+ */
45
+static ssize_t amdgpu_mem_info_gtt_total_show(struct device *dev,
46
+ struct device_attribute *attr, char *buf)
47
+{
48
+ struct drm_device *ddev = dev_get_drvdata(dev);
49
+ struct amdgpu_device *adev = drm_to_adev(ddev);
50
+ struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
51
+
52
+ return snprintf(buf, PAGE_SIZE, "%llu\n",
53
+ man->size * PAGE_SIZE);
54
+}
55
+
56
+/**
57
+ * DOC: mem_info_gtt_used
58
+ *
59
+ * The amdgpu driver provides a sysfs API for reporting current total amount of
60
+ * used GTT.
61
+ * The file mem_info_gtt_used is used for this, and returns the current used
62
+ * size of the GTT block, in bytes
63
+ */
64
+static ssize_t amdgpu_mem_info_gtt_used_show(struct device *dev,
65
+ struct device_attribute *attr, char *buf)
66
+{
67
+ struct drm_device *ddev = dev_get_drvdata(dev);
68
+ struct amdgpu_device *adev = drm_to_adev(ddev);
69
+ struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
70
+
71
+ return snprintf(buf, PAGE_SIZE, "%llu\n",
72
+ amdgpu_gtt_mgr_usage(man));
73
+}
74
+
75
+static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO,
76
+ amdgpu_mem_info_gtt_total_show, NULL);
77
+static DEVICE_ATTR(mem_info_gtt_used, S_IRUGO,
78
+ amdgpu_mem_info_gtt_used_show, NULL);
79
+
80
+static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func;
81
+/**
4082 * amdgpu_gtt_mgr_init - init GTT manager and DRM MM
4183 *
42
- * @man: TTM memory type manager
43
- * @p_size: maximum size of GTT
84
+ * @adev: amdgpu_device pointer
85
+ * @gtt_size: maximum size of GTT
4486 *
4587 * Allocate and initialize the GTT manager.
4688 */
47
-static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man,
48
- unsigned long p_size)
89
+int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
4990 {
50
- struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
51
- struct amdgpu_gtt_mgr *mgr;
91
+ struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
92
+ struct ttm_resource_manager *man = &mgr->manager;
5293 uint64_t start, size;
94
+ int ret;
5395
54
- mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
55
- if (!mgr)
56
- return -ENOMEM;
96
+ man->use_tt = true;
97
+ man->func = &amdgpu_gtt_mgr_func;
98
+
99
+ ttm_resource_manager_init(man, gtt_size >> PAGE_SHIFT);
57100
58101 start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
59102 size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
60103 drm_mm_init(&mgr->mm, start, size);
61104 spin_lock_init(&mgr->lock);
62
- atomic64_set(&mgr->available, p_size);
63
- man->priv = mgr;
105
+ atomic64_set(&mgr->available, gtt_size >> PAGE_SHIFT);
106
+
107
+ ret = device_create_file(adev->dev, &dev_attr_mem_info_gtt_total);
108
+ if (ret) {
109
+ DRM_ERROR("Failed to create device file mem_info_gtt_total\n");
110
+ return ret;
111
+ }
112
+ ret = device_create_file(adev->dev, &dev_attr_mem_info_gtt_used);
113
+ if (ret) {
114
+ DRM_ERROR("Failed to create device file mem_info_gtt_used\n");
115
+ return ret;
116
+ }
117
+
118
+ ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager);
119
+ ttm_resource_manager_set_used(man, true);
64120 return 0;
65121 }
66122
67123 /**
68124 * amdgpu_gtt_mgr_fini - free and destroy GTT manager
69125 *
70
- * @man: TTM memory type manager
126
+ * @adev: amdgpu_device pointer
71127 *
72128 * Destroy and free the GTT manager, returns -EBUSY if ranges are still
73129 * allocated inside it.
74130 */
75
-static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man)
131
+void amdgpu_gtt_mgr_fini(struct amdgpu_device *adev)
76132 {
77
- struct amdgpu_gtt_mgr *mgr = man->priv;
133
+ struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
134
+ struct ttm_resource_manager *man = &mgr->manager;
135
+ int ret;
136
+
137
+ ttm_resource_manager_set_used(man, false);
138
+
139
+ ret = ttm_resource_manager_force_list_clean(&adev->mman.bdev, man);
140
+ if (ret)
141
+ return;
142
+
78143 spin_lock(&mgr->lock);
79144 drm_mm_takedown(&mgr->mm);
80145 spin_unlock(&mgr->lock);
81
- kfree(mgr);
82
- man->priv = NULL;
83
- return 0;
146
+
147
+ device_remove_file(adev->dev, &dev_attr_mem_info_gtt_total);
148
+ device_remove_file(adev->dev, &dev_attr_mem_info_gtt_used);
149
+
150
+ ttm_resource_manager_cleanup(man);
151
+ ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, NULL);
84152 }
85153
86154 /**
....@@ -90,62 +158,9 @@
90158 *
91159 * Check if a mem object has already address space allocated.
92160 */
93
-bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem)
161
+bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem)
94162 {
95
- struct amdgpu_gtt_node *node = mem->mm_node;
96
-
97
- return (node->node.start != AMDGPU_BO_INVALID_OFFSET);
98
-}
99
-
100
-/**
101
- * amdgpu_gtt_mgr_alloc - allocate new ranges
102
- *
103
- * @man: TTM memory type manager
104
- * @tbo: TTM BO we need this range for
105
- * @place: placement flags and restrictions
106
- * @mem: the resulting mem object
107
- *
108
- * Allocate the address space for a node.
109
- */
110
-static int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
111
- struct ttm_buffer_object *tbo,
112
- const struct ttm_place *place,
113
- struct ttm_mem_reg *mem)
114
-{
115
- struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
116
- struct amdgpu_gtt_mgr *mgr = man->priv;
117
- struct amdgpu_gtt_node *node = mem->mm_node;
118
- enum drm_mm_insert_mode mode;
119
- unsigned long fpfn, lpfn;
120
- int r;
121
-
122
- if (amdgpu_gtt_mgr_has_gart_addr(mem))
123
- return 0;
124
-
125
- if (place)
126
- fpfn = place->fpfn;
127
- else
128
- fpfn = 0;
129
-
130
- if (place && place->lpfn)
131
- lpfn = place->lpfn;
132
- else
133
- lpfn = adev->gart.num_cpu_pages;
134
-
135
- mode = DRM_MM_INSERT_BEST;
136
- if (place && place->flags & TTM_PL_FLAG_TOPDOWN)
137
- mode = DRM_MM_INSERT_HIGH;
138
-
139
- spin_lock(&mgr->lock);
140
- r = drm_mm_insert_node_in_range(&mgr->mm, &node->node, mem->num_pages,
141
- mem->page_alignment, 0, fpfn, lpfn,
142
- mode);
143
- spin_unlock(&mgr->lock);
144
-
145
- if (!r)
146
- mem->start = node->node.start;
147
-
148
- return r;
163
+ return mem->mm_node != NULL;
149164 }
150165
151166 /**
....@@ -158,12 +173,12 @@
158173 *
159174 * Dummy, allocate the node but no space for it yet.
160175 */
161
-static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,
176
+static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
162177 struct ttm_buffer_object *tbo,
163178 const struct ttm_place *place,
164
- struct ttm_mem_reg *mem)
179
+ struct ttm_resource *mem)
165180 {
166
- struct amdgpu_gtt_mgr *mgr = man->priv;
181
+ struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
167182 struct amdgpu_gtt_node *node;
168183 int r;
169184
....@@ -171,10 +186,16 @@
171186 if ((&tbo->mem == mem || tbo->mem.mem_type != TTM_PL_TT) &&
172187 atomic64_read(&mgr->available) < mem->num_pages) {
173188 spin_unlock(&mgr->lock);
174
- return 0;
189
+ return -ENOSPC;
175190 }
176191 atomic64_sub(mem->num_pages, &mgr->available);
177192 spin_unlock(&mgr->lock);
193
+
194
+ if (!place->lpfn) {
195
+ mem->mm_node = NULL;
196
+ mem->start = AMDGPU_BO_INVALID_OFFSET;
197
+ return 0;
198
+ }
178199
179200 node = kzalloc(sizeof(*node), GFP_KERNEL);
180201 if (!node) {
....@@ -182,24 +203,25 @@
182203 goto err_out;
183204 }
184205
185
- node->node.start = AMDGPU_BO_INVALID_OFFSET;
186
- node->node.size = mem->num_pages;
187206 node->tbo = tbo;
188
- mem->mm_node = node;
189207
190
- if (place->fpfn || place->lpfn || place->flags & TTM_PL_FLAG_TOPDOWN) {
191
- r = amdgpu_gtt_mgr_alloc(man, tbo, place, mem);
192
- if (unlikely(r)) {
193
- kfree(node);
194
- mem->mm_node = NULL;
195
- r = 0;
196
- goto err_out;
197
- }
198
- } else {
199
- mem->start = node->node.start;
200
- }
208
+ spin_lock(&mgr->lock);
209
+ r = drm_mm_insert_node_in_range(&mgr->mm, &node->node, mem->num_pages,
210
+ mem->page_alignment, 0, place->fpfn,
211
+ place->lpfn, DRM_MM_INSERT_BEST);
212
+ spin_unlock(&mgr->lock);
213
+
214
+ if (unlikely(r))
215
+ goto err_free;
216
+
217
+ mem->mm_node = node;
218
+ mem->start = node->node.start;
201219
202220 return 0;
221
+
222
+err_free:
223
+ kfree(node);
224
+
203225 err_out:
204226 atomic64_add(mem->num_pages, &mgr->available);
205227
....@@ -210,29 +232,24 @@
210232 * amdgpu_gtt_mgr_del - free ranges
211233 *
212234 * @man: TTM memory type manager
213
- * @tbo: TTM BO we need this range for
214
- * @place: placement flags and restrictions
215235 * @mem: TTM memory object
216236 *
217237 * Free the allocated GTT again.
218238 */
219
-static void amdgpu_gtt_mgr_del(struct ttm_mem_type_manager *man,
220
- struct ttm_mem_reg *mem)
239
+static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man,
240
+ struct ttm_resource *mem)
221241 {
222
- struct amdgpu_gtt_mgr *mgr = man->priv;
242
+ struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
223243 struct amdgpu_gtt_node *node = mem->mm_node;
224244
225
- if (!node)
226
- return;
227
-
228
- spin_lock(&mgr->lock);
229
- if (node->node.start != AMDGPU_BO_INVALID_OFFSET)
245
+ if (node) {
246
+ spin_lock(&mgr->lock);
230247 drm_mm_remove_node(&node->node);
231
- spin_unlock(&mgr->lock);
232
- atomic64_add(mem->num_pages, &mgr->available);
248
+ spin_unlock(&mgr->lock);
249
+ kfree(node);
250
+ }
233251
234
- kfree(node);
235
- mem->mm_node = NULL;
252
+ atomic64_add(mem->num_pages, &mgr->available);
236253 }
237254
238255 /**
....@@ -242,17 +259,17 @@
242259 *
243260 * Return how many bytes are used in the GTT domain
244261 */
245
-uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man)
262
+uint64_t amdgpu_gtt_mgr_usage(struct ttm_resource_manager *man)
246263 {
247
- struct amdgpu_gtt_mgr *mgr = man->priv;
264
+ struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
248265 s64 result = man->size - atomic64_read(&mgr->available);
249266
250267 return (result > 0 ? result : 0) * PAGE_SIZE;
251268 }
252269
253
-int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man)
270
+int amdgpu_gtt_mgr_recover(struct ttm_resource_manager *man)
254271 {
255
- struct amdgpu_gtt_mgr *mgr = man->priv;
272
+ struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
256273 struct amdgpu_gtt_node *node;
257274 struct drm_mm_node *mm_node;
258275 int r = 0;
....@@ -277,10 +294,10 @@
277294 *
278295 * Dump the table content using printk.
279296 */
280
-static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man,
297
+static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man,
281298 struct drm_printer *printer)
282299 {
283
- struct amdgpu_gtt_mgr *mgr = man->priv;
300
+ struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
284301
285302 spin_lock(&mgr->lock);
286303 drm_mm_print(&mgr->mm, printer);
....@@ -291,10 +308,8 @@
291308 amdgpu_gtt_mgr_usage(man) >> 20);
292309 }
293310
294
-const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func = {
295
- .init = amdgpu_gtt_mgr_init,
296
- .takedown = amdgpu_gtt_mgr_fini,
297
- .get_node = amdgpu_gtt_mgr_new,
298
- .put_node = amdgpu_gtt_mgr_del,
311
+static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
312
+ .alloc = amdgpu_gtt_mgr_new,
313
+ .free = amdgpu_gtt_mgr_del,
299314 .debug = amdgpu_gtt_mgr_debug
300315 };