Commit b4e75cbf authored by Sam Bradshaw's avatar Sam Bradshaw Committed by Matthew Wilcox

NVMe: Adhere to request queue block accounting enable/disable

Recently, a new sysfs control "iostats" was added to selectively
enable or disable io statistics collection for request queues.  This
patch hooks that control.

IO statistics collection is rather expensive on large, multi-node
machines with drives pushing millions of iops.  Having the ability to
disable collection if not needed can improve throughput significantly.

As a data point, on a quad E5-4640, I see more than 50% throughput
improvement when io statistics accounting is disabled during heavily
multi-threaded small block random read benchmarks where device
performance is in the million iops+ range.
Signed-off-by: default avatarSam Bradshaw <sbradshaw@micron.com>
Signed-off-by: default avatarMatthew Wilcox <matthew.r.wilcox@intel.com>
parent a51afb54
...@@ -406,18 +406,22 @@ void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod) ...@@ -406,18 +406,22 @@ void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod)
static void nvme_start_io_acct(struct bio *bio) static void nvme_start_io_acct(struct bio *bio)
{ {
struct gendisk *disk = bio->bi_bdev->bd_disk; struct gendisk *disk = bio->bi_bdev->bd_disk;
if (blk_queue_io_stat(disk->queue)) {
const int rw = bio_data_dir(bio); const int rw = bio_data_dir(bio);
int cpu = part_stat_lock(); int cpu = part_stat_lock();
part_round_stats(cpu, &disk->part0); part_round_stats(cpu, &disk->part0);
part_stat_inc(cpu, &disk->part0, ios[rw]); part_stat_inc(cpu, &disk->part0, ios[rw]);
part_stat_add(cpu, &disk->part0, sectors[rw], bio_sectors(bio)); part_stat_add(cpu, &disk->part0, sectors[rw],
bio_sectors(bio));
part_inc_in_flight(&disk->part0, rw); part_inc_in_flight(&disk->part0, rw);
part_stat_unlock(); part_stat_unlock();
}
} }
static void nvme_end_io_acct(struct bio *bio, unsigned long start_time) static void nvme_end_io_acct(struct bio *bio, unsigned long start_time)
{ {
struct gendisk *disk = bio->bi_bdev->bd_disk; struct gendisk *disk = bio->bi_bdev->bd_disk;
if (blk_queue_io_stat(disk->queue)) {
const int rw = bio_data_dir(bio); const int rw = bio_data_dir(bio);
unsigned long duration = jiffies - start_time; unsigned long duration = jiffies - start_time;
int cpu = part_stat_lock(); int cpu = part_stat_lock();
...@@ -425,6 +429,7 @@ static void nvme_end_io_acct(struct bio *bio, unsigned long start_time) ...@@ -425,6 +429,7 @@ static void nvme_end_io_acct(struct bio *bio, unsigned long start_time)
part_round_stats(cpu, &disk->part0); part_round_stats(cpu, &disk->part0);
part_dec_in_flight(&disk->part0, rw); part_dec_in_flight(&disk->part0, rw);
part_stat_unlock(); part_stat_unlock();
}
} }
static void bio_completion(struct nvme_queue *nvmeq, void *ctx, static void bio_completion(struct nvme_queue *nvmeq, void *ctx,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment