diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index 5127af69471c343f097ad746156762935a3ed572..c707bea6232bcc7de6b1090f157780467ffedc5c 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 3378482bcf6f81678c14ba842292d0d640b3ab77..822e08438e2d74d03afc3f04e84fa37acb6f8db5 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 e14ce1f6b1ec598d6047f330f7117f3e3692c79b..d97a7da65e49e56464992a305620c6f3ef85915c 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 162517343cb1c283234e45ef0b12809a8604cee7..a538ce360e7d4bfb7977cb4958f1f2d294f79bb2 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 e0afdc2dad2cc3bd9b2568fb601928e9f545eaf2..bb23790fd2d39f7cb17cc72018dc774650875a62 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -41,6 +41,10 @@ #include #include +#ifdef CONFIG_XCU_SCHEDULER +#include +#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 119aabc72a2d403596ff695208e3fc02c9de350e..2e7b2c57c8c08fd76c9f7c4b0f815f9a88d391ff 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 38db18c0d5701f5001838c5e17db0b2f10f6270c..60cb43b4631ff46f8cc57264a85e67591076a6e5 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -6,6 +6,7 @@ #include #include #include +#include #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 0000000000000000000000000000000000000000..f52fe32d519840bb0fb0dc8f74aa863ce6a4953d --- /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 f015a398725570423d0a2e050f308497c30b2264..154e0ecc946cfb762132e4d21d7d8916fc97bbe3 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 1adc171495587eb3d48948dc19e2a6333f1705b0..61a6345708c80d73f9670d9a5607353be1662dcf 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -14,6 +14,9 @@ #include #include +#ifdef CONFIG_XCU_SCHEDULER +#include +#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 328bbf6a36d20f4c6c583d938085946b834010fc..f3c663602345ff0a1a640610250b9053ff6dfc13 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 69f1a442f985cc36c39444c8c7c52c5049d536fd..b23f2ca7820b71d613ac63a96a4801d0ca69cce3 100644 --- a/kernel/xsched/core.c +++ b/kernel/xsched/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -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 41b60e341679b7bafdea84f44d5d0464440a5ce9..e2ce1ebb8a7a062d91ba2370ec8782dcc85e51d5 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 4d76d89700133b3888bd12b17ccf12a466ee6e78..8ed79b4b20e3cf017009e811f58569d3e413a42c 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 65004179e548874898608f7410d8ccaeba579340..9cc0623ee8e570357229e67e1e2b35f75e825eb8 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