aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Bradshaw <sbradshaw@micron.com>2014-05-09 16:27:07 -0400
committerMatthew Wilcox <matthew.r.wilcox@intel.com>2014-06-03 22:58:54 -0400
commitb4e75cbf1364c4bbce3599c3279892a55b6ede07 (patch)
tree9387e92ae6a0b2e6e491e3332c2d89d3a5b95469
parenta51afb54339c5e9ee72df66ae0f2ac5aacfed365 (diff)
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: Sam Bradshaw <sbradshaw@micron.com> Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
-rw-r--r--drivers/block/nvme-core.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 29a3e85873b5..bb6ce311ad44 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -406,25 +406,30 @@ void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod)
406static void nvme_start_io_acct(struct bio *bio) 406static void nvme_start_io_acct(struct bio *bio)
407{ 407{
408 struct gendisk *disk = bio->bi_bdev->bd_disk; 408 struct gendisk *disk = bio->bi_bdev->bd_disk;
409 const int rw = bio_data_dir(bio); 409 if (blk_queue_io_stat(disk->queue)) {
410 int cpu = part_stat_lock(); 410 const int rw = bio_data_dir(bio);
411 part_round_stats(cpu, &disk->part0); 411 int cpu = part_stat_lock();
412 part_stat_inc(cpu, &disk->part0, ios[rw]); 412 part_round_stats(cpu, &disk->part0);
413 part_stat_add(cpu, &disk->part0, sectors[rw], bio_sectors(bio)); 413 part_stat_inc(cpu, &disk->part0, ios[rw]);
414 part_inc_in_flight(&disk->part0, rw); 414 part_stat_add(cpu, &disk->part0, sectors[rw],
415 part_stat_unlock(); 415 bio_sectors(bio));
416 part_inc_in_flight(&disk->part0, rw);
417 part_stat_unlock();
418 }
416} 419}
417 420
418static void nvme_end_io_acct(struct bio *bio, unsigned long start_time) 421static void nvme_end_io_acct(struct bio *bio, unsigned long start_time)
419{ 422{
420 struct gendisk *disk = bio->bi_bdev->bd_disk; 423 struct gendisk *disk = bio->bi_bdev->bd_disk;
421 const int rw = bio_data_dir(bio); 424 if (blk_queue_io_stat(disk->queue)) {
422 unsigned long duration = jiffies - start_time; 425 const int rw = bio_data_dir(bio);
423 int cpu = part_stat_lock(); 426 unsigned long duration = jiffies - start_time;
424 part_stat_add(cpu, &disk->part0, ticks[rw], duration); 427 int cpu = part_stat_lock();
425 part_round_stats(cpu, &disk->part0); 428 part_stat_add(cpu, &disk->part0, ticks[rw], duration);
426 part_dec_in_flight(&disk->part0, rw); 429 part_round_stats(cpu, &disk->part0);
427 part_stat_unlock(); 430 part_dec_in_flight(&disk->part0, rw);
431 part_stat_unlock();
432 }
428} 433}
429 434
430static void bio_completion(struct nvme_queue *nvmeq, void *ctx, 435static void bio_completion(struct nvme_queue *nvmeq, void *ctx,