
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/release-management/issues/IC9Q31 -------------------------------- Xcall prefetch implements customized epoll_wait() and read() system calls, which enable data prefetching. In scenarios where the number of network connections established by a service is large, the time consumed by the service in the read() system call can be reduced. Users can enable xcall prefetch with the following command: echo 1 > /proc/$PID/prefetch Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> --- arch/Kconfig | 17 +++++++++++ fs/proc/base.c | 67 +++++++++++++++++++++++++++++++++++++++++++ include/linux/xcall.h | 1 + kernel/fork.c | 4 ++- 4 files changed, 88 insertions(+), 1 deletion(-) diff --git a/arch/Kconfig b/arch/Kconfig index 6dc501a4afb1..d27eb1800cd9 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1205,6 +1205,23 @@ config FAST_SYSCALL exception handling path that only considers necessary features such as security, context saving, and recovery. +config XCALL_PREFETCH + bool "Xcall prefetch support" + depends on FAST_SYSCALL + depends on EPOLL + default n + help + This enable xcall prefetch feature. + Xcall prefetch feature implements customized epoll_wait() and + read() system calls, which enable data prefetching. + In high-concurrency connection scenarios, this improves + the parallel execution efficiency of the read() system call + and increases the system's business throughput. + The Xcall prefetch feature is suitable for business scenarios + where the epoll I/O multiplexing mechanism is used, the read() + system call takes up a large proportion of time, and the number + of concurrent connections is large. + config ARCH_SUPPORTS_FAST_IRQ bool diff --git a/fs/proc/base.c b/fs/proc/base.c index 924959c9a02b..3e19b7bcbf66 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -3704,6 +3704,70 @@ static const struct file_operations proc_pid_xcall_operations = { }; #endif +#ifdef CONFIG_XCALL_PREFETCH +static int xcall_prefetch_show(struct seq_file *m, void *v) +{ + struct inode *inode = m->private; + struct task_struct *p; + + if (!fast_syscall_enabled()) + return -EACCES; + + p = get_proc_task(inode); + if (!p) + return -ESRCH; + + if (p->xinfo) + seq_printf(m, "%d\n", p->xinfo->prefetch); + + put_task_struct(p); + + return 0; +} + +static int xcall_prefetch_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, xcall_prefetch_show, inode); +} + +static ssize_t xcall_prefetch_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset) +{ + struct inode *inode = file_inode(file); + struct task_struct *p; + char buffer[TASK_COMM_LEN]; + const size_t maxlen = sizeof(buffer) - 1; + bool prefetch_enable = true; + + memset(buffer, 0, sizeof(buffer)); + if (copy_from_user(buffer, buf, count > maxlen ? maxlen : count)) + return -EFAULT; + + p = get_proc_task(inode); + if (!p) + return -ESRCH; + + if (!p->xinfo || p->xinfo->prefetch || + kstrtobool(buffer, &prefetch_enable) || !prefetch_enable) { + put_task_struct(p); + return -EINVAL; + } + + p->xinfo->prefetch = true; + put_task_struct(p); + + return count; +} + +static const struct file_operations proc_pid_xcall_prefetch_operations = { + .open = xcall_prefetch_open, + .read = seq_read, + .write = xcall_prefetch_write, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + /* * Thread groups */ @@ -3733,6 +3797,9 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_FAST_SYSCALL REG("xcall", 0644, proc_pid_xcall_operations), #endif +#ifdef CONFIG_XCALL_PREFETCH + REG("prefetch", 0644, proc_pid_xcall_prefetch_operations), +#endif #ifdef CONFIG_SCHED_AUTOGROUP REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations), #endif diff --git a/include/linux/xcall.h b/include/linux/xcall.h index f52f2d9685f0..88ce88793940 100644 --- a/include/linux/xcall.h +++ b/include/linux/xcall.h @@ -5,5 +5,6 @@ struct xcall_info { /* Must be first! */ DECLARE_BITMAP(xcall_enable, __NR_syscalls); + bool prefetch; }; #endif diff --git a/kernel/fork.c b/kernel/fork.c index 429b909d093d..7295de34c015 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2102,9 +2102,11 @@ static __latent_entropy struct task_struct *copy_process( p->xinfo = kzalloc(sizeof(struct xcall_info), GFP_KERNEL); if (!p->xinfo) goto bad_fork_free; - if (current->xinfo) + if (current->xinfo) { bitmap_copy(p->xinfo->xcall_enable, current->xinfo->xcall_enable, __NR_syscalls); + p->xinfo->prefetch = current->xinfo->prefetch; + } #endif #ifdef CONFIG_QOS_SCHED_DYNAMIC_AFFINITY -- 2.34.1