From: Alexander Pavlenko <pavlenko.alexander@huawei.com> hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/8424 ---------------------------------------- This commit enforces a strict teardown order when releasing memory associated with an XPU device: the device memory (dmem) region must first be unregistered from the xsched subsystem before the underlying physical memory is deallocated. Signed-off-by: Alexander Pavlenko <pavlenko.alexander@huawei.com> Signed-off-by: Liu Kai <liukai284@huawei.com> --- include/linux/xsched.h | 1 + include/uapi/linux/xsched/xcu_vstream.h | 1 + kernel/xsched/dmem.c | 29 +++++++++++++++++++++++++ kernel/xsched/vstream.c | 26 ++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/include/linux/xsched.h b/include/linux/xsched.h index d635ecc516c7..bb29d9243e97 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -520,6 +520,7 @@ int xsched_dmem_register_region(uint64_t size, int dev_id); void xsched_dmem_unregister_region(int dev_id); bool xsched_dmem_used(void); int xsched_dmem_alloc(struct xsched_context *ctx, struct vstream_args *args); +int xsched_dmem_free(struct xsched_context *ctx, struct vstream_args *args); #endif #endif /* !__LINUX_XSCHED_H__ */ diff --git a/include/uapi/linux/xsched/xcu_vstream.h b/include/uapi/linux/xsched/xcu_vstream.h index d4cfa3cf0591..54c5efb63d53 100644 --- a/include/uapi/linux/xsched/xcu_vstream.h +++ b/include/uapi/linux/xsched/xcu_vstream.h @@ -23,6 +23,7 @@ typedef enum VSTREAM_COMMAND { VSTREAM_FREE, VSTREAM_KICK, VSTREAM_HBM_ALLOC, + VSTREAM_HBM_FREE, MAX_COMMAND } vstream_command_t; diff --git a/kernel/xsched/dmem.c b/kernel/xsched/dmem.c index 7691cfb2f1b9..ec78604c3042 100644 --- a/kernel/xsched/dmem.c +++ b/kernel/xsched/dmem.c @@ -173,3 +173,32 @@ int xsched_dmem_alloc(struct xsched_context *ctx, struct vstream_args *args) error_out: return ret; } + +int xsched_dmem_free(struct xsched_context *ctx, struct vstream_args *args) +{ + struct xsched_dmem_pool *pool, *target = NULL; + uint64_t addr = args->vm_args.addr; + + if (!xsched_dmem_used()) + return -EPERM; + + spin_lock(&ctx->ctx_lock); + list_for_each_entry(pool, &ctx->pool_list, pool_node) { + if (pool->addr == addr) { + list_del(&pool->pool_node); + target = pool; + break; + } + } + spin_unlock(&ctx->ctx_lock); + + if (!target) + return -ENOENT; + + XSCHED_DEBUG("uncharged %llu bytes for pool = %p with addr %llu\n", + target->size, target, target->addr); + dmem_cgroup_uncharge(target->pool, target->size); + kfree(target); + + return 0; +} diff --git a/kernel/xsched/vstream.c b/kernel/xsched/vstream.c index 89586c876fec..593a2a3519d0 100644 --- a/kernel/xsched/vstream.c +++ b/kernel/xsched/vstream.c @@ -672,8 +672,33 @@ static int vstream_hbm_alloc(struct vstream_args *arg) return xsched_dmem_alloc(ctx, arg); } + +static int vstream_hbm_free(struct vstream_args *arg) +{ + struct xsched_cu *xcu_found; + struct xsched_context *ctx; + + if (!dmem_cgroup_enabled()) + return -EPERM; + + xcu_found = xcu_find(XCU_TYPE_XPU, arg->dev_id, arg->channel_id); + if (!xcu_found) + return -EINVAL; + + mutex_lock(&xcu_found->ctx_list_lock); + ctx = ctx_find_by_tgid_and_xcu(current->tgid, xcu_found); + mutex_unlock(&xcu_found->ctx_list_lock); + + if (!ctx) { + XSCHED_ERR("Failed to find a context for HBM free"); + return -ENOENT; + } + + return xsched_dmem_free(ctx, arg); +} #else static int vstream_hbm_alloc(struct vstream_args *arg) { return -EOPNOTSUPP; } +static int vstream_hbm_free(struct vstream_args *arg) { return -EOPNOTSUPP; } #endif /* CONFIG_CGROUP_DMEM */ /* @@ -684,6 +709,7 @@ static vstream_manage_t(*vstream_command_table[MAX_COMMAND + 1]) = { vstream_free, // VSTREAM_FREE vstream_kick, // VSTREAM_KICK vstream_hbm_alloc, // VSTREAM_HBM_ALLOC + vstream_hbm_free, // VSTREAM_HBM_FREE NULL // MAX_COMMAND }; -- 2.34.1