
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> Signed-off-by: Xia Fukun <xiafukun@huawei.com> --- include/linux/vstream.h | 28 ++++++++++++++++++++++++ include/linux/xsched.h | 15 +++++++++++++ kernel/xsched/core.c | 25 +++++++++++++++++++++ kernel/xsched/vstream.c | 48 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/include/linux/vstream.h b/include/linux/vstream.h index ca956ac2cf4f..58ee4c235a07 100644 --- a/include/linux/vstream.h +++ b/include/linux/vstream.h @@ -3,6 +3,34 @@ #define _LINUX_VSTREAM_H #include <uapi/linux/xcu_vstream.h> +#include <linux/ktime.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; + + /* Time of list insertion */ + ktime_t add_time; +} vstream_metadata_t; typedef struct vstream_info { uint32_t user_stream_id; diff --git a/include/linux/xsched.h b/include/linux/xsched.h index 702483b85621..7a25d2a7455b 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -135,6 +135,18 @@ static inline struct xsched_context *ctx_find_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_xcu_register(struct xcu_group *group); void xsched_task_free(struct kref *kref); int xsched_ctx_init_xse(struct xsched_context *ctx, struct vstream_info *vs); @@ -142,4 +154,7 @@ int ctx_bind_to_xcu(vstream_info_t *vstream_info, struct xsched_context *ctx); int vstream_bind_to_xcu(vstream_info_t *vstream_info); struct xsched_cu *xcu_find(uint32_t *type, uint32_t dev_id, uint32_t 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 bcc305c8df7b..5b83410c8b07 100644 --- a/kernel/xsched/core.c +++ b/kernel/xsched/core.c @@ -161,6 +161,31 @@ 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) +{ + struct vstream_metadata *new_vsm; + + new_vsm = kmalloc(sizeof(struct vstream_metadata), GFP_KERNEL); + if (!new_vsm) { + XSCHED_ERR("Failed to alloc kick metadata for vs %u @ %s\n", + vs->id, __func__); + return -ENOMEM; + } + + if (vs->kicks_count > MAX_VSTREAM_SIZE) { + kfree(new_vsm); + return -EBUSY; + } + + xsched_init_vsm(new_vsm, vs, arg); + list_add_tail(&new_vsm->node, &vs->metadata_list); + new_vsm->add_time = ktime_get(); + vs->kicks_count += 1; + + return 0; +} + /* * Initialize and register xcu in xcu_manager array. */ diff --git a/kernel/xsched/vstream.c b/kernel/xsched/vstream.c index b06eb4e22335..0c37abb4ff50 100644 --- a/kernel/xsched/vstream.c +++ b/kernel/xsched/vstream.c @@ -401,7 +401,53 @@ int vstream_free(struct vstream_args *arg) int vstream_kick(struct vstream_args *arg) { - return 0; + vstream_info_t *vstream; + int vstream_id = arg->sq_id; + struct xsched_entity *xse; + int err = 0; + + struct xsched_cu *xcu = NULL; + + XSCHED_CALL_STUB(); + + /* Get vstream. */ + vstream = vstream_get(vstream_id); + if (!vstream || !vstream->ctx) { + XSCHED_ERR("Vstream NULL or doesn't have a context.\n"); + return -EINVAL; + } + + xse = &vstream->ctx->xse; + xcu = vstream->xcu; + XSCHED_DEBUG("New kick on xse %d @ %s\n", xse->tgid, __func__); + + do { + mutex_lock(&xcu->xcu_lock); + spin_lock(&vstream->stream_lock); + + /* Adding kick metadata. */ + err = xsched_vsm_add_tail(vstream, arg); + if (err == -EBUSY) { + spin_unlock(&vstream->stream_lock); + mutex_unlock(&xcu->xcu_lock); + + /* Retry after a while */ + usleep_range(100, 200); + continue; + } + + /* Don't forget to unlock */ + if (err) { + XSCHED_ERR("Fail to add kick metadata to vs %u @ %s\n", + vstream->id, __func__); + break; + } + } while (err == -EBUSY); + + spin_unlock(&vstream->stream_lock); + mutex_unlock(&xcu->xcu_lock); + + return err; } /* -- 2.34.1