From 8754693fe6ddac4b74e27800a05d5aea00bb0359 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Fri, 15 Sep 2023 09:34:24 -0400 Subject: [PATCH] LU-9859 libcfs: move kernel specific code out of libcfs core Over time kernel version specific code has leaked into the libcfs core code. Move that code to the linux subdirectory code so in the future code cleanup is not missed. Test-Parameters: trivial Change-Id: I38a00c377334066160083edd3932d4a718198497 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52010 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Timothy Day Reviewed-by: Arshad Hussain Reviewed-by: Neil Brown Reviewed-by: Oleg Drokin --- libcfs/include/libcfs/libcfs.h | 19 -------- libcfs/include/libcfs/libcfs_debug.h | 2 - libcfs/include/libcfs/libcfs_private.h | 3 -- libcfs/include/libcfs/linux/linux-mem.h | 6 +++ libcfs/include/libcfs/linux/linux-misc.h | 21 ++++++++ libcfs/libcfs/debug.c | 27 +---------- libcfs/libcfs/libcfs_mem.c | 57 ---------------------- libcfs/libcfs/linux/linux-prim.c | 83 ++++++++++++++++++++++++++++++++ libcfs/libcfs/module.c | 6 --- 9 files changed, 112 insertions(+), 112 deletions(-) diff --git a/libcfs/include/libcfs/libcfs.h b/libcfs/include/libcfs/libcfs.h index e12fe6a..12d9dfd 100644 --- a/libcfs/include/libcfs/libcfs.h +++ b/libcfs/include/libcfs/libcfs.h @@ -105,25 +105,6 @@ do { \ ); \ } while (0) -/* atomic-context safe vfree */ -void libcfs_vfree_atomic(const void *addr); - -/* interval tree */ - -#ifdef HAVE_INTERVAL_TREE_CACHED -#define interval_tree_root rb_root_cached -#define interval_tree_first rb_first_cached -#define INTERVAL_TREE_ROOT RB_ROOT_CACHED -#else -#define interval_tree_root rb_root -#define interval_tree_first rb_first -#define INTERVAL_TREE_ROOT RB_ROOT -#endif /* HAVE_INTERVAL_TREE_CACHED */ - -#ifndef unsafe_memcpy -#define unsafe_memcpy(to, from, size, reason) memcpy((to), (from), (size)) -#endif - #define FLEXIBLE_OBJECT \ "Struct contains a flexible member, the size of object is checked" \ "and can be safely copied in a single memcpy()" diff --git a/libcfs/include/libcfs/libcfs_debug.h b/libcfs/include/libcfs/libcfs_debug.h index f7d5bd9..705e8cd 100644 --- a/libcfs/include/libcfs/libcfs_debug.h +++ b/libcfs/include/libcfs/libcfs_debug.h @@ -306,8 +306,6 @@ do { \ return; \ } while (0) -void cfs_debug_init(void); - static inline void cfs_tty_write_msg(const char *msg) { struct tty_struct *tty; diff --git a/libcfs/include/libcfs/libcfs_private.h b/libcfs/include/libcfs/libcfs_private.h index 0cd7774..bbc7e04 100644 --- a/libcfs/include/libcfs/libcfs_private.h +++ b/libcfs/include/libcfs/libcfs_private.h @@ -220,9 +220,6 @@ do { \ #define LIBCFS_CPT_ALLOC(ptr, cptab, cpt, size) \ LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, GFP_NOFS) -void init_libcfs_vfree_atomic(void); -void exit_libcfs_vfree_atomic(void); - #define LIBCFS_FREE(ptr, size) \ do { \ int s = (size); \ diff --git a/libcfs/include/libcfs/linux/linux-mem.h b/libcfs/include/libcfs/linux/linux-mem.h index 548eb96..3847cae 100644 --- a/libcfs/include/libcfs/linux/linux-mem.h +++ b/libcfs/include/libcfs/linux/linux-mem.h @@ -136,6 +136,12 @@ static inline void mmap_read_unlock(struct mm_struct *mm) #define __ll_vmalloc(size, flags) __vmalloc(size, flags, PAGE_KERNEL) #endif +void init_libcfs_vfree_atomic(void); +void exit_libcfs_vfree_atomic(void); + +/* atomic-context safe vfree */ +void libcfs_vfree_atomic(const void *addr); + #ifndef HAVE_KFREE_SENSITIVE #define kfree_sensitive(x) kzfree(x) #endif diff --git a/libcfs/include/libcfs/linux/linux-misc.h b/libcfs/include/libcfs/linux/linux-misc.h index e00f79d..2f285a5 100644 --- a/libcfs/include/libcfs/linux/linux-misc.h +++ b/libcfs/include/libcfs/linux/linux-misc.h @@ -120,6 +120,7 @@ static inline int kref_read(const struct kref *kref) #endif /* HAVE_KREF_READ */ void cfs_arch_init(void); +void cfs_arch_exit(void); #ifndef container_of_safe /** @@ -151,6 +152,26 @@ void cfs_arch_init(void); #define task_is_running(task) (task->state == TASK_RUNNING) #endif +/* interval tree */ +#ifdef HAVE_INTERVAL_TREE_CACHED +#define interval_tree_root rb_root_cached +#define interval_tree_first rb_first_cached +#define INTERVAL_TREE_ROOT RB_ROOT_CACHED +#else +#define interval_tree_root rb_root +#define interval_tree_first rb_first +#define INTERVAL_TREE_ROOT RB_ROOT +#endif /* HAVE_INTERVAL_TREE_CACHED */ + +/* Linux v5.1-rc5 214d8ca6ee ("stacktrace: Provide common infrastructure") + * CONFIG_ARCH_STACKWALK indicates that save_stack_trace_tsk symbol is not + * exported. Use symbol_get() to find if save_stack_trace_tsk is available. + */ +#ifdef CONFIG_ARCH_STACKWALK +int cfs_stack_trace_save_tsk(struct task_struct *task, unsigned long *store, + unsigned int size, unsigned int skipnr); +#endif + #ifndef memset_startat /** from linux 5.19 include/linux/string.h: */ #define memset_startat(obj, v, member) \ diff --git a/libcfs/libcfs/debug.c b/libcfs/libcfs/debug.c index 8df44e5..38dc64c 100644 --- a/libcfs/libcfs/debug.c +++ b/libcfs/libcfs/debug.c @@ -502,27 +502,6 @@ static void cfs_print_stack_trace(unsigned long *entries, unsigned int nr) #define MAX_ST_ENTRIES 100 static DEFINE_SPINLOCK(st_lock); -/* Linux v5.1-rc5 214d8ca6ee ("stacktrace: Provide common infrastructure") - * CONFIG_ARCH_STACKWALK indicates that save_stack_trace_tsk symbol is not - * exported. Use symbol_get() to find if save_stack_trace_tsk is available. - */ -#ifdef CONFIG_ARCH_STACKWALK -typedef unsigned int (stack_trace_save_tsk_t)(struct task_struct *task, - unsigned long *store, - unsigned int size, - unsigned int skipnr); -static stack_trace_save_tsk_t *task_dump_stack; -#endif - -void __init cfs_debug_init(void) -{ -#ifdef CONFIG_ARCH_STACKWALK - task_dump_stack = (void *) - cfs_kallsyms_lookup_name("stack_trace_save_tsk"); - -#endif -} - static void libcfs_call_trace(struct task_struct *tsk) { static unsigned long entries[MAX_ST_ENTRIES]; @@ -533,10 +512,8 @@ static void libcfs_call_trace(struct task_struct *tsk) pr_info("Pid: %d, comm: %.20s %s %s\n", tsk->pid, tsk->comm, init_utsname()->release, init_utsname()->version); pr_info("Call Trace TBD:\n"); - if (task_dump_stack) { - nr_entries = task_dump_stack(tsk, entries, MAX_ST_ENTRIES, 0); - cfs_print_stack_trace(entries, nr_entries); - } + nr_entries = cfs_stack_trace_save_tsk(tsk, entries, MAX_ST_ENTRIES, 0); + cfs_print_stack_trace(entries, nr_entries); spin_unlock(&st_lock); #else struct stack_trace trace; diff --git a/libcfs/libcfs/libcfs_mem.c b/libcfs/libcfs/libcfs_mem.c index d514b01..1edfc53 100644 --- a/libcfs/libcfs/libcfs_mem.c +++ b/libcfs/libcfs/libcfs_mem.c @@ -34,7 +34,6 @@ #include #include -#include struct cfs_var_array { unsigned int va_count; /* # of buffers */ @@ -118,59 +117,3 @@ cfs_percpt_number(void *vars) return arr->va_count; } EXPORT_SYMBOL(cfs_percpt_number); - - -/* - * This is opencoding of vfree_atomic from Linux kernel added in 4.10 with - * minimum changes needed to work on older kernels too. - */ - -#ifndef llist_for_each_safe -#define llist_for_each_safe(pos, n, node) \ - for ((pos) = (node); (pos) && ((n) = (pos)->next, true); (pos) = (n)) -#endif - -struct vfree_deferred { - struct llist_head list; - struct work_struct wq; -}; -static DEFINE_PER_CPU(struct vfree_deferred, vfree_deferred); - -static void free_work(struct work_struct *w) -{ - struct vfree_deferred *p = container_of(w, struct vfree_deferred, wq); - struct llist_node *t, *llnode; - - llist_for_each_safe(llnode, t, llist_del_all(&p->list)) - vfree((void *)llnode); -} - -void libcfs_vfree_atomic(const void *addr) -{ - struct vfree_deferred *p = raw_cpu_ptr(&vfree_deferred); - - if (!addr) - return; - - if (llist_add((struct llist_node *)addr, &p->list)) - schedule_work(&p->wq); -} -EXPORT_SYMBOL(libcfs_vfree_atomic); - -void __init init_libcfs_vfree_atomic(void) -{ - int i; - - for_each_possible_cpu(i) { - struct vfree_deferred *p; - - p = &per_cpu(vfree_deferred, i); - init_llist_head(&p->list); - INIT_WORK(&p->wq, free_work); - } -} - -void __exit exit_libcfs_vfree_atomic(void) -{ - flush_scheduled_work(); -} diff --git a/libcfs/libcfs/linux/linux-prim.c b/libcfs/libcfs/linux/linux-prim.c index 060c1ad..8e0ee07 100644 --- a/libcfs/libcfs/linux/linux-prim.c +++ b/libcfs/libcfs/linux/linux-prim.c @@ -46,9 +46,11 @@ #include #endif +#include #include #include #include +#include #ifndef HAVE_XARRAY_SUPPORT #include #endif @@ -119,6 +121,25 @@ int cfs_apply_workqueue_attrs(struct workqueue_struct *wq, } EXPORT_SYMBOL_GPL(cfs_apply_workqueue_attrs); +/* Linux v5.1-rc5 214d8ca6ee ("stacktrace: Provide common infrastructure") + * CONFIG_ARCH_STACKWALK indicates that save_stack_trace_tsk symbol is not + * exported. Use symbol_get() to find if save_stack_trace_tsk is available. + */ +#ifdef CONFIG_ARCH_STACKWALK +static unsigned int (*task_dump_stack_t)(struct task_struct *task, + unsigned long *store, + unsigned int size, + unsigned int skipnr); + +int cfs_stack_trace_save_tsk(struct task_struct *task, unsigned long *store, + unsigned int size, unsigned int skipnr) +{ + if (task_dump_stack_t) + return task_dump_stack_t(task, store, size, skipnr); + return 0; +} +#endif + #ifndef HAVE_XARRAY_SUPPORT struct kmem_cache *xarray_cachep; @@ -131,11 +152,67 @@ static void xarray_node_ctor(void *arg) } #endif +/* + * This is opencoding of vfree_atomic from Linux kernel added in 4.10 with + * minimum changes needed to work on older kernels too. + */ + +#ifndef llist_for_each_safe +#define llist_for_each_safe(pos, n, node) \ + for ((pos) = (node); (pos) && ((n) = (pos)->next, true); (pos) = (n)) +#endif + +struct vfree_deferred { + struct llist_head list; + struct work_struct wq; +}; +static DEFINE_PER_CPU(struct vfree_deferred, vfree_deferred); + +static void free_work(struct work_struct *w) +{ + struct vfree_deferred *p = container_of(w, struct vfree_deferred, wq); + struct llist_node *t, *llnode; + + llist_for_each_safe(llnode, t, llist_del_all(&p->list)) + vfree((void *)llnode); +} + +void libcfs_vfree_atomic(const void *addr) +{ + struct vfree_deferred *p = raw_cpu_ptr(&vfree_deferred); + + if (!addr) + return; + + if (llist_add((struct llist_node *)addr, &p->list)) + schedule_work(&p->wq); +} +EXPORT_SYMBOL(libcfs_vfree_atomic); + +void __init init_libcfs_vfree_atomic(void) +{ + int i; + + for_each_possible_cpu(i) { + struct vfree_deferred *p; + + p = &per_cpu(vfree_deferred, i); + init_llist_head(&p->list); + INIT_WORK(&p->wq, free_work); + } +} + void __init cfs_arch_init(void) { + init_libcfs_vfree_atomic(); + #ifndef HAVE_WAIT_VAR_EVENT wait_bit_init(); #endif +#ifdef CONFIG_ARCH_STACKWALK + task_dump_stack_t = + (void *)cfs_kallsyms_lookup_name("stack_trace_save_tsk"); +#endif cfs_apply_workqueue_attrs_t = (void *)cfs_kallsyms_lookup_name("apply_workqueue_attrs"); #ifndef HAVE_XARRAY_SUPPORT @@ -146,6 +223,12 @@ void __init cfs_arch_init(void) #endif } +void __exit cfs_arch_exit(void) +{ + /* exit_libcfs_vfree_atomic */ + flush_scheduled_work(); +} + int cfs_kernel_write(struct file *filp, const void *buf, size_t count, loff_t *pos) { diff --git a/libcfs/libcfs/module.c b/libcfs/libcfs/module.c index 33bba9c..5fdac4a 100644 --- a/libcfs/libcfs/module.c +++ b/libcfs/libcfs/module.c @@ -667,16 +667,12 @@ static int __init libcfs_init(void) cfs_arch_init(); - init_libcfs_vfree_atomic(); - rc = libcfs_debug_init(5 * 1024 * 1024); if (rc < 0) { pr_err("LustreError: libcfs_debug_init: rc = %d\n", rc); return (rc); } - cfs_debug_init(); - rc = cfs_cpu_init(); if (rc != 0) goto cleanup_debug; @@ -748,8 +744,6 @@ static void __exit libcfs_exit(void) rc = libcfs_debug_cleanup(); if (rc) pr_err("LustreError: libcfs_debug_cleanup: rc = %d\n", rc); - - exit_libcfs_vfree_atomic(); } MODULE_AUTHOR("OpenSFS, Inc. "); -- 1.8.3.1