mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Minchan Kim <minchan@kernel.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
	linux-kernel@vger.kernel.org, Minchan Kim <minchan@kernel.org>
Subject: [PATCH 3/3] zram: adjust the number of zram thread
Date: Thu, 22 Sep 2016 15:42:45 +0900	[thread overview]
Message-ID: <1474526565-6676-3-git-send-email-minchan@kernel.org> (raw)
In-Reply-To: <1474526565-6676-1-git-send-email-minchan@kernel.org>

It's pointless to keep many workers greater than the number of
online CPU so adjust the number of worker whenever changing
online CPU number.

Signed-off-by: Minchan Kim <minchan@kernel.org>
---
 drivers/block/zram/zram_drv.c | 94 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 71 insertions(+), 23 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index abab76e2cf28..a930f96f01ab 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -31,6 +31,7 @@
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/sysfs.h>
+#include <linux/cpu.h>
 
 #include "zram_drv.h"
 
@@ -987,6 +988,8 @@ struct zram_workers {
 	struct list_head worker_list;
 	wait_queue_head_t req_wait;
 	spinlock_t req_lock;
+
+	struct notifier_block notifier;
 } workers;
 
 struct bio_request {
@@ -1269,52 +1272,97 @@ static int zram_thread(void *data)
 	return 0;
 }
 
-static void destroy_workers(void)
+static int __zram_cpu_notifier(void *dummy, unsigned long action,
+				unsigned long cpu)
 {
 	struct zram_worker *worker;
 
-	while (!list_empty(&workers.worker_list)) {
+	switch (action) {
+	case CPU_UP_PREPARE:
+		worker = kmalloc(sizeof(*worker), GFP_KERNEL);
+		if (!worker) {
+			pr_err("Can't allocate a worker\n");
+			return NOTIFY_BAD;
+		}
+
+		worker->task = kthread_run(zram_thread, NULL, "zramd-%lu", cpu);
+		if (IS_ERR(worker->task)) {
+			kfree(worker);
+			pr_err("Can't allocate a zram thread\n");
+			return NOTIFY_BAD;
+		}
+
+		spin_lock(&workers.req_lock);
+		list_add(&worker->list, &workers.worker_list);
+		spin_unlock(&workers.req_lock);
+		break;
+	case CPU_DEAD:
+	case CPU_UP_CANCELED:
+		spin_lock(&workers.req_lock);
+		WARN_ON(list_empty(&workers.worker_list));
+
 		worker = list_first_entry(&workers.worker_list,
-				struct zram_worker,
-				list);
-		kthread_stop(worker->task);
+					struct zram_worker, list);
 		list_del(&worker->list);
+		spin_unlock(&workers.req_lock);
+
+		kthread_stop(worker->task);
 		kfree(worker);
+		break;
+	default:
+		break;
 	}
+	return NOTIFY_OK;
+}
+
+static int zram_cpu_notifier(struct notifier_block *nb,
+		unsigned long action, void *pcpu)
+{
+	unsigned long cpu = (unsigned long)pcpu;
+
+	return __zram_cpu_notifier(NULL, action, cpu);
+}
+
+static void destroy_workers(void)
+{
+	unsigned long cpu;
+
+	cpu_notifier_register_begin();
+	for_each_online_cpu(cpu)
+		__zram_cpu_notifier(NULL, CPU_UP_CANCELED, cpu);
+	__unregister_cpu_notifier(&workers.notifier);
+	cpu_notifier_register_done();
 
 	WARN_ON(workers.nr_running);
 }
 
 static int create_workers(void)
 {
-	int i;
-	int nr_cpu = num_online_cpus();
-	struct zram_worker *worker;
+	int cpu;
 
 	INIT_LIST_HEAD(&workers.worker_list);
 	INIT_LIST_HEAD(&workers.req_list);
 	spin_lock_init(&workers.req_lock);
 	init_waitqueue_head(&workers.req_wait);
 
-	for (i = 0; i < nr_cpu; i++) {
-		worker = kmalloc(sizeof(*worker), GFP_KERNEL);
-		if (!worker)
-			goto error;
-
-		worker->task = kthread_run(zram_thread, NULL, "zramd-%d", i);
-		if (IS_ERR(worker->task)) {
-			kfree(worker);
-			goto error;
-		}
-
-		list_add(&worker->list, &workers.worker_list);
+	workers.notifier.notifier_call = zram_cpu_notifier;
+	cpu_notifier_register_begin();
+	for_each_online_cpu(cpu) {
+		if (__zram_cpu_notifier(NULL, CPU_UP_PREPARE, cpu) ==
+				NOTIFY_BAD)
+			goto cleanup;
 	}
 
+	__register_cpu_notifier(&workers.notifier);
+	cpu_notifier_register_done();
+
 	return 0;
+cleanup:
+	for_each_online_cpu(cpu)
+		__zram_cpu_notifier(NULL, CPU_UP_CANCELED, cpu);
+	cpu_notifier_register_done();
 
-error:
-	destroy_workers();
-	return 1;
+	return -ENOMEM;
 }
 
 static int zram_rw_async_page(struct zram *zram,
-- 
2.7.4

  parent reply	other threads:[~2016-09-22  6:49 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-22  6:42 [PATCH 1/3] zram: rename IO processing functions Minchan Kim
2016-09-22  6:42 ` [PATCH 2/3] zram: support page-based parallel write Minchan Kim
2016-09-29  3:18   ` Sergey Senozhatsky
2016-09-30  5:52     ` Minchan Kim
2016-10-04  4:43       ` Sergey Senozhatsky
2016-10-04  7:35         ` Minchan Kim
2016-10-05  2:01         ` Minchan Kim
2016-10-06  8:29           ` Sergey Senozhatsky
2016-10-07  6:33             ` Minchan Kim
2016-10-07 18:08               ` Sergey Senozhatsky
2016-10-17  5:04               ` Minchan Kim
2016-10-21  6:08                 ` Sergey Senozhatsky
2016-10-24  4:51                   ` Minchan Kim
2016-10-21  6:03   ` Sergey Senozhatsky
2016-10-24  4:47     ` Minchan Kim
2016-10-24  5:20       ` Sergey Senozhatsky
2016-10-24  5:58         ` Minchan Kim
2016-10-24  7:23           ` Sergey Senozhatsky
2016-09-22  6:42 ` Minchan Kim [this message]
2016-10-21  6:23   ` [PATCH 3/3] zram: adjust the number of zram thread Sergey Senozhatsky
2016-10-24  4:54     ` Minchan Kim
2016-10-24  5:29       ` Sergey Senozhatsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1474526565-6676-3-git-send-email-minchan@kernel.org \
    --to=minchan@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sergey.senozhatsky@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome