122 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2021-2022 Intel Corporation4 * Copyright (C) 2021-2002 Red Hat5 */6 7#include "xe_ttm_sys_mgr.h"8 9#include <drm/drm_managed.h>10 11#include <drm/ttm/ttm_placement.h>12#include <drm/ttm/ttm_range_manager.h>13#include <drm/ttm/ttm_tt.h>14 15#include "xe_bo.h"16#include "xe_gt.h"17 18struct xe_ttm_sys_node {19 struct ttm_buffer_object *tbo;20 struct ttm_range_mgr_node base;21};22 23static inline struct xe_ttm_sys_node *24to_xe_ttm_sys_node(struct ttm_resource *res)25{26 return container_of(res, struct xe_ttm_sys_node, base.base);27}28 29static int xe_ttm_sys_mgr_new(struct ttm_resource_manager *man,30 struct ttm_buffer_object *tbo,31 const struct ttm_place *place,32 struct ttm_resource **res)33{34 struct xe_ttm_sys_node *node;35 int r;36 37 node = kzalloc(struct_size(node, base.mm_nodes, 1), GFP_KERNEL);38 if (!node)39 return -ENOMEM;40 41 node->tbo = tbo;42 ttm_resource_init(tbo, place, &node->base.base);43 44 if (!(place->flags & TTM_PL_FLAG_TEMPORARY) &&45 ttm_resource_manager_usage(man) > (man->size << PAGE_SHIFT)) {46 r = -ENOSPC;47 goto err_fini;48 }49 50 node->base.mm_nodes[0].start = 0;51 node->base.mm_nodes[0].size = PFN_UP(node->base.base.size);52 node->base.base.start = XE_BO_INVALID_OFFSET;53 54 *res = &node->base.base;55 56 return 0;57 58err_fini:59 ttm_resource_fini(man, &node->base.base);60 kfree(node);61 return r;62}63 64static void xe_ttm_sys_mgr_del(struct ttm_resource_manager *man,65 struct ttm_resource *res)66{67 struct xe_ttm_sys_node *node = to_xe_ttm_sys_node(res);68 69 ttm_resource_fini(man, res);70 kfree(node);71}72 73static void xe_ttm_sys_mgr_debug(struct ttm_resource_manager *man,74 struct drm_printer *printer)75{76 /*77 * This function is called by debugfs entry and would require78 * pm_runtime_{get,put} wrappers around any operation.79 */80}81 82static const struct ttm_resource_manager_func xe_ttm_sys_mgr_func = {83 .alloc = xe_ttm_sys_mgr_new,84 .free = xe_ttm_sys_mgr_del,85 .debug = xe_ttm_sys_mgr_debug86};87 88static void ttm_sys_mgr_fini(struct drm_device *drm, void *arg)89{90 struct xe_device *xe = (struct xe_device *)arg;91 struct ttm_resource_manager *man = &xe->mem.sys_mgr;92 int err;93 94 ttm_resource_manager_set_used(man, false);95 96 err = ttm_resource_manager_evict_all(&xe->ttm, man);97 if (err)98 return;99 100 ttm_resource_manager_cleanup(man);101 ttm_set_driver_manager(&xe->ttm, XE_PL_TT, NULL);102}103 104int xe_ttm_sys_mgr_init(struct xe_device *xe)105{106 struct ttm_resource_manager *man = &xe->mem.sys_mgr;107 struct sysinfo si;108 u64 gtt_size;109 110 si_meminfo(&si);111 gtt_size = (u64)si.totalram * si.mem_unit;112 /* TTM limits allocation of all TTM devices by 50% of system memory */113 gtt_size /= 2;114 115 man->use_tt = true;116 man->func = &xe_ttm_sys_mgr_func;117 ttm_resource_manager_init(man, &xe->ttm, gtt_size >> PAGE_SHIFT);118 ttm_set_driver_manager(&xe->ttm, XE_PL_TT, man);119 ttm_resource_manager_set_used(man, true);120 return drmm_add_action_or_reset(&xe->drm, ttm_sys_mgr_fini, xe);121}122