The quilt patch titled Subject: nilfs2: use kthread_create and kthread_stop for the log writer thread has been removed from the -mm tree. Its filename was nilfs2-use-kthread_create-and-kthread_stop-for-the-log-writer-thread.patch This patch was dropped because it was merged into the mm-nonmm-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm ------------------------------------------------------ From: Ryusuke Konishi <konishi.ryusuke@xxxxxxxxx> Subject: nilfs2: use kthread_create and kthread_stop for the log writer thread Date: Tue, 27 Aug 2024 02:41:15 +0900 By using kthread_create() and kthread_stop() to start and stop the log writer thread, eliminate custom thread start and stop helpers, as well as the wait queue "sc_wait_task" on the "nilfs_sc_info" struct and NILFS_SEGCTOR_QUIT flag that exist only to implement them. Also, update the kernel doc comments of the changed functions as appropriate. Link: https://lkml.kernel.org/r/20240826174116.5008-8-konishi.ryusuke@xxxxxxxxx Signed-off-by: Ryusuke Konishi <konishi.ryusuke@xxxxxxxxx> Cc: Huang Xiaojia <huangxiaojia2@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/nilfs2/segment.c | 82 +++++++++++++++--------------------------- fs/nilfs2/segment.h | 3 - 2 files changed, 31 insertions(+), 54 deletions(-) --- a/fs/nilfs2/segment.c~nilfs2-use-kthread_create-and-kthread_stop-for-the-log-writer-thread +++ a/fs/nilfs2/segment.c @@ -2628,11 +2628,15 @@ static int nilfs_segctor_flush_mode(stru } /** - * nilfs_segctor_thread - main loop of the segment constructor thread. + * nilfs_segctor_thread - main loop of the log writer thread * @arg: pointer to a struct nilfs_sc_info. * - * nilfs_segctor_thread() initializes a timer and serves as a daemon - * to execute segment constructions. + * nilfs_segctor_thread() is the main loop function of the log writer kernel + * thread, which determines whether log writing is necessary, and if so, + * performs the log write in the background, or waits if not. It is also + * used to decide the background writeback of the superblock. + * + * Return: Always 0. */ static int nilfs_segctor_thread(void *arg) { @@ -2640,11 +2644,6 @@ static int nilfs_segctor_thread(void *ar struct the_nilfs *nilfs = sci->sc_super->s_fs_info; int timeout = 0; - timer_setup(&sci->sc_timer, nilfs_construction_timeout, 0); - - /* start sync. */ - sci->sc_task = current; - wake_up(&sci->sc_wait_task); /* for nilfs_segctor_start_thread() */ nilfs_info(sci->sc_super, "segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds", sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ); @@ -2655,7 +2654,7 @@ static int nilfs_segctor_thread(void *ar for (;;) { int mode; - if (sci->sc_state & NILFS_SEGCTOR_QUIT) + if (kthread_should_stop()) goto end_thread; if (timeout || sci->sc_seq_request != sci->sc_seq_done) @@ -2709,41 +2708,10 @@ static int nilfs_segctor_thread(void *ar /* end sync. */ sci->sc_task = NULL; timer_shutdown_sync(&sci->sc_timer); - wake_up(&sci->sc_wait_task); /* for nilfs_segctor_kill_thread() */ spin_unlock(&sci->sc_state_lock); return 0; } -static int nilfs_segctor_start_thread(struct nilfs_sc_info *sci) -{ - struct task_struct *t; - - t = kthread_run(nilfs_segctor_thread, sci, "segctord"); - if (IS_ERR(t)) { - int err = PTR_ERR(t); - - nilfs_err(sci->sc_super, "error %d creating segctord thread", - err); - return err; - } - wait_event(sci->sc_wait_task, sci->sc_task != NULL); - return 0; -} - -static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) - __acquires(&sci->sc_state_lock) - __releases(&sci->sc_state_lock) -{ - sci->sc_state |= NILFS_SEGCTOR_QUIT; - - while (sci->sc_task) { - wake_up(&sci->sc_wait_daemon); - spin_unlock(&sci->sc_state_lock); - wait_event(sci->sc_wait_task, sci->sc_task == NULL); - spin_lock(&sci->sc_state_lock); - } -} - /* * Setup & clean-up functions */ @@ -2764,7 +2732,6 @@ static struct nilfs_sc_info *nilfs_segct init_waitqueue_head(&sci->sc_wait_request); init_waitqueue_head(&sci->sc_wait_daemon); - init_waitqueue_head(&sci->sc_wait_task); spin_lock_init(&sci->sc_state_lock); INIT_LIST_HEAD(&sci->sc_dirty_files); INIT_LIST_HEAD(&sci->sc_segbufs); @@ -2819,8 +2786,12 @@ static void nilfs_segctor_destroy(struct up_write(&nilfs->ns_segctor_sem); + if (sci->sc_task) { + wake_up(&sci->sc_wait_daemon); + kthread_stop(sci->sc_task); + } + spin_lock(&sci->sc_state_lock); - nilfs_segctor_kill_thread(sci); flag = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) || sci->sc_flush_request || sci->sc_seq_request != sci->sc_seq_done); spin_unlock(&sci->sc_state_lock); @@ -2868,14 +2839,15 @@ static void nilfs_segctor_destroy(struct * This allocates a log writer object, initializes it, and starts the * log writer. * - * Return Value: On success, 0 is returned. On error, one of the following - * negative error code is returned. - * - * %-ENOMEM - Insufficient memory available. + * Return: 0 on success, or the following negative error code on failure. + * * %-EINTR - Log writer thread creation failed due to interruption. + * * %-ENOMEM - Insufficient memory available. */ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root) { struct the_nilfs *nilfs = sb->s_fs_info; + struct nilfs_sc_info *sci; + struct task_struct *t; int err; if (nilfs->ns_writer) { @@ -2888,15 +2860,23 @@ int nilfs_attach_log_writer(struct super return 0; } - nilfs->ns_writer = nilfs_segctor_new(sb, root); - if (!nilfs->ns_writer) + sci = nilfs_segctor_new(sb, root); + if (unlikely(!sci)) return -ENOMEM; - err = nilfs_segctor_start_thread(nilfs->ns_writer); - if (unlikely(err)) + nilfs->ns_writer = sci; + t = kthread_create(nilfs_segctor_thread, sci, "segctord"); + if (IS_ERR(t)) { + err = PTR_ERR(t); + nilfs_err(sb, "error %d creating segctord thread", err); nilfs_detach_log_writer(sb); + return err; + } + sci->sc_task = t; + timer_setup(&sci->sc_timer, nilfs_construction_timeout, 0); - return err; + wake_up_process(sci->sc_task); + return 0; } /** --- a/fs/nilfs2/segment.h~nilfs2-use-kthread_create-and-kthread_stop-for-the-log-writer-thread +++ a/fs/nilfs2/segment.h @@ -105,7 +105,6 @@ struct nilfs_segsum_pointer { * @sc_flush_request: inode bitmap of metadata files to be flushed * @sc_wait_request: Client request queue * @sc_wait_daemon: Daemon wait queue - * @sc_wait_task: Start/end wait queue to control segctord task * @sc_seq_request: Request counter * @sc_seq_accepted: Accepted request count * @sc_seq_done: Completion counter @@ -158,7 +157,6 @@ struct nilfs_sc_info { wait_queue_head_t sc_wait_request; wait_queue_head_t sc_wait_daemon; - wait_queue_head_t sc_wait_task; __u32 sc_seq_request; __u32 sc_seq_accepted; @@ -191,7 +189,6 @@ enum { }; /* sc_state */ -#define NILFS_SEGCTOR_QUIT 0x0001 /* segctord is being destroyed */ #define NILFS_SEGCTOR_COMMIT 0x0004 /* committed transaction exists */ /* _ Patches currently in -mm which might be from konishi.ryusuke@xxxxxxxxx are