0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <drm/ttm/ttm_range_manager.h>
0026
0027 #include "amdgpu.h"
0028
0029 static inline struct amdgpu_gtt_mgr *
0030 to_gtt_mgr(struct ttm_resource_manager *man)
0031 {
0032 return container_of(man, struct amdgpu_gtt_mgr, manager);
0033 }
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 static ssize_t amdgpu_mem_info_gtt_total_show(struct device *dev,
0044 struct device_attribute *attr,
0045 char *buf)
0046 {
0047 struct drm_device *ddev = dev_get_drvdata(dev);
0048 struct amdgpu_device *adev = drm_to_adev(ddev);
0049 struct ttm_resource_manager *man;
0050
0051 man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
0052 return sysfs_emit(buf, "%llu\n", man->size);
0053 }
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 static ssize_t amdgpu_mem_info_gtt_used_show(struct device *dev,
0064 struct device_attribute *attr,
0065 char *buf)
0066 {
0067 struct drm_device *ddev = dev_get_drvdata(dev);
0068 struct amdgpu_device *adev = drm_to_adev(ddev);
0069 struct ttm_resource_manager *man = &adev->mman.gtt_mgr.manager;
0070
0071 return sysfs_emit(buf, "%llu\n", ttm_resource_manager_usage(man));
0072 }
0073
0074 static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO,
0075 amdgpu_mem_info_gtt_total_show, NULL);
0076 static DEVICE_ATTR(mem_info_gtt_used, S_IRUGO,
0077 amdgpu_mem_info_gtt_used_show, NULL);
0078
0079 static struct attribute *amdgpu_gtt_mgr_attributes[] = {
0080 &dev_attr_mem_info_gtt_total.attr,
0081 &dev_attr_mem_info_gtt_used.attr,
0082 NULL
0083 };
0084
0085 const struct attribute_group amdgpu_gtt_mgr_attr_group = {
0086 .attrs = amdgpu_gtt_mgr_attributes
0087 };
0088
0089
0090
0091
0092
0093
0094
0095
0096 bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *res)
0097 {
0098 struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(res);
0099
0100 return drm_mm_node_allocated(&node->mm_nodes[0]);
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
0114 struct ttm_buffer_object *tbo,
0115 const struct ttm_place *place,
0116 struct ttm_resource **res)
0117 {
0118 struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
0119 uint32_t num_pages = PFN_UP(tbo->base.size);
0120 struct ttm_range_mgr_node *node;
0121 int r;
0122
0123 node = kzalloc(struct_size(node, mm_nodes, 1), GFP_KERNEL);
0124 if (!node)
0125 return -ENOMEM;
0126
0127 ttm_resource_init(tbo, place, &node->base);
0128 if (!(place->flags & TTM_PL_FLAG_TEMPORARY) &&
0129 ttm_resource_manager_usage(man) > man->size) {
0130 r = -ENOSPC;
0131 goto err_free;
0132 }
0133
0134 if (place->lpfn) {
0135 spin_lock(&mgr->lock);
0136 r = drm_mm_insert_node_in_range(&mgr->mm, &node->mm_nodes[0],
0137 num_pages, tbo->page_alignment,
0138 0, place->fpfn, place->lpfn,
0139 DRM_MM_INSERT_BEST);
0140 spin_unlock(&mgr->lock);
0141 if (unlikely(r))
0142 goto err_free;
0143
0144 node->base.start = node->mm_nodes[0].start;
0145 } else {
0146 node->mm_nodes[0].start = 0;
0147 node->mm_nodes[0].size = node->base.num_pages;
0148 node->base.start = AMDGPU_BO_INVALID_OFFSET;
0149 }
0150
0151 *res = &node->base;
0152 return 0;
0153
0154 err_free:
0155 ttm_resource_fini(man, &node->base);
0156 kfree(node);
0157 return r;
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man,
0169 struct ttm_resource *res)
0170 {
0171 struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(res);
0172 struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
0173
0174 spin_lock(&mgr->lock);
0175 if (drm_mm_node_allocated(&node->mm_nodes[0]))
0176 drm_mm_remove_node(&node->mm_nodes[0]);
0177 spin_unlock(&mgr->lock);
0178
0179 ttm_resource_fini(man, res);
0180 kfree(node);
0181 }
0182
0183
0184
0185
0186
0187
0188
0189
0190 void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
0191 {
0192 struct ttm_range_mgr_node *node;
0193 struct drm_mm_node *mm_node;
0194 struct amdgpu_device *adev;
0195
0196 adev = container_of(mgr, typeof(*adev), mman.gtt_mgr);
0197 spin_lock(&mgr->lock);
0198 drm_mm_for_each_node(mm_node, &mgr->mm) {
0199 node = container_of(mm_node, typeof(*node), mm_nodes[0]);
0200 amdgpu_ttm_recover_gart(node->base.bo);
0201 }
0202 spin_unlock(&mgr->lock);
0203
0204 amdgpu_gart_invalidate_tlb(adev);
0205 }
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man,
0216 struct drm_printer *printer)
0217 {
0218 struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
0219
0220 spin_lock(&mgr->lock);
0221 drm_mm_print(&mgr->mm, printer);
0222 spin_unlock(&mgr->lock);
0223 }
0224
0225 static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
0226 .alloc = amdgpu_gtt_mgr_new,
0227 .free = amdgpu_gtt_mgr_del,
0228 .debug = amdgpu_gtt_mgr_debug
0229 };
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
0240 {
0241 struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
0242 struct ttm_resource_manager *man = &mgr->manager;
0243 uint64_t start, size;
0244
0245 man->use_tt = true;
0246 man->func = &amdgpu_gtt_mgr_func;
0247
0248 ttm_resource_manager_init(man, &adev->mman.bdev, gtt_size);
0249
0250 start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
0251 size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
0252 drm_mm_init(&mgr->mm, start, size);
0253 spin_lock_init(&mgr->lock);
0254
0255 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager);
0256 ttm_resource_manager_set_used(man, true);
0257 return 0;
0258 }
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 void amdgpu_gtt_mgr_fini(struct amdgpu_device *adev)
0269 {
0270 struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
0271 struct ttm_resource_manager *man = &mgr->manager;
0272 int ret;
0273
0274 ttm_resource_manager_set_used(man, false);
0275
0276 ret = ttm_resource_manager_evict_all(&adev->mman.bdev, man);
0277 if (ret)
0278 return;
0279
0280 spin_lock(&mgr->lock);
0281 drm_mm_takedown(&mgr->mm);
0282 spin_unlock(&mgr->lock);
0283
0284 ttm_resource_manager_cleanup(man);
0285 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, NULL);
0286 }