mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Philipp Reisner <philipp.reisner@linbit.com>
To: linux-kernel@vger.kernel.org, Jens Axboe <axboe@kernel.dk>
Cc: drbd-dev@lists.linbit.com
Subject: [PATCH 07/27] drbd: Move cpu_mask from connection to resource
Date: Mon, 23 Dec 2013 22:50:36 +0100	[thread overview]
Message-ID: <1387835456-29695-8-git-send-email-philipp.reisner@linbit.com> (raw)
In-Reply-To: <1387835456-29695-1-git-send-email-philipp.reisner@linbit.com>

From: Andreas Gruenbacher <agruen@linbit.com>

Also fix drbd_calc_cpu_mask() to spread resources equally over all online cpus
independent of device minor numbers.

Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
---
 drivers/block/drbd/drbd_int.h  |    5 ++-
 drivers/block/drbd/drbd_main.c |   74 ++++++++++++++++++++++++----------------
 2 files changed, 47 insertions(+), 32 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d0defe8..d7eade8 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -579,6 +579,8 @@ struct drbd_resource {
 	unsigned susp:1;		/* IO suspended by user */
 	unsigned susp_nod:1;		/* IO suspended because no data */
 	unsigned susp_fen:1;		/* IO suspended because fence peer handler runs */
+
+	cpumask_var_t cpu_mask;
 };
 
 struct drbd_connection {
@@ -627,7 +629,6 @@ struct drbd_connection {
 	struct drbd_thread receiver;
 	struct drbd_thread worker;
 	struct drbd_thread asender;
-	cpumask_var_t cpu_mask;
 
 	/* sender side */
 	struct drbd_work_queue sender_work;
@@ -875,10 +876,8 @@ extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
 extern char *drbd_task_to_thread_name(struct drbd_connection *connection, struct task_struct *task);
 #ifdef CONFIG_SMP
 extern void drbd_thread_current_set_cpu(struct drbd_thread *thi);
-extern void drbd_calc_cpu_mask(struct drbd_connection *connection);
 #else
 #define drbd_thread_current_set_cpu(A) ({})
-#define drbd_calc_cpu_mask(A) ({})
 #endif
 extern void tl_release(struct drbd_connection *, unsigned int barrier_nr,
 		       unsigned int set_size);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index cab0641..718c3bd 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -513,28 +513,38 @@ int conn_lowest_minor(struct drbd_connection *connection)
 #ifdef CONFIG_SMP
 /**
  * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs
- * @device:	DRBD device.
  *
- * Forces all threads of a device onto the same CPU. This is beneficial for
+ * Forces all threads of a resource onto the same CPU. This is beneficial for
  * DRBD's performance. May be overwritten by user's configuration.
  */
-void drbd_calc_cpu_mask(struct drbd_connection *connection)
+static void drbd_calc_cpu_mask(cpumask_var_t *cpu_mask)
 {
-	int ord, cpu;
+	unsigned int *resources_per_cpu, min_index = ~0;
 
-	/* user override. */
-	if (cpumask_weight(connection->cpu_mask))
-		return;
+	resources_per_cpu = kzalloc(nr_cpu_ids * sizeof(*resources_per_cpu), GFP_KERNEL);
+	if (resources_per_cpu) {
+		struct drbd_resource *resource;
+		unsigned int cpu, min = ~0;
 
-	ord = conn_lowest_minor(connection) % cpumask_weight(cpu_online_mask);
-	for_each_online_cpu(cpu) {
-		if (ord-- == 0) {
-			cpumask_set_cpu(cpu, connection->cpu_mask);
-			return;
+		rcu_read_lock();
+		for_each_resource_rcu(resource, &drbd_resources) {
+			for_each_cpu(cpu, resource->cpu_mask)
+				resources_per_cpu[cpu]++;
 		}
+		rcu_read_unlock();
+		for_each_online_cpu(cpu) {
+			if (resources_per_cpu[cpu] < min) {
+				min = resources_per_cpu[cpu];
+				min_index = cpu;
+			}
+		}
+		kfree(resources_per_cpu);
+	}
+	if (min_index == ~0) {
+		cpumask_setall(*cpu_mask);
+		return;
 	}
-	/* should not be reached */
-	cpumask_setall(connection->cpu_mask);
+	cpumask_set_cpu(min_index, *cpu_mask);
 }
 
 /**
@@ -552,8 +562,10 @@ void drbd_thread_current_set_cpu(struct drbd_thread *thi)
 	if (!thi->reset_cpu_mask)
 		return;
 	thi->reset_cpu_mask = 0;
-	set_cpus_allowed_ptr(p, thi->connection->cpu_mask);
+	set_cpus_allowed_ptr(p, thi->connection->resource->cpu_mask);
 }
+#else
+#define drbd_calc_cpu_mask(A) ({})
 #endif
 
 /**
@@ -2289,6 +2301,7 @@ void drbd_destroy_resource(struct kref *kref)
 		container_of(kref, struct drbd_resource, kref);
 
 	idr_destroy(&resource->devices);
+	free_cpumask_var(resource->cpu_mask);
 	kfree(resource->name);
 	kfree(resource);
 }
@@ -2514,10 +2527,11 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_op
 		}
 	}
 	resource->res_opts = *res_opts;
-	for_each_connection_rcu(connection, resource) {
-		if (!cpumask_equal(connection->cpu_mask, new_cpu_mask)) {
-			cpumask_copy(connection->cpu_mask, new_cpu_mask);
-			drbd_calc_cpu_mask(connection);
+	if (cpumask_empty(new_cpu_mask))
+		drbd_calc_cpu_mask(&new_cpu_mask);
+	if (!cpumask_equal(resource->cpu_mask, new_cpu_mask)) {
+		cpumask_copy(resource->cpu_mask, new_cpu_mask);
+		for_each_connection_rcu(connection, resource) {
 			connection->receiver.reset_cpu_mask = 1;
 			connection->asender.reset_cpu_mask = 1;
 			connection->worker.reset_cpu_mask = 1;
@@ -2537,12 +2551,12 @@ struct drbd_resource *drbd_create_resource(const char *name)
 
 	resource = kzalloc(sizeof(struct drbd_resource), GFP_KERNEL);
 	if (!resource)
-		return NULL;
+		goto fail;
 	resource->name = kstrdup(name, GFP_KERNEL);
-	if (!resource->name) {
-		kfree(resource);
-		return NULL;
-	}
+	if (!resource->name)
+		goto fail_free_resource;
+	if (!zalloc_cpumask_var(&resource->cpu_mask, GFP_KERNEL))
+		goto fail_free_name;
 	kref_init(&resource->kref);
 	idr_init(&resource->devices);
 	INIT_LIST_HEAD(&resource->connections);
@@ -2550,6 +2564,13 @@ struct drbd_resource *drbd_create_resource(const char *name)
 	mutex_init(&resource->conf_update);
 	spin_lock_init(&resource->req_lock);
 	return resource;
+
+fail_free_name:
+	kfree(resource->name);
+fail_free_resource:
+	kfree(resource);
+fail:
+	return NULL;
 }
 
 /* caller must be under genl_lock() */
@@ -2567,9 +2588,6 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
 	if (drbd_alloc_socket(&connection->meta))
 		goto fail;
 
-	if (!zalloc_cpumask_var(&connection->cpu_mask, GFP_KERNEL))
-		goto fail;
-
 	connection->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL);
 	if (!connection->current_epoch)
 		goto fail;
@@ -2618,7 +2636,6 @@ fail_resource:
 	drbd_free_resource(resource);
 fail:
 	kfree(connection->current_epoch);
-	free_cpumask_var(connection->cpu_mask);
 	drbd_free_socket(&connection->meta);
 	drbd_free_socket(&connection->data);
 	kfree(connection);
@@ -2636,7 +2653,6 @@ void drbd_destroy_connection(struct kref *kref)
 
 	idr_destroy(&connection->peer_devices);
 
-	free_cpumask_var(connection->cpu_mask);
 	drbd_free_socket(&connection->meta);
 	drbd_free_socket(&connection->data);
 	kfree(connection->int_dig_in);
-- 
1.7.9.5


  parent reply	other threads:[~2013-12-23 22:06 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-23 21:50 [PATCH 00/27] DRBD code reorganization Philipp Reisner
2013-12-23 21:50 ` [PATCH 01/27] drbd: Rename net_conf variables old_conf -> old_net_conf and new_conf -> new_net_conf Philipp Reisner
2013-12-23 21:50 ` [PATCH 02/27] drbd: Iterate over all connections Philipp Reisner
2013-12-23 21:50 ` [PATCH 03/27] drbd: drbd_adm_prepare(): Only set adm_ctx.connection when a connection is requested Philipp Reisner
2013-12-23 21:50 ` [PATCH 04/27] drbd: Move conf_mutex from connection to resource Philipp Reisner
2013-12-23 21:50 ` [PATCH 05/27] drbd: Move susp, susp_nod, susp_fen " Philipp Reisner
2013-12-23 21:50 ` [PATCH 06/27] drbd: Define the size of res_opts->cpu_mask in a single place Philipp Reisner
2013-12-23 21:50 ` Philipp Reisner [this message]
2013-12-23 21:50 ` [PATCH 08/27] drbd: Rename drbdd_init() -> drbd_receiver() Philipp Reisner
2013-12-23 21:50 ` [PATCH 09/27] drbd: Function prototype cleanups Philipp Reisner
2013-12-23 21:50 ` [PATCH 10/27] drbd: drbd_csum_bio(), drbd_csum_ee(): Remove unused device argument Philipp Reisner
2013-12-23 21:50 ` [PATCH 11/27] drbd: Replace vnr_to_mdev() with conn_peer_device() Philipp Reisner
2013-12-23 21:50 ` [PATCH 12/27] drbd: Pass a peer device to a number of fuctions Philipp Reisner
2013-12-23 21:50 ` [PATCH 13/27] drbd: Kill drbd_task_to_thread_name() Philipp Reisner
2013-12-23 21:50 ` [PATCH 14/27] drbd: Remove useless assertion Philipp Reisner
2013-12-23 21:50 ` [PATCH 15/27] drbd: Move string function prototypes from linux/drbd.h to drbd_string.h Philipp Reisner
2013-12-23 21:50 ` [PATCH 16/27] drbd: Rename w_prev_work_done -> w_complete Philipp Reisner
2013-12-23 21:50 ` [PATCH 17/27] drbd: Create a dedicated struct drbd_device_work Philipp Reisner
2013-12-23 21:50 ` [PATCH 18/27] drbd: Turn conn_flush_workqueue() into drbd_flush_workqueue() Philipp Reisner
2013-12-23 21:50 ` [PATCH 19/27] drbd: struct after_conn_state_chg_work: Use drbd_work instead of drbd_device_work Philipp Reisner
2013-12-23 21:50 ` [PATCH 20/27] drbd: struct drbd_peer_request: " Philipp Reisner
2013-12-23 21:50 ` [PATCH 21/27] drbd: Make w_make_resync_request() static Philipp Reisner
2013-12-23 21:50 ` [PATCH 22/27] drbd: Turn w_make_ov_request and make_resync_request into "normal" functions Philipp Reisner
2013-12-23 21:50 ` [PATCH 23/27] drbd: In the worker thread, process drbd_work instead of drbd_device_work items Philipp Reisner
2013-12-23 21:50 ` [PATCH 24/27] drbd: Get rid of first_peer_device() in handle_write_conflicts() Philipp Reisner
2013-12-23 21:50 ` [PATCH 25/27] drbd: Remove unused parameter of wire_flags_to_bio() Philipp Reisner
2013-12-23 21:50 ` [PATCH 26/27] drbd: Use the right peer device Philipp Reisner
2013-12-23 21:50 ` [PATCH 27/27] drbd: Add drbd_thread->resource and make drbd_thread->connection optional Philipp Reisner

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=1387835456-29695-8-git-send-email-philipp.reisner@linbit.com \
    --to=philipp.reisner@linbit.com \
    --cc=axboe@kernel.dk \
    --cc=drbd-dev@lists.linbit.com \
    --cc=linux-kernel@vger.kernel.org \
    /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

all inboxes | Powered by JetHome®