From c2f54aa2b2707d835c00a2a43933dd3882c44580 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Fri, 9 Feb 2024 10:10:03 -0600 Subject: dm vdo: rename uds-threads.[ch] to thread-utils.[ch] Signed-off-by: Mike Snitzer Signed-off-by: Matthew Sakai --- drivers/md/dm-vdo/Makefile | 2 +- drivers/md/dm-vdo/config.c | 2 +- drivers/md/dm-vdo/funnel-requestqueue.c | 2 +- drivers/md/dm-vdo/index-page-map.c | 2 +- drivers/md/dm-vdo/index-session.h | 2 +- drivers/md/dm-vdo/logger.c | 2 +- drivers/md/dm-vdo/status-codes.c | 2 +- drivers/md/dm-vdo/thread-cond-var.c | 2 +- drivers/md/dm-vdo/thread-utils.c | 137 ++++++++++++++++++++++++++++++++ drivers/md/dm-vdo/thread-utils.h | 62 +++++++++++++++ drivers/md/dm-vdo/uds-threads.c | 137 -------------------------------- drivers/md/dm-vdo/uds-threads.h | 63 --------------- drivers/md/dm-vdo/volume-index.c | 2 +- drivers/md/dm-vdo/volume-index.h | 2 +- drivers/md/dm-vdo/volume.c | 2 +- drivers/md/dm-vdo/volume.h | 2 +- 16 files changed, 211 insertions(+), 212 deletions(-) create mode 100644 drivers/md/dm-vdo/thread-utils.c create mode 100644 drivers/md/dm-vdo/thread-utils.h delete mode 100644 drivers/md/dm-vdo/uds-threads.c delete mode 100644 drivers/md/dm-vdo/uds-threads.h (limited to 'drivers/md') diff --git a/drivers/md/dm-vdo/Makefile b/drivers/md/dm-vdo/Makefile index 8c06c3b969e3..be5020b81c47 100644 --- a/drivers/md/dm-vdo/Makefile +++ b/drivers/md/dm-vdo/Makefile @@ -51,8 +51,8 @@ dm-vdo-objs := \ thread-cond-var.o \ thread-device.o \ thread-registry.o \ + thread-utils.o \ uds-sysfs.o \ - uds-threads.o \ vdo.o \ vio.o \ volume-index.o \ diff --git a/drivers/md/dm-vdo/config.c b/drivers/md/dm-vdo/config.c index e9c7e9bdbce0..0bf315e7b5d1 100644 --- a/drivers/md/dm-vdo/config.c +++ b/drivers/md/dm-vdo/config.c @@ -9,7 +9,7 @@ #include "memory-alloc.h" #include "numeric.h" #include "string-utils.h" -#include "uds-threads.h" +#include "thread-utils.h" static const u8 INDEX_CONFIG_MAGIC[] = "ALBIC"; static const u8 INDEX_CONFIG_VERSION_6_02[] = "06.02"; diff --git a/drivers/md/dm-vdo/funnel-requestqueue.c b/drivers/md/dm-vdo/funnel-requestqueue.c index c8ba04c1089c..e7a3a4962295 100644 --- a/drivers/md/dm-vdo/funnel-requestqueue.c +++ b/drivers/md/dm-vdo/funnel-requestqueue.c @@ -12,7 +12,7 @@ #include "funnel-queue.h" #include "logger.h" #include "memory-alloc.h" -#include "uds-threads.h" +#include "thread-utils.h" /* * This queue will attempt to handle requests in reasonably sized batches instead of reacting diff --git a/drivers/md/dm-vdo/index-page-map.c b/drivers/md/dm-vdo/index-page-map.c index f3748a915c03..8441f86ef3a4 100644 --- a/drivers/md/dm-vdo/index-page-map.c +++ b/drivers/md/dm-vdo/index-page-map.c @@ -12,7 +12,7 @@ #include "numeric.h" #include "permassert.h" #include "string-utils.h" -#include "uds-threads.h" +#include "thread-utils.h" #include "uds.h" /* diff --git a/drivers/md/dm-vdo/index-session.h b/drivers/md/dm-vdo/index-session.h index c77ee021d510..62a9020dd9fa 100644 --- a/drivers/md/dm-vdo/index-session.h +++ b/drivers/md/dm-vdo/index-session.h @@ -10,7 +10,7 @@ #include #include "config.h" -#include "uds-threads.h" +#include "thread-utils.h" #include "uds.h" /* diff --git a/drivers/md/dm-vdo/logger.c b/drivers/md/dm-vdo/logger.c index 1efbf8d52f2c..ff1c570f81bf 100644 --- a/drivers/md/dm-vdo/logger.c +++ b/drivers/md/dm-vdo/logger.c @@ -12,7 +12,7 @@ #include #include "thread-device.h" -#include "uds-threads.h" +#include "thread-utils.h" struct priority_name { const char *name; diff --git a/drivers/md/dm-vdo/status-codes.c b/drivers/md/dm-vdo/status-codes.c index b4d7eb7f94ff..d77bc5e4a99a 100644 --- a/drivers/md/dm-vdo/status-codes.c +++ b/drivers/md/dm-vdo/status-codes.c @@ -8,7 +8,7 @@ #include "errors.h" #include "logger.h" #include "permassert.h" -#include "uds-threads.h" +#include "thread-utils.h" const struct error_info vdo_status_list[] = { { "VDO_NOT_IMPLEMENTED", "Not implemented" }, diff --git a/drivers/md/dm-vdo/thread-cond-var.c b/drivers/md/dm-vdo/thread-cond-var.c index ed7f0b79ca0a..82b80338b448 100644 --- a/drivers/md/dm-vdo/thread-cond-var.c +++ b/drivers/md/dm-vdo/thread-cond-var.c @@ -7,8 +7,8 @@ #include #include "errors.h" +#include "thread-utils.h" #include "time-utils.h" -#include "uds-threads.h" int uds_init_cond(struct cond_var *cv) { diff --git a/drivers/md/dm-vdo/thread-utils.c b/drivers/md/dm-vdo/thread-utils.c new file mode 100644 index 000000000000..1a1eb9ae9e33 --- /dev/null +++ b/drivers/md/dm-vdo/thread-utils.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2023 Red Hat + */ + +#include "thread-utils.h" + +#include +#include +#include +#include +#include + +#include "errors.h" +#include "logger.h" +#include "memory-alloc.h" + +static struct hlist_head thread_list; +static struct mutex thread_mutex; +static atomic_t thread_once = ATOMIC_INIT(0); + +struct thread { + void (*thread_function)(void *thread_data); + void *thread_data; + struct hlist_node thread_links; + struct task_struct *thread_task; + struct completion thread_done; +}; + +enum { + ONCE_NOT_DONE = 0, + ONCE_IN_PROGRESS = 1, + ONCE_COMPLETE = 2, +}; + +/* Run a function once only, and record that fact in the atomic value. */ +void uds_perform_once(atomic_t *once, void (*function)(void)) +{ + for (;;) { + switch (atomic_cmpxchg(once, ONCE_NOT_DONE, ONCE_IN_PROGRESS)) { + case ONCE_NOT_DONE: + function(); + atomic_set_release(once, ONCE_COMPLETE); + return; + case ONCE_IN_PROGRESS: + cond_resched(); + break; + case ONCE_COMPLETE: + return; + default: + return; + } + } +} + +static void thread_init(void) +{ + mutex_init(&thread_mutex); +} + +static int thread_starter(void *arg) +{ + struct registered_thread allocating_thread; + struct thread *thread = arg; + + thread->thread_task = current; + uds_perform_once(&thread_once, thread_init); + mutex_lock(&thread_mutex); + hlist_add_head(&thread->thread_links, &thread_list); + mutex_unlock(&thread_mutex); + uds_register_allocating_thread(&allocating_thread, NULL); + thread->thread_function(thread->thread_data); + uds_unregister_allocating_thread(); + complete(&thread->thread_done); + return 0; +} + +int uds_create_thread(void (*thread_function)(void *), void *thread_data, + const char *name, struct thread **new_thread) +{ + char *name_colon = strchr(name, ':'); + char *my_name_colon = strchr(current->comm, ':'); + struct task_struct *task; + struct thread *thread; + int result; + + result = uds_allocate(1, struct thread, __func__, &thread); + if (result != UDS_SUCCESS) { + uds_log_warning("Error allocating memory for %s", name); + return result; + } + + thread->thread_function = thread_function; + thread->thread_data = thread_data; + init_completion(&thread->thread_done); + /* + * Start the thread, with an appropriate thread name. + * + * If the name supplied contains a colon character, use that name. This causes uds module + * threads to have names like "uds:callbackW" and the main test runner thread to be named + * "zub:runtest". + * + * Otherwise if the current thread has a name containing a colon character, prefix the name + * supplied with the name of the current thread up to (and including) the colon character. + * Thus when the "kvdo0:dedupeQ" thread opens an index session, all the threads associated + * with that index will have names like "kvdo0:foo". + * + * Otherwise just use the name supplied. This should be a rare occurrence. + */ + if ((name_colon == NULL) && (my_name_colon != NULL)) { + task = kthread_run(thread_starter, thread, "%.*s:%s", + (int) (my_name_colon - current->comm), current->comm, + name); + } else { + task = kthread_run(thread_starter, thread, "%s", name); + } + + if (IS_ERR(task)) { + uds_free(thread); + return PTR_ERR(task); + } + + *new_thread = thread; + return UDS_SUCCESS; +} + +int uds_join_threads(struct thread *thread) +{ + while (wait_for_completion_interruptible(&thread->thread_done)) + fsleep(1000); + + mutex_lock(&thread_mutex); + hlist_del(&thread->thread_links); + mutex_unlock(&thread_mutex); + uds_free(thread); + return UDS_SUCCESS; +} diff --git a/drivers/md/dm-vdo/thread-utils.h b/drivers/md/dm-vdo/thread-utils.h new file mode 100644 index 000000000000..30637dd264cc --- /dev/null +++ b/drivers/md/dm-vdo/thread-utils.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2023 Red Hat + */ + +#ifndef THREAD_UTILS_H +#define THREAD_UTILS_H + +#include +#include +#include +#include +#include +#include + +#include "errors.h" + +/* Thread and synchronization utilities for UDS */ + +struct cond_var { + wait_queue_head_t wait_queue; +}; + +struct thread; + + +int __must_check uds_create_thread(void (*thread_function)(void *), void *thread_data, + const char *name, struct thread **new_thread); + +void uds_perform_once(atomic_t *once_state, void (*function) (void)); + +int uds_join_threads(struct thread *thread); + +int __must_check uds_init_cond(struct cond_var *cond); +int uds_signal_cond(struct cond_var *cond); +int uds_broadcast_cond(struct cond_var *cond); +int uds_wait_cond(struct cond_var *cond, struct mutex *mutex); +int uds_destroy_cond(struct cond_var *cond); + +static inline int __must_check uds_init_mutex(struct mutex *mutex) +{ + mutex_init(mutex); + return UDS_SUCCESS; +} + +static inline int uds_destroy_mutex(struct mutex *mutex) +{ + return UDS_SUCCESS; +} + +static inline void uds_lock_mutex(struct mutex *mutex) +{ + mutex_lock(mutex); +} + +static inline void uds_unlock_mutex(struct mutex *mutex) +{ + mutex_unlock(mutex); +} + + +#endif /* UDS_THREADS_H */ diff --git a/drivers/md/dm-vdo/uds-threads.c b/drivers/md/dm-vdo/uds-threads.c deleted file mode 100644 index 3bfd22bae8b1..000000000000 --- a/drivers/md/dm-vdo/uds-threads.c +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2023 Red Hat - */ - -#include "uds-threads.h" - -#include -#include -#include -#include -#include - -#include "errors.h" -#include "logger.h" -#include "memory-alloc.h" - -static struct hlist_head thread_list; -static struct mutex thread_mutex; -static atomic_t thread_once = ATOMIC_INIT(0); - -struct thread { - void (*thread_function)(void *thread_data); - void *thread_data; - struct hlist_node thread_links; - struct task_struct *thread_task; - struct completion thread_done; -}; - -enum { - ONCE_NOT_DONE = 0, - ONCE_IN_PROGRESS = 1, - ONCE_COMPLETE = 2, -}; - -/* Run a function once only, and record that fact in the atomic value. */ -void uds_perform_once(atomic_t *once, void (*function)(void)) -{ - for (;;) { - switch (atomic_cmpxchg(once, ONCE_NOT_DONE, ONCE_IN_PROGRESS)) { - case ONCE_NOT_DONE: - function(); - atomic_set_release(once, ONCE_COMPLETE); - return; - case ONCE_IN_PROGRESS: - cond_resched(); - break; - case ONCE_COMPLETE: - return; - default: - return; - } - } -} - -static void thread_init(void) -{ - mutex_init(&thread_mutex); -} - -static int thread_starter(void *arg) -{ - struct registered_thread allocating_thread; - struct thread *thread = arg; - - thread->thread_task = current; - uds_perform_once(&thread_once, thread_init); - mutex_lock(&thread_mutex); - hlist_add_head(&thread->thread_links, &thread_list); - mutex_unlock(&thread_mutex); - uds_register_allocating_thread(&allocating_thread, NULL); - thread->thread_function(thread->thread_data); - uds_unregister_allocating_thread(); - complete(&thread->thread_done); - return 0; -} - -int uds_create_thread(void (*thread_function)(void *), void *thread_data, - const char *name, struct thread **new_thread) -{ - char *name_colon = strchr(name, ':'); - char *my_name_colon = strchr(current->comm, ':'); - struct task_struct *task; - struct thread *thread; - int result; - - result = uds_allocate(1, struct thread, __func__, &thread); - if (result != UDS_SUCCESS) { - uds_log_warning("Error allocating memory for %s", name); - return result; - } - - thread->thread_function = thread_function; - thread->thread_data = thread_data; - init_completion(&thread->thread_done); - /* - * Start the thread, with an appropriate thread name. - * - * If the name supplied contains a colon character, use that name. This causes uds module - * threads to have names like "uds:callbackW" and the main test runner thread to be named - * "zub:runtest". - * - * Otherwise if the current thread has a name containing a colon character, prefix the name - * supplied with the name of the current thread up to (and including) the colon character. - * Thus when the "kvdo0:dedupeQ" thread opens an index session, all the threads associated - * with that index will have names like "kvdo0:foo". - * - * Otherwise just use the name supplied. This should be a rare occurrence. - */ - if ((name_colon == NULL) && (my_name_colon != NULL)) { - task = kthread_run(thread_starter, thread, "%.*s:%s", - (int) (my_name_colon - current->comm), current->comm, - name); - } else { - task = kthread_run(thread_starter, thread, "%s", name); - } - - if (IS_ERR(task)) { - uds_free(thread); - return PTR_ERR(task); - } - - *new_thread = thread; - return UDS_SUCCESS; -} - -int uds_join_threads(struct thread *thread) -{ - while (wait_for_completion_interruptible(&thread->thread_done)) - fsleep(1000); - - mutex_lock(&thread_mutex); - hlist_del(&thread->thread_links); - mutex_unlock(&thread_mutex); - uds_free(thread); - return UDS_SUCCESS; -} diff --git a/drivers/md/dm-vdo/uds-threads.h b/drivers/md/dm-vdo/uds-threads.h deleted file mode 100644 index 2a0580e4482b..000000000000 --- a/drivers/md/dm-vdo/uds-threads.h +++ /dev/null @@ -1,63 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2023 Red Hat - */ - -#ifndef UDS_THREADS_H -#define UDS_THREADS_H - -#include -#include -#include -#include -#include -#include - -#include "errors.h" -#include "time-utils.h" - -/* Thread and synchronization utilities for UDS */ - -struct cond_var { - wait_queue_head_t wait_queue; -}; - -struct thread; - - -int __must_check uds_create_thread(void (*thread_function)(void *), void *thread_data, - const char *name, struct thread **new_thread); - -void uds_perform_once(atomic_t *once_state, void (*function) (void)); - -int uds_join_threads(struct thread *thread); - -int __must_check uds_init_cond(struct cond_var *cond); -int uds_signal_cond(struct cond_var *cond); -int uds_broadcast_cond(struct cond_var *cond); -int uds_wait_cond(struct cond_var *cond, struct mutex *mutex); -int uds_destroy_cond(struct cond_var *cond); - -static inline int __must_check uds_init_mutex(struct mutex *mutex) -{ - mutex_init(mutex); - return UDS_SUCCESS; -} - -static inline int uds_destroy_mutex(struct mutex *mutex) -{ - return UDS_SUCCESS; -} - -static inline void uds_lock_mutex(struct mutex *mutex) -{ - mutex_lock(mutex); -} - -static inline void uds_unlock_mutex(struct mutex *mutex) -{ - mutex_unlock(mutex); -} - - -#endif /* UDS_THREADS_H */ diff --git a/drivers/md/dm-vdo/volume-index.c b/drivers/md/dm-vdo/volume-index.c index eebc19fe7d6f..daeafe7691ea 100644 --- a/drivers/md/dm-vdo/volume-index.c +++ b/drivers/md/dm-vdo/volume-index.c @@ -18,8 +18,8 @@ #include "memory-alloc.h" #include "numeric.h" #include "permassert.h" +#include "thread-utils.h" #include "uds.h" -#include "uds-threads.h" /* * The volume index is a combination of two separate subindexes, one containing sparse hook entries diff --git a/drivers/md/dm-vdo/volume-index.h b/drivers/md/dm-vdo/volume-index.h index 537e9947cf4a..2eb2cee7ee58 100644 --- a/drivers/md/dm-vdo/volume-index.h +++ b/drivers/md/dm-vdo/volume-index.h @@ -10,8 +10,8 @@ #include "config.h" #include "delta-index.h" +#include "thread-utils.h" #include "uds.h" -#include "uds-threads.h" /* * The volume index is the primary top-level index for UDS. It contains records which map a record diff --git a/drivers/md/dm-vdo/volume.c b/drivers/md/dm-vdo/volume.c index 8bd64057c2ca..5b3cb5d89e47 100644 --- a/drivers/md/dm-vdo/volume.c +++ b/drivers/md/dm-vdo/volume.c @@ -20,7 +20,7 @@ #include "permassert.h" #include "sparse-cache.h" #include "string-utils.h" -#include "uds-threads.h" +#include "thread-utils.h" /* * The first block of the volume layout is reserved for the volume header, which is no longer used. diff --git a/drivers/md/dm-vdo/volume.h b/drivers/md/dm-vdo/volume.h index 066680282340..7ef9945d8403 100644 --- a/drivers/md/dm-vdo/volume.h +++ b/drivers/md/dm-vdo/volume.h @@ -19,8 +19,8 @@ #include "permassert.h" #include "radix-sort.h" #include "sparse-cache.h" +#include "thread-utils.h" #include "uds.h" -#include "uds-threads.h" /* * The volume manages deduplication records on permanent storage. The term "volume" can also refer -- cgit