
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/release-management/issues/IC9Q31 -------------------------------- Add percpu cache hit/miss count to calculate the usage efficiency of xcall prefetch framework. Also Add "/proc/xcall/stats" dir, so we can get the xcall prefetch hit ratio on each CPU that initiates a read system call, which is important for performance tuning. Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> --- fs/eventpoll.c | 5 ++++ fs/proc/base.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 3 +++ 3 files changed, 69 insertions(+) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 5a1b509e31a6..d34abfb3fe31 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -769,6 +769,9 @@ static void epi_rcu_free(struct rcu_head *head) } #ifdef CONFIG_XCALL_PREFETCH +DEFINE_PER_CPU_ALIGNED(unsigned long, xcall_cache_hit); +DEFINE_PER_CPU_ALIGNED(unsigned long, xcall_cache_miss); + #define PREFETCH_ITEM_HASH_BITS 6 #define PREFETCH_ITEM_TABLE_SIZE (1 << PREFETCH_ITEM_HASH_BITS) static DEFINE_HASHTABLE(xcall_item_table, PREFETCH_ITEM_HASH_BITS); @@ -1289,12 +1292,14 @@ static int xcall_read(struct prefetch_item *pfi, unsigned int fd, transition_state(pfi, XCALL_CACHE_CANCEL, XCALL_CACHE_READY); } hit_return: + this_cpu_inc(xcall_cache_hit); if (copy_ret == 0) return copy_len; else return -EBADF; reset_pfi_and_retry_vfs_read: + this_cpu_inc(xcall_cache_miss); pfi->len = 0; pfi->pos = 0; cancel_work(&pfi->work); diff --git a/fs/proc/base.c b/fs/proc/base.c index d322ab93b810..fb931f4bcb6e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -3738,6 +3738,67 @@ static const struct file_operations proc_pid_xcall_operations = { }; #endif +#ifdef CONFIG_XCALL_PREFETCH +static ssize_t xcall_stats_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + int cpu; + + for_each_cpu(cpu, cpu_online_mask) { + *per_cpu_ptr(&xcall_cache_hit, cpu) = 0; + *per_cpu_ptr(&xcall_cache_miss, cpu) = 0; + } + + return count; +} + +static int xcall_stats_show(struct seq_file *m, void *v) +{ + unsigned long hit = 0, miss = 0; + unsigned int cpu; + u64 percent; + + for_each_cpu(cpu, cpu_online_mask) { + hit = *per_cpu_ptr(&xcall_cache_hit, cpu); + miss = *per_cpu_ptr(&xcall_cache_miss, cpu); + + if (hit == 0 && miss == 0) + continue; + + percent = (hit * 10000ULL) / (hit + miss); + seq_printf(m, "cpu%d epoll cache_{hit,miss}: %ld,%ld, hit ratio: %3llu.%02llu%%\n", + cpu, hit, miss, percent / 100, percent % 100); + } + return 0; +} + +static int xcall_stats_open(struct inode *inode, struct file *file) +{ + return single_open(file, xcall_stats_show, NULL); +} + +static const struct proc_ops xcall_stats_fops = { + .proc_open = xcall_stats_open, + .proc_read = seq_read, + .proc_write = xcall_stats_write, + .proc_lseek = seq_lseek, + .proc_release = single_release +}; + +static int __init init_xcall_stats_procfs(void) +{ + struct proc_dir_entry *xcall_proc_dir; + + if (!fast_syscall_enabled()) + return 0; + + xcall_proc_dir = proc_mkdir("xcall", NULL); + proc_create("stats", 0444, xcall_proc_dir, &xcall_stats_fops); + return 0; +} +device_initcall(init_xcall_stats_procfs); +#endif + /* * Thread groups */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 2b62da0fc3b7..9c27031bfea0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3774,6 +3774,9 @@ struct prefetch_item { struct hlist_node node; }; +DECLARE_PER_CPU_ALIGNED(unsigned long, xcall_cache_hit); +DECLARE_PER_CPU_ALIGNED(unsigned long, xcall_cache_miss); + int xcall_read_begin(struct file *file, unsigned int fd, char __user *buf, size_t count); void xcall_read_end(struct file *file); -- 2.34.1