
From: Konstantin Meskhidze <konstantin.meskhidze@huawei.com> hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC5EHB ----------------------------------------- Add vstream_metadata data structures. Add vstream_kick() and xcu_run() implementation. Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com> Signed-off-by: Hui Tang <tanghui20@.huawei.com> Signed-off-by: Liu Kai <liukai284@huawei.com> --- include/linux/vstream.h | 24 ++++++++++++++++++ include/linux/xsched.h | 16 ++++++++++++ kernel/xsched/core.c | 32 +++++++++++++++++++++++ kernel/xsched/vstream.c | 56 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 127 insertions(+), 1 deletion(-) diff --git a/include/linux/vstream.h b/include/linux/vstream.h index 39cc6a26db50..8e7bf5992898 100644 --- a/include/linux/vstream.h +++ b/include/linux/vstream.h @@ -4,6 +4,30 @@ #include <uapi/linux/xcu_vstream.h> +#define MAX_VSTREAM_SIZE 2048 + +/* Vstream metadata describes each incoming kick + * that gets stored into a list of pending kicks + * inside a vstream to keep track of what is left + * to be processed by a driver. + */ +typedef struct vstream_metadata { + uint32_t exec_time; + /* A value of SQ tail that has been passed with the + * kick that is described by this exact metadata object. + */ + uint32_t sq_tail; + uint32_t sqe_num; + uint32_t sq_id; + int32_t timeout; + int8_t sqe[XCU_SQE_SIZE_MAX]; + + /* A node for metadata list */ + struct list_head node; + + struct vstream_info *parent; +} vstream_metadata_t; + typedef struct vstream_info { uint32_t user_streamId; uint32_t id; diff --git a/include/linux/xsched.h b/include/linux/xsched.h index 15c67bb1ac95..902f4a4fba34 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -156,10 +156,26 @@ static inline struct xsched_context *find_ctx_by_tgid(pid_t tgid) return ret; } + +static inline void xsched_init_vsm(struct vstream_metadata *vsm, + struct vstream_info *vs, + vstream_args_t *arg) +{ + vsm->sq_id = arg->sq_id; + vsm->sqe_num = arg->vk_args.sqe_num; + vsm->timeout = arg->vk_args.timeout; + memcpy(vsm->sqe, arg->vk_args.sqe, XCU_SQE_SIZE_MAX); + vsm->parent = vs; + INIT_LIST_HEAD(&vsm->node); +} + int xsched_register_xcu(struct xcu_group *group); void xsched_free_task(struct kref *kref); int xsched_ctx_init_xse(struct xsched_context *ctx, struct vstream_info *vs); int bind_ctx_to_xcu(vstream_info_t *vstream_info, struct xsched_context *ctx); int bind_vstream_to_xcu(vstream_info_t *vstream_info); struct xsched_cu *xcu_find(__u32 *type, __u32 devId, __u32 channel_id); + +/* Vstream metadata proccesing functions.*/ +int xsched_vsm_add_tail(struct vstream_info *vs, vstream_args_t *arg); #endif /* !__LINUX_XSCHED_H__ */ diff --git a/kernel/xsched/core.c b/kernel/xsched/core.c index 98f412c1ca7b..8e531297d4c5 100644 --- a/kernel/xsched/core.c +++ b/kernel/xsched/core.c @@ -176,6 +176,38 @@ static int alloc_xcu_id(void) return xcu_id; } +/* Adds vstream_metadata object to a specified vstream. */ +int xsched_vsm_add_tail(struct vstream_info *vs, vstream_args_t *arg) +{ + int err = 0; + struct vstream_metadata *new_vsm; + + new_vsm = kmalloc(sizeof(struct vstream_metadata), GFP_KERNEL); + if (!new_vsm) { + XSCHED_ERR("Failed to allocate kick metadata for vs %u @ %s\n", + vs->id, __func__); + err = -ENOMEM; + goto out_err; + } + + xsched_init_vsm(new_vsm, vs, arg); + + if (vs->kicks_count > MAX_VSTREAM_SIZE) { + err = -EBUSY; + kfree(new_vsm); + goto out_err; + } + + list_add_tail(&new_vsm->node, &vs->metadata_list); + vs->kicks_count += 1; + + XSCHED_INFO("Vstream_id %u Add vsm: sq_tail %u, sqe_num %u, kicks_count %u\n", + vs->id, new_vsm->sq_tail, new_vsm->sqe_num, vs->kicks_count); + +out_err: + return err; +} + /* * Initialize and register xcu in xcu_manager array. */ diff --git a/kernel/xsched/vstream.c b/kernel/xsched/vstream.c index 30f8073593ab..1d1b4e436f69 100644 --- a/kernel/xsched/vstream.c +++ b/kernel/xsched/vstream.c @@ -468,7 +468,61 @@ int vstream_free(struct vstream_args *arg) int vstream_kick(struct vstream_args *arg) { - return 0; + vstream_info_t *vstream; + int vstreamId = arg->sq_id; + struct xsched_entity *xse; + int err = 0; + + struct xsched_cu *xcu = NULL; + + XSCHED_CALL_STUB(); + + /* Get vstream. */ + vstream = vstream_get(vstreamId); + if (!vstream || !vstream->ctx) { + XSCHED_ERR( + "Vstream NULL or doesn't have a context.\n"); + err = -EINVAL; + goto out_err; + } + + xse = &vstream->ctx->xse; + xcu = vstream->xcu; + XSCHED_INFO("New kick on xse %d @ %s\n", xse->tgid, __func__); + +repeat_kick: + mutex_lock(&xcu->xcu_lock); + XSCHED_INFO("xcu lock taken @ %s\n", __func__); + spin_lock(&vstream->stream_lock); + XSCHED_INFO("vstream lock taken @ %s\n", __func__); + + /* Adding kick metadata. */ + err = xsched_vsm_add_tail(vstream, arg); + if (err) { + if (err == -EBUSY) { + spin_unlock(&vstream->stream_lock); + XSCHED_INFO("no space: vstream lock released @ %s\n", __func__); + mutex_unlock(&xcu->xcu_lock); + goto repeat_kick; + } + XSCHED_ERR("Failed to add kick metadata to vs %u @ %s\n", + vstream->id, __func__); + + spin_unlock(&vstream->stream_lock); + XSCHED_INFO("vstream lock released @ %s\n", __func__); + mutex_unlock(&xcu->xcu_lock); + XSCHED_INFO("Xcu lock released @ %s\n", __func__); + goto out_err; + } + + spin_unlock(&vstream->stream_lock); + XSCHED_INFO("vstream lock released @ %s\n", __func__); + mutex_unlock(&xcu->xcu_lock); + +out_err: + XSCHED_EXIT_STUB(); + + return err; } /* -- 2.34.1