[PATCH v3 OLK-6.6] xsched: add xsched_{set,get}attr syscall
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ID9IFI ----------------------------------------- If CONFIG_CGROUP_XCU is not enabled, the xsched defaults to the RT scheduling class, and there is no interface available to configure the RT priority. Therefore, two new syscalls are added to set and get the configuration of the RT scheduling class. The default priority for RT is 4 (the lowest priority) in the kernel. In contrast, user-configured values work the opposity way: the smaller the value, the lower the priority. The child process inherits the priority configuration of the parent process during fork. If pid=0, it indicates that the configuration is applied to the current process. Additionally, an interface is reserved for configuring the xsched scheduling class, which will be used to support CFS in the future. Currently, these system calls are only available for ARM64 and x86_64 architectures. Fixes: 832ec54e11a0 ("xsched: Add xsched RT class") Signed-off-by: Liu Kai <liukai284@huawei.com> --- arch/arm/tools/syscall.tbl | 4 +- arch/powerpc/kernel/syscalls/syscall.tbl | 4 +- arch/x86/entry/syscalls/syscall_32.tbl | 4 +- arch/x86/entry/syscalls/syscall_64.tbl | 4 +- include/linux/sched.h | 8 ++ include/linux/syscalls.h | 3 + include/linux/xsched.h | 19 +--- include/linux/xsched_types.h | 27 ++++++ include/uapi/asm-generic/unistd.h | 8 +- init/init_task.c | 6 ++ kernel/fork.c | 3 + kernel/xsched/core.c | 79 +++++++++++++++ kernel/xsched/rt.c | 96 ++----------------- .../arch/powerpc/entry/syscalls/syscall.tbl | 4 +- .../arch/x86/entry/syscalls/syscall_64.tbl | 4 +- 15 files changed, 152 insertions(+), 121 deletions(-) create mode 100644 include/linux/xsched_types.h diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index 5127af69471c..c707bea6232b 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -480,5 +480,5 @@ 464 common kabi_reserved464 sys_ni_syscall 465 common kabi_reserved465 sys_ni_syscall 466 common kabi_reserved466 sys_ni_syscall -467 common kabi_reserved467 sys_ni_syscall -468 common kabi_reserved468 sys_ni_syscall +467 common xsched_setattr sys_ni_syscall +468 common xsched_getattr sys_ni_syscall diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index 3378482bcf6f..822e08438e2d 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -557,5 +557,5 @@ 464 common kabi_reserved464 sys_ni_syscall 465 common kabi_reserved465 sys_ni_syscall 466 common kabi_reserved466 sys_ni_syscall -467 common kabi_reserved467 sys_ni_syscall -468 common kabi_reserved468 sys_ni_syscall +467 common xsched_setattr sys_ni_syscall +468 common xsched_getattr sys_ni_syscall diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index e14ce1f6b1ec..d97a7da65e49 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -471,5 +471,5 @@ 464 i386 kabi_reserved464 sys_ni_syscall 465 i386 kabi_reserved465 sys_ni_syscall 466 i386 kabi_reserved466 sys_ni_syscall -467 i386 kabi_reserved467 sys_ni_syscall -468 i386 kabi_reserved468 sys_ni_syscall +467 i386 xsched_setattr sys_ni_syscall +468 i386 xsched_getattr sys_ni_syscall diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index 162517343cb1..a538ce360e7d 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -388,8 +388,8 @@ 464 common kabi_reserved464 sys_ni_syscall 465 common kabi_reserved465 sys_ni_syscall 466 common kabi_reserved466 sys_ni_syscall -467 common kabi_reserved467 sys_ni_syscall -468 common kabi_reserved468 sys_ni_syscall +467 common xsched_setattr sys_xsched_setattr +468 common xsched_getattr sys_xsched_getattr # # Due to a historical design error, certain syscalls are numbered differently diff --git a/include/linux/sched.h b/include/linux/sched.h index e0afdc2dad2c..bb23790fd2d3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -41,6 +41,10 @@ #include <linux/thread_bits.h> #include <linux/kabi.h> +#ifdef CONFIG_XCU_SCHEDULER +#include <linux/xsched_types.h> +#endif + /* task_struct member predeclarations (sorted alphabetically): */ struct audit_context; struct bio_list; @@ -776,6 +780,10 @@ struct kmap_ctrl { struct task_struct_resvd { /* pointer back to the main task_struct */ struct task_struct *task; + +#ifdef CONFIG_XCU_SCHEDULER + struct xsched_attr xse_attr; +#endif }; struct task_struct { diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 119aabc72a2d..2e7b2c57c8c0 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -950,6 +950,9 @@ asmlinkage long sys_cachestat(unsigned int fd, asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags); asmlinkage long sys_vstream_manage(struct vstream_args __user *arg, int cmd); + +asmlinkage long sys_xsched_setattr(pid_t pid, struct xsched_attr __user *arg); +asmlinkage long sys_xsched_getattr(pid_t pid, struct xsched_attr __user *arg); /* * Architecture-specific system calls */ diff --git a/include/linux/xsched.h b/include/linux/xsched.h index 38db18c0d570..60cb43b4631f 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -6,6 +6,7 @@ #include <linux/kref.h> #include <linux/vstream.h> #include <linux/xcu_group.h> +#include <linux/xsched_types.h> #ifndef pr_fmt #define pr_fmt(fmt) fmt @@ -53,20 +54,6 @@ extern struct xsched_cu *xsched_cu_mgr[XSCHED_NR_CUS]; -enum xcu_sched_type { - XSCHED_TYPE_RT = 0, - XSCHED_TYPE_CFS = 1, - XSCHED_TYPE_NUM, - XSCHED_TYPE_DFLT = XSCHED_TYPE_RT -}; - -enum xse_prio { - XSE_PRIO_HIGH = 0, - XSE_PRIO_LOW = 4, - NR_XSE_PRIO, - XSE_PRIO_DFLT = XSE_PRIO_LOW -}; - extern struct xsched_class rt_xsched_class; extern struct xsched_class fair_xsched_class; @@ -406,7 +393,7 @@ static inline u64 gcd(u64 a, u64 b) } struct xsched_class { - enum xcu_sched_type class_id; + enum xcu_sched_class class_id; size_t kick_slice; struct list_head node; @@ -456,7 +443,7 @@ int xsched_init_entity(struct xsched_context *ctx, struct vstream_info *vs); int ctx_bind_to_xcu(vstream_info_t *vstream_info, struct xsched_context *ctx); int xsched_vsm_add_tail(struct vstream_info *vs, vstream_args_t *arg); struct vstream_metadata *xsched_vsm_fetch_first(struct vstream_info *vs); -int xsched_rt_prio_set(pid_t tgid, unsigned int prio); +void xsched_rt_prio_set(pid_t tgid, unsigned int prio); void enqueue_ctx(struct xsched_entity *xse, struct xsched_cu *xcu); void dequeue_ctx(struct xsched_entity *xse, struct xsched_cu *xcu); int delete_ctx(struct xsched_context *ctx); diff --git a/include/linux/xsched_types.h b/include/linux/xsched_types.h new file mode 100644 index 000000000000..f52fe32d5198 --- /dev/null +++ b/include/linux/xsched_types.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _XSCHED_TYPE_H +#define _XSCHED_TYPE_H + +struct xsched_attr { + /* Scheduling class type, from enum xcu_sched_class */ + unsigned int xsched_class; + + /* RT scheduling priority, from enum xse_prio */ + unsigned int xsched_priority; +}; + +enum xcu_sched_class { + XSCHED_TYPE_RT = 0, + XSCHED_TYPE_CFS = 1, + XSCHED_TYPE_NUM, + XSCHED_TYPE_DFLT = XSCHED_TYPE_RT +}; + +enum xse_prio { + XSE_PRIO_HIGH = 0, + XSE_PRIO_LOW = 4, + NR_XSE_PRIO, + XSE_PRIO_DFLT = XSE_PRIO_LOW +}; + +#endif /* ! _XSCHED_TYPE_H */ diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index f015a3987255..154e0ecc946c 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -853,10 +853,10 @@ __SYSCALL(__NR_kabi_reserved464, sys_ni_syscall) __SYSCALL(__NR_kabi_reserved465, sys_ni_syscall) #define __NR_kabi_reserved466 466 __SYSCALL(__NR_kabi_reserved466, sys_ni_syscall) -#define __NR_kabi_reserved467 467 -__SYSCALL(__NR_kabi_reserved467, sys_ni_syscall) -#define __NR_kabi_reserved468 468 -__SYSCALL(__NR_kabi_reserved468, sys_ni_syscall) +#define __NR_xsched_setattr 467 +__SYSCALL(__NR_xsched_setattr, sys_xsched_setattr) +#define __NR_xsched_getattr 468 +__SYSCALL(__NR_xsched_getattr, sys_xsched_getattr) #undef __NR_syscalls #define __NR_syscalls 469 diff --git a/init/init_task.c b/init/init_task.c index 1adc17149558..61a6345708c8 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -14,6 +14,9 @@ #include <linux/scs.h> #include <linux/uaccess.h> +#ifdef CONFIG_XCU_SCHEDULER +#include <linux/xsched_types.h> +#endif static struct signal_struct init_signals = { .nr_threads = 1, @@ -59,6 +62,9 @@ unsigned long init_shadow_call_stack[SCS_SIZE / sizeof(long)] static struct task_struct_resvd init_task_struct_resvd = { .task = &init_task, +#ifdef CONFIG_XCU_SCHEDULER + .xse_attr = { .xsched_priority = XSE_PRIO_DFLT }, +#endif }; /* diff --git a/kernel/fork.c b/kernel/fork.c index 328bbf6a36d2..f3c663602345 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1165,6 +1165,9 @@ static bool dup_resvd_task_struct(struct task_struct *dst, return false; dst->_resvd->task = dst; +#ifdef CONFIG_XCU_SCHEDULER + dst->_resvd->xse_attr = orig->_resvd->xse_attr; +#endif return true; } diff --git a/kernel/xsched/core.c b/kernel/xsched/core.c index 69f1a442f985..b23f2ca7820b 100644 --- a/kernel/xsched/core.c +++ b/kernel/xsched/core.c @@ -20,6 +20,7 @@ #include <linux/kthread.h> #include <linux/slab.h> #include <linux/spinlock_types.h> +#include <linux/syscalls.h> #include <linux/types.h> #include <linux/xsched.h> @@ -533,3 +534,81 @@ __init int xsched_sched_init(void) } late_initcall(xsched_sched_init); +static int xsched_setattr(struct task_struct *p, const struct xsched_attr *attr) +{ + struct xsched_attr *old_attr = &p->_resvd->xse_attr; + + if (old_attr->xsched_class == attr->xsched_class && + old_attr->xsched_priority == attr->xsched_priority) + return 0; + + old_attr->xsched_class = attr->xsched_class; + old_attr->xsched_priority = attr->xsched_priority; + xsched_rt_prio_set(p->pid, old_attr->xsched_priority); + + return 0; +} + +SYSCALL_DEFINE2(xsched_setattr, pid_t, pid, struct xsched_attr __user *, arg) +{ + struct xsched_attr kattr; + struct task_struct *p; + int rt_prio, retval; + + if (pid < 0 || !arg) + return -EINVAL; + + if (copy_from_user(&kattr, arg, sizeof(*arg))) { + XSCHED_ERR("Fail to copy_from_user @ %s\n", __func__); + return -EFAULT; + } + + rt_prio = NR_XSE_PRIO - kattr.xsched_priority; + /* Only support RT */ + if (rt_prio < XSE_PRIO_HIGH || rt_prio > XSE_PRIO_LOW || + kattr.xsched_class != XSCHED_TYPE_RT) + return -EINVAL; + + kattr.xsched_priority = rt_prio; + + rcu_read_lock(); + retval = -ESRCH; + p = pid ? find_task_by_vpid(pid) : current; + if (likely(p)) + get_task_struct(p); + rcu_read_unlock(); + + if (likely(p)) { + retval = xsched_setattr(p, &kattr); + put_task_struct(p); + } + + return retval; +} + +SYSCALL_DEFINE2(xsched_getattr, pid_t, pid, struct xsched_attr __user *, arg) +{ + struct xsched_attr kattr = { }; + struct task_struct *p; + + if (pid < 0 || !arg) + return -EINVAL; + + rcu_read_lock(); + p = pid ? find_task_by_vpid(pid) : current; + if (!p) { + rcu_read_unlock(); + return -ESRCH; + } + kattr = p->_resvd->xse_attr; + rcu_read_unlock(); + + kattr.xsched_priority = NR_XSE_PRIO - kattr.xsched_priority; + + if (copy_to_user(arg, &kattr, sizeof(kattr))) { + XSCHED_ERR("Fail to copy_to_user @ %s\n", __func__); + return -EFAULT; + } + + return 0; +} diff --git a/kernel/xsched/rt.c b/kernel/xsched/rt.c index 41b60e341679..e2ce1ebb8a7a 100644 --- a/kernel/xsched/rt.c +++ b/kernel/xsched/rt.c @@ -25,76 +25,6 @@ #define XSCHED_RT_TIMESLICE (10 * NSEC_PER_MSEC) -#define TGID_HASH_BITS 8 - -/* Mapping between tgid and context */ -struct tgid_prio { - pid_t tgid; - int32_t prio; - struct hlist_node hnode; -}; - -static DEFINE_HASHTABLE(tgid_prio_map, TGID_HASH_BITS); -static DEFINE_SPINLOCK(tgid_prio_lock); - -static int tgid_prio_insert(pid_t tgid, int32_t prio) -{ - struct tgid_prio *new_map; - unsigned int hash_key; - - if (prio >= NR_XSE_PRIO) - return -EINVAL; - - new_map = kzalloc(sizeof(struct tgid_prio), GFP_KERNEL); - if (!new_map) { - XSCHED_ERR("Fail to alloc mapping (tgid=%d) @ %s\n", - tgid, __func__); - return -ENOMEM; - } - - new_map->tgid = tgid; - new_map->prio = prio; - - hash_key = hash_32(tgid, TGID_HASH_BITS); - - spin_lock(&tgid_prio_lock); - hash_add_rcu(tgid_prio_map, &new_map->hnode, hash_key); - spin_unlock(&tgid_prio_lock); - - return 0; -} - -static struct tgid_prio *tgid_prio_find(pid_t tgid) -{ - struct tgid_prio *map = NULL; - unsigned int hash_key = hash_32(tgid, TGID_HASH_BITS); - - rcu_read_lock(); - hash_for_each_possible_rcu(tgid_prio_map, map, hnode, hash_key) { - if (map->tgid == tgid) - break; - } - rcu_read_unlock(); - return map; -} - -static void tgid_prio_delete(pid_t tgid) -{ - struct tgid_prio *map; - unsigned int hash_key = hash_32(tgid, TGID_HASH_BITS); - - spin_lock(&tgid_prio_lock); - hash_for_each_possible(tgid_prio_map, map, hnode, hash_key) { - if (map->tgid == tgid) { - hash_del_rcu(&map->hnode); - spin_unlock(&tgid_prio_lock); - kfree(map); - return; - } - } - spin_unlock(&tgid_prio_lock); -} - static inline void xse_rt_add(struct xsched_entity *xse, struct xsched_cu *xcu) { @@ -115,7 +45,7 @@ static inline void xse_rt_move_tail(struct xsched_entity *xse) /* Increase RT runqueue total and per prio nr_running stat. */ static inline void xrq_inc_nr_running(struct xsched_entity *xse, - struct xsched_cu *xcu) + struct xsched_cu *xcu) { xcu->xrq.rt.nr_running++; } @@ -143,7 +73,7 @@ static void enqueue_ctx_rt(struct xsched_entity *xse, struct xsched_cu *xcu) } static inline struct xsched_entity *xrq_next_xse(struct xsched_cu *xcu, - int prio) + int prio) { return list_first_entry(&xcu->xrq.rt.rq[prio], struct xsched_entity, rt.list_node); @@ -217,23 +147,16 @@ void rq_init_rt(struct xsched_cu *xcu) void xse_init_rt(struct xsched_entity *xse) { - struct tgid_prio *map = tgid_prio_find(xse->tgid); + struct task_struct *p; - xse->rt.prio = (map) ? map->prio : XSE_PRIO_DFLT; + p = find_task_by_vpid(xse->tgid); + xse->rt.prio = p->_resvd->xse_attr.xsched_priority; XSCHED_DEBUG("Xse init: set priority=%d.\n", xse->rt.prio); xse->rt.timeslice = XSCHED_RT_TIMESLICE; INIT_LIST_HEAD(&xse->rt.list_node); } -void xse_deinit_rt(struct xsched_entity *xse) -{ - struct tgid_prio *map = tgid_prio_find(xse->tgid); - - if (map) { - tgid_prio_delete(xse->tgid); - XSCHED_DEBUG("Map deleted: tgid=%d\n", xse->tgid); - } -} +void xse_deinit_rt(struct xsched_entity *xse) { } struct xsched_class rt_xsched_class = { .class_id = XSCHED_TYPE_RT, @@ -248,16 +171,13 @@ struct xsched_class rt_xsched_class = { .check_preempt = check_preempt_ctx_rt }; -int xsched_rt_prio_set(pid_t tgid, unsigned int prio) +void xsched_rt_prio_set(pid_t tgid, unsigned int prio) { unsigned int id; struct xsched_cu *xcu; struct xsched_context *ctx; struct xsched_entity *xse; - tgid_prio_delete(tgid); - tgid_prio_insert(tgid, prio); - for_each_active_xcu(xcu, id) { mutex_lock(&xcu->ctx_list_lock); mutex_lock(&xcu->xcu_lock); @@ -275,7 +195,5 @@ int xsched_rt_prio_set(pid_t tgid, unsigned int prio) mutex_unlock(&xcu->xcu_lock); mutex_unlock(&xcu->ctx_list_lock); } - - return 0; } diff --git a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl index 4d76d8970013..8ed79b4b20e3 100644 --- a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl @@ -553,5 +553,5 @@ 464 common kabi_reserved464 sys_ni_syscall 465 common kabi_reserved465 sys_ni_syscall 466 common kabi_reserved466 sys_ni_syscall -467 common kabi_reserved467 sys_ni_syscall -468 common kabi_reserved468 sys_ni_syscall +467 common xsched_setattr sys_ni_syscall +468 common xsched_getattr sys_ni_syscall diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl index 65004179e548..9cc0623ee8e5 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl @@ -388,8 +388,8 @@ 464 common kabi_reserved464 sys_ni_syscall 465 common kabi_reserved465 sys_ni_syscall 466 common kabi_reserved466 sys_ni_syscall -467 common kabi_reserved467 sys_ni_syscall -468 common kabi_reserved468 sys_ni_syscall +467 common xsched_setattr sys_ni_syscall +468 common xsched_getattr sys_ni_syscall # # Due to a historical design error, certain syscalls are numbered differently -- 2.34.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/19390 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/2IA... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/19390 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/2IA...
participants (2)
-
Liu Kai -
patchwork bot