lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 23 Dec 2022 21:16:01 +0800
From:   Zqiang <qiang1.zhang@...el.com>
To:     pmladek@...e.com, akpm@...ux-foundation.org, frederic@...nel.org
Cc:     linux-kernel@...r.kernel.org
Subject: [PATCH] kthread_worker: Flush all delayed works when destroy kthread worker

When destroy a kthread worker, only flush all current works on
kthread worker, this is not very sufficient, there may be some
delayed works in the pending state, this commit therefore add
flush delayed works function in kthread_destroy_worker().

Signed-off-by: Zqiang <qiang1.zhang@...el.com>
---
 include/linux/kthread.h |  1 +
 kernel/kthread.c        | 31 +++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 30e5bec81d2b..8616228abb3b 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -206,6 +206,7 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker,
 
 void kthread_flush_work(struct kthread_work *work);
 void kthread_flush_worker(struct kthread_worker *worker);
+void kthread_flush_delayed_works(struct kthread_worker *worker);
 
 bool kthread_cancel_work_sync(struct kthread_work *work);
 bool kthread_cancel_delayed_work_sync(struct kthread_delayed_work *work);
diff --git a/kernel/kthread.c b/kernel/kthread.c
index f97fd01a2932..2744f6b769d1 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -1375,6 +1375,35 @@ void kthread_flush_worker(struct kthread_worker *worker)
 }
 EXPORT_SYMBOL_GPL(kthread_flush_worker);
 
+/**
+ * kthread_flush_delayed_works - flush all current delayed works on a
+ * kthread_worker.
+ * @worker: worker to flush
+ *
+ * Wait until all currently executing or pending delayed works are
+ * queued completed.
+ */
+void kthread_flush_delayed_works(struct kthread_worker *worker)
+{
+	unsigned long flags;
+	struct kthread_delayed_work *dwork;
+	struct kthread_work *work;
+
+	raw_spin_lock_irqsave(&worker->lock, flags);
+	while (!list_empty(&worker->delayed_work_list)) {
+		work = list_first_entry(&worker->delayed_work_list,
+					struct kthread_work, node);
+		list_del_init(&work->node);
+		dwork = container_of(work, struct kthread_delayed_work, work);
+		raw_spin_unlock_irqrestore(&worker->lock, flags);
+		if (del_timer_sync(&dwork->timer))
+			kthread_queue_work(worker, &dwork->work);
+		raw_spin_lock_irqsave(&worker->lock, flags);
+	}
+	raw_spin_unlock_irqrestore(&worker->lock, flags);
+}
+EXPORT_SYMBOL_GPL(kthread_flush_delayed_works);
+
 /**
  * kthread_destroy_worker - destroy a kthread worker
  * @worker: worker to be destroyed
@@ -1391,8 +1420,10 @@ void kthread_destroy_worker(struct kthread_worker *worker)
 	if (WARN_ON(!task))
 		return;
 
+	kthread_flush_delayed_works(worker);
 	kthread_flush_worker(worker);
 	kthread_stop(task);
+	WARN_ON(!list_empty(&worker->delayed_work_list));
 	WARN_ON(!list_empty(&worker->work_list));
 	kfree(worker);
 }
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ