Skip to contentSkip to conversation

dm: use percpu counters

PATCH In review Mikulas Patocka 1 participant 1 message Nov 6, 2018 Device mapper

lore
Share & tools
lore

Mikulas Patocka

author maintainer
#0 lore raw

PATCH 4/5 dm: use percpu counters

Use percpu inflight counters to avoid cache line bouncing and improve performance.

---
 drivers/md/dm-core.h |    5 ++++
 drivers/md/dm-rq.c   |   10 +++++++--
 drivers/md/dm.c      |   52 +++++++++++++++++++++++++++++++++++----------------
 3 files changed, 49 insertions(+), 18 deletions(-)
drivers/md/dm-core.h +5 -0
Index: linux-2.6/drivers/md/dm-core.h
===================================================================
@@ -24,6 +24,10 @@ struct dm_kobject_holder {
 	struct completion completion;
 };
 
+struct dm_percpu {
+	unsigned inflight[2];
+};
+
 /*
  * DM core internal structure that used directly by dm.c and dm-rq.c
  * DM targets must _not_ deference a mapped_device to directly access its members!
@@ -63,6 +67,7 @@ struct mapped_device {
 	/*
 	 * A list of ios that arrived while we were suspended.
 	 */
+	struct dm_percpu __percpu *counters;
 	struct work_struct work;
 	wait_queue_head_t wait;
 	spinlock_t deferred_lock;
drivers/md/dm.c +36 -16

92 lines not on this page · raw message

drivers/md/dm-rq.c +8 -2
Index: linux-2.6/drivers/md/dm-rq.c
===================================================================
@@ -172,6 +172,12 @@ static void rq_end_stats(struct mapped_d
 	}
 }
 
+static unsigned rq_md_in_flight(struct mapped_device *md)
+{
+	return	atomic_read(&dm_disk(md)->part0.in_flight[READ]) +
+		atomic_read(&dm_disk(md)->part0.in_flight[WRITE]);
+}
+
 /*
  * Don't touch any member of the md after calling this function because
  * the md may be freed in dm_put() at the end of this function.
@@ -185,7 +191,7 @@ static void rq_completed(struct mapped_d
 	atomic_dec(&dm_disk(md)->part0.in_flight[rw]);
 
 	/* nudge anyone waiting on suspend queue */
-	if (!md_in_flight(md))
+	if (!rq_md_in_flight(md))
 		wake_up(&md->wait);
 
 	/*
@@ -674,7 +680,7 @@ static void dm_old_request_fn(struct req
 			pos = blk_rq_pos(rq);
 
 		if ((dm_old_request_peeked_before_merge_deadline(md) &&
-		     md_in_flight(md) && rq->bio && !bio_multiple_segments(rq->bio) &&
+		     rq_md_in_flight(md) && rq->bio && !bio_multiple_segments(rq->bio) &&
 		     md->last_rq_pos == pos && md->last_rq_rw == rq_data_dir(rq)) ||
 		    (ti->type->busy && ti->type->busy(ti))) {
 			blk_delay_queue(q, 10);