
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/release-management/issues/IC9Q31 -------------------------------- Add percpu cache hit/miss count to 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 | 60 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 3 +++ 3 files changed, 68 insertions(+) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index fa93c6b9aae2..181a23ade1e2 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -773,6 +773,9 @@ static void epi_rcu_free(struct rcu_head *head) } #ifdef CONFIG_FAST_SYSCALL +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); @@ -1319,6 +1322,7 @@ int xcall_read(struct prefetch_item *pfi, unsigned int fd, char __user *buf, if (pfi->pos >= ((1 << cache_pages_order) * PAGE_SIZE) || pfi->len == 0) pfi->pos = 0; hit_return: + this_cpu_inc(xcall_cache_hit); if (pfi->len == 0 || copy_len == 0) transition_state(pfi, XCALL_CACHE_CANCEL, XCALL_CACHE_NONE); @@ -1330,6 +1334,7 @@ int xcall_read(struct prefetch_item *pfi, unsigned int fd, char __user *buf, else return -EBADF; reset_pfi_and_retry_vfs_read: + this_cpu_inc(xcall_cache_miss); pfi->len = 0; cancel_work(&pfi->work); diff --git a/fs/proc/base.c b/fs/proc/base.c index 1392b8a52ac5..b900447f3efe 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -3592,6 +3592,66 @@ static const struct file_operations proc_pid_sg_level_operations = { #ifdef CONFIG_FAST_SYSCALL bool fast_syscall_enabled(void); +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); + static int xcall_show(struct seq_file *m, void *v) { struct inode *inode = m->private; diff --git a/include/linux/fs.h b/include/linux/fs.h index d84ecaf70f14..61929fb02310 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3776,6 +3776,9 @@ static inline bool cachefiles_ondemand_is_enabled(void) #endif #ifdef CONFIG_FAST_SYSCALL +DECLARE_PER_CPU_ALIGNED(unsigned long, xcall_cache_hit); +DECLARE_PER_CPU_ALIGNED(unsigned long, xcall_cache_miss); + extern unsigned long *xcall_numa_cpumask_bits0; extern unsigned long *xcall_numa_cpumask_bits1; extern unsigned long *xcall_numa_cpumask_bits2; -- 2.34.1