hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ID9IFI ----------------------------------------- If CONFIG_XCU_CGROUP is not enabled, the xsched kernel defaults to only 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), and it 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. 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 | 11 +++ include/linux/syscalls.h | 3 + include/linux/xsched.h | 17 +--- 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 | 74 ++++++++++++++ kernel/xsched/rt.c | 96 ++----------------- .../arch/powerpc/entry/syscalls/syscall.tbl | 4 +- .../arch/x86/entry/syscalls/syscall_64.tbl | 4 +- 15 files changed, 149 insertions(+), 120 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..9c04d1625193 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -468,8 +468,8 @@ 452 common fchmodat2 sys_fchmodat2 453 common map_shadow_stack sys_map_shadow_stack 454 common vstream_manage sys_ni_syscall -455 common kabi_reserved455 sys_ni_syscall -456 common kabi_reserved456 sys_ni_syscall +455 common xsched_setattr sys_ni_syscall +456 common xsched_getattr sys_ni_syscall 457 common kabi_reserved457 sys_ni_syscall 458 common kabi_reserved458 sys_ni_syscall 459 common kabi_reserved459 sys_ni_syscall diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index 3378482bcf6f..086f8d3e8c12 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -545,8 +545,8 @@ 452 common fchmodat2 sys_fchmodat2 453 common map_shadow_stack sys_ni_syscall 454 common vstream_manage sys_ni_syscall -455 common kabi_reserved455 sys_ni_syscall -456 common kabi_reserved456 sys_ni_syscall +455 common xsched_setattr sys_ni_syscall +456 common xsched_getattr sys_ni_syscall 457 common kabi_reserved457 sys_ni_syscall 458 common kabi_reserved458 sys_ni_syscall 459 common kabi_reserved459 sys_ni_syscall diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index e14ce1f6b1ec..90d4cd7dfe28 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -459,8 +459,8 @@ 452 i386 fchmodat2 sys_fchmodat2 453 i386 map_shadow_stack sys_map_shadow_stack 454 i386 vstream_manage sys_ni_syscall -455 i386 kabi_reserved455 sys_ni_syscall -456 i386 kabi_reserved456 sys_ni_syscall +455 i386 xsched_setattr sys_ni_syscall +456 i386 xsched_getattr sys_ni_syscall 457 i386 kabi_reserved457 sys_ni_syscall 458 i386 kabi_reserved458 sys_ni_syscall 459 i386 kabi_reserved459 sys_ni_syscall diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index 162517343cb1..5f6579d0e307 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -376,8 +376,8 @@ 452 common fchmodat2 sys_fchmodat2 453 64 map_shadow_stack sys_map_shadow_stack 454 common vstream_manage sys_vstream_manage -455 common kabi_reserved455 sys_ni_syscall -456 common kabi_reserved456 sys_ni_syscall +455 common xsched_setattr sys_xsched_setattr +456 common xsched_getattr sys_xsched_getattr 457 common kabi_reserved457 sys_ni_syscall 458 common kabi_reserved458 sys_ni_syscall 459 common kabi_reserved459 sys_ni_syscall diff --git a/include/linux/sched.h b/include/linux/sched.h index e0afdc2dad2c..e3c0c5b56f01 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; @@ -72,6 +76,9 @@ struct signal_struct; struct task_delay_info; struct task_group; struct user_event_mm; +#ifdef CONFIG_XCU_SCHEDULER +struct xsched_attr; +#endif /* * Task state bitmask. NOTE! These bits are also @@ -776,6 +783,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..2f1354dd49f6 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; @@ -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..5b4f0423024d --- /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 { + /* XSCHED_TYPE_RT, XSCHED_TYPE_CFS */ + unsigned int xsched_class; + + /* 1~5 */ + unsigned int xsched_priority; +}; + +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 +}; + +#endif /* ! _XSCHED_TYPE_H */ diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index f015a3987255..02f2cb738d48 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -829,10 +829,10 @@ __SYSCALL(__NR_map_shadow_stack, sys_map_shadow_stack) #define __NR_vstream_manage 454 __SYSCALL(__NR_vstream_manage, sys_vstream_manage) -#define __NR_kabi_reserved455 455 -__SYSCALL(__NR_kabi_reserved455, sys_ni_syscall) -#define __NR_kabi_reserved456 456 -__SYSCALL(__NR_kabi_reserved456, sys_ni_syscall) +#define __NR_xsched_setattr 455 +__SYSCALL(__NR_xsched_setattr, sys_xsched_setattr) +#define __NR_xsched_getattr 456 +__SYSCALL(__NR_xsched_getattr, sys_xsched_getattr) #define __NR_kabi_reserved457 457 __SYSCALL(__NR_kabi_reserved457, sys_ni_syscall) #define __NR_kabi_reserved458 458 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..02d326868094 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,76 @@ __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 retval, rt_prio; + + 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(); + 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; + 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..32cdc194a940 100644 --- a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl @@ -541,8 +541,8 @@ 452 common fchmodat2 sys_fchmodat2 453 common map_shadow_stack sys_ni_syscall 454 common vstream_manage sys_ni_syscall -455 common kabi_reserved455 sys_ni_syscall -456 common kabi_reserved456 sys_ni_syscall +455 common xsched_setattr sys_ni_syscall +456 common xsched_getattr sys_ni_syscall 457 common kabi_reserved457 sys_ni_syscall 458 common kabi_reserved458 sys_ni_syscall 459 common kabi_reserved459 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..3f20eeaf9f18 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl @@ -376,8 +376,8 @@ 452 common fchmodat2 sys_fchmodat2 453 64 map_shadow_stack sys_map_shadow_stack 454 common vstream_manage sys_vstream_manage -455 common kabi_reserved455 sys_ni_syscall -456 common kabi_reserved456 sys_ni_syscall +455 common xsched_setattr sys_ni_syscall +456 common xsched_getattr sys_ni_syscall 457 common kabi_reserved457 sys_ni_syscall 458 common kabi_reserved458 sys_ni_syscall 459 common kabi_reserved459 sys_ni_syscall -- 2.34.1