From patchwork Wed Nov 28 00:42:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 10701671 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4FAFF14D6 for ; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3E0502C90A for ; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 325D82C915; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,SUBJ_OBFU_PUNCT_FEW autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 791DB2C910 for ; Wed, 28 Nov 2018 00:43:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726907AbeK1Lmm (ORCPT ); Wed, 28 Nov 2018 06:42:42 -0500 Received: from 109-183-129-149.customers.tmcz.cz ([109.183.129.149]:56968 "EHLO leontynka.twibright.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726418AbeK1Lml (ORCPT ); Wed, 28 Nov 2018 06:42:41 -0500 Received: from debian.vm ([192.168.192.2]) by leontynka.twibright.com with smtp (Exim 4.89) (envelope-from ) id 1gRnwH-0007s3-Kx; Wed, 28 Nov 2018 01:42:50 +0100 Received: by debian.vm (sSMTP sendmail emulation); Wed, 28 Nov 2018 01:42:49 +0100 Message-Id: <20181128004249.147084927@debian.vm> User-Agent: quilt/0.65 Date: Wed, 28 Nov 2018 01:42:12 +0100 From: Mikulas Patocka To: Jens Axboe Cc: Mike Snitzer , dm-devel@redhat.com, linux-block@vger.kernel.org, "Alasdair G. Kergon" , Christoph Hellwig , Mikulas Patocka Subject: [PATCH 1/3] block: delete part_round_stats and switch to less precise counting MIME-Version: 1.0 Content-Disposition: inline; filename=block-delete-part_round_stats.patch Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We want to convert to per-cpu in_flight counters. The function part_round_stats needs the in_flight counter every jiffy, it would be too costly to sum all the percpu variables every jiffy, so it must be deleted. part_round_stats is used to calculate two counters - time_in_queue and io_ticks. time_in_queue can be calculated without part_round_stats, by adding the duration of the I/O when the I/O ends (the value is almost as exact as the previously calculated value, except that time for in-progress I/Os is not counted). io_ticks can be approximated by increasing the value when I/O is started or ended and the jiffies value has changed. If the I/Os take less than a jiffy, the value is as exact as the previously calculated value. If the I/Os take more than a jiffy, io_ticks can drift behind the previously calculated value. Signed-off-by: Mikulas Patocka --- block/bio.c | 26 ++++++++++++++++-- block/blk-core.c | 64 +++------------------------------------------- block/blk-merge.c | 1 block/genhd.c | 4 -- block/partition-generic.c | 4 -- include/linux/genhd.h | 3 -- 6 files changed, 29 insertions(+), 73 deletions(-) Index: linux-block/block/bio.c =================================================================== --- linux-block.orig/block/bio.c 2018-11-26 23:44:17.000000000 +0100 +++ linux-block/block/bio.c 2018-11-26 23:44:17.000000000 +0100 @@ -1663,13 +1663,29 @@ defer: } EXPORT_SYMBOL_GPL(bio_check_pages_dirty); +void update_io_ticks(int cpu, struct hd_struct *part, unsigned long now) +{ + unsigned long stamp; +again: + stamp = READ_ONCE(part->stamp); + if (unlikely(stamp != now)) { + if (likely(cmpxchg(&part->stamp, stamp, now) == stamp)) { + __part_stat_add(cpu, part, io_ticks, 1); + } + } + if (part->partno) { + part = &part_to_disk(part)->part0; + goto again; + } +} + void generic_start_io_acct(struct request_queue *q, int op, unsigned long sectors, struct hd_struct *part) { const int sgrp = op_stat_group(op); int cpu = part_stat_lock(); - part_round_stats(q, cpu, part); + update_io_ticks(cpu, part, jiffies); part_stat_inc(cpu, part, ios[sgrp]); part_stat_add(cpu, part, sectors[sgrp], sectors); part_inc_in_flight(q, part, op_is_write(op)); @@ -1681,12 +1697,16 @@ EXPORT_SYMBOL(generic_start_io_acct); void generic_end_io_acct(struct request_queue *q, int req_op, struct hd_struct *part, unsigned long start_time) { - unsigned long duration = jiffies - start_time; + unsigned long now = jiffies; + unsigned long duration = now - start_time; const int sgrp = op_stat_group(req_op); int cpu = part_stat_lock(); + update_io_ticks(cpu, part, now); part_stat_add(cpu, part, nsecs[sgrp], jiffies_to_nsecs(duration)); - part_round_stats(q, cpu, part); + part_stat_add(cpu, part, time_in_queue, duration); + if (part->partno) + part_stat_add(cpu, &part_to_disk(part)->part0, time_in_queue, duration); part_dec_in_flight(q, part, op_is_write(req_op)); part_stat_unlock(); Index: linux-block/block/blk-core.c =================================================================== --- linux-block.orig/block/blk-core.c 2018-11-26 23:44:17.000000000 +0100 +++ linux-block/block/blk-core.c 2018-11-26 23:44:17.000000000 +0100 @@ -583,63 +583,6 @@ struct request *blk_get_request(struct r } EXPORT_SYMBOL(blk_get_request); -static void part_round_stats_single(struct request_queue *q, int cpu, - struct hd_struct *part, unsigned long now, - unsigned int inflight) -{ - if (inflight) { - __part_stat_add(cpu, part, time_in_queue, - inflight * (now - part->stamp)); - __part_stat_add(cpu, part, io_ticks, (now - part->stamp)); - } - part->stamp = now; -} - -/** - * part_round_stats() - Round off the performance stats on a struct disk_stats. - * @q: target block queue - * @cpu: cpu number for stats access - * @part: target partition - * - * The average IO queue length and utilisation statistics are maintained - * by observing the current state of the queue length and the amount of - * time it has been in this state for. - * - * Normally, that accounting is done on IO completion, but that can result - * in more than a second's worth of IO being accounted for within any one - * second, leading to >100% utilisation. To deal with that, we call this - * function to do a round-off before returning the results when reading - * /proc/diskstats. This accounts immediately for all queue usage up to - * the current jiffies and restarts the counters again. - */ -void part_round_stats(struct request_queue *q, int cpu, struct hd_struct *part) -{ - struct hd_struct *part2 = NULL; - unsigned long now = jiffies; - unsigned int inflight[2]; - int stats = 0; - - if (part->stamp != now) - stats |= 1; - - if (part->partno) { - part2 = &part_to_disk(part)->part0; - if (part2->stamp != now) - stats |= 2; - } - - if (!stats) - return; - - part_in_flight(q, part, inflight); - - if (stats & 2) - part_round_stats_single(q, cpu, part2, now, inflight[1]); - if (stats & 1) - part_round_stats_single(q, cpu, part, now, inflight[0]); -} -EXPORT_SYMBOL_GPL(part_round_stats); - void blk_put_request(struct request *req) { blk_mq_free_request(req); @@ -1408,9 +1351,11 @@ void blk_account_io_done(struct request cpu = part_stat_lock(); part = req->part; + update_io_ticks(cpu, part, jiffies); part_stat_inc(cpu, part, ios[sgrp]); part_stat_add(cpu, part, nsecs[sgrp], now - req->start_time_ns); - part_round_stats(req->q, cpu, part); + part_stat_add(cpu, part, time_in_queue, nsecs_to_jiffies64(now - req->start_time_ns)); + part_stat_add(cpu, &part_to_disk(part)->part0, time_in_queue, nsecs_to_jiffies64(now - req->start_time_ns)); part_dec_in_flight(req->q, part, rq_data_dir(req)); hd_struct_put(part); @@ -1446,11 +1391,12 @@ void blk_account_io_start(struct request part = &rq->rq_disk->part0; hd_struct_get(part); } - part_round_stats(rq->q, cpu, part); part_inc_in_flight(rq->q, part, rw); rq->part = part; } + update_io_ticks(cpu, part, jiffies); + part_stat_unlock(); } Index: linux-block/block/blk-merge.c =================================================================== --- linux-block.orig/block/blk-merge.c 2018-11-26 23:44:17.000000000 +0100 +++ linux-block/block/blk-merge.c 2018-11-26 23:44:17.000000000 +0100 @@ -690,7 +690,6 @@ static void blk_account_io_merge(struct cpu = part_stat_lock(); part = req->part; - part_round_stats(req->q, cpu, part); part_dec_in_flight(req->q, part, rq_data_dir(req)); hd_struct_put(part); Index: linux-block/block/genhd.c =================================================================== --- linux-block.orig/block/genhd.c 2018-11-26 23:44:17.000000000 +0100 +++ linux-block/block/genhd.c 2018-11-26 23:44:17.000000000 +0100 @@ -1326,7 +1326,6 @@ static int diskstats_show(struct seq_fil struct hd_struct *hd; char buf[BDEVNAME_SIZE]; unsigned int inflight[2]; - int cpu; /* if (&disk_to_dev(gp)->kobj.entry == block_class.devices.next) @@ -1338,9 +1337,6 @@ static int diskstats_show(struct seq_fil disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0); while ((hd = disk_part_iter_next(&piter))) { - cpu = part_stat_lock(); - part_round_stats(gp->queue, cpu, hd); - part_stat_unlock(); part_in_flight(gp->queue, hd, inflight); seq_printf(seqf, "%4d %7d %s " "%lu %lu %lu %u " Index: linux-block/block/partition-generic.c =================================================================== --- linux-block.orig/block/partition-generic.c 2018-11-26 23:44:17.000000000 +0100 +++ linux-block/block/partition-generic.c 2018-11-26 23:44:17.000000000 +0100 @@ -121,11 +121,7 @@ ssize_t part_stat_show(struct device *de struct hd_struct *p = dev_to_part(dev); struct request_queue *q = part_to_disk(p)->queue; unsigned int inflight[2]; - int cpu; - cpu = part_stat_lock(); - part_round_stats(q, cpu, p); - part_stat_unlock(); part_in_flight(q, p, inflight); return sprintf(buf, "%8lu %8lu %8llu %8u " Index: linux-block/include/linux/genhd.h =================================================================== --- linux-block.orig/include/linux/genhd.h 2018-11-26 23:44:17.000000000 +0100 +++ linux-block/include/linux/genhd.h 2018-11-26 23:44:17.000000000 +0100 @@ -398,8 +398,7 @@ static inline void free_part_info(struct kfree(part->info); } -/* block/blk-core.c */ -extern void part_round_stats(struct request_queue *q, int cpu, struct hd_struct *part); +void update_io_ticks(int cpu, struct hd_struct *part, unsigned long now); /* block/genhd.c */ extern void device_add_disk(struct device *parent, struct gendisk *disk, From patchwork Wed Nov 28 00:42:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 10701673 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6D53718B8 for ; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5B71A2C90A for ; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4733F2C921; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A48FD2C91D for ; Wed, 28 Nov 2018 00:43:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726457AbeK1Lmm (ORCPT ); Wed, 28 Nov 2018 06:42:42 -0500 Received: from 109-183-129-149.customers.tmcz.cz ([109.183.129.149]:56966 "EHLO leontynka.twibright.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726500AbeK1Lmm (ORCPT ); Wed, 28 Nov 2018 06:42:42 -0500 Received: from debian.vm ([192.168.192.2]) by leontynka.twibright.com with smtp (Exim 4.89) (envelope-from ) id 1gRnwI-0007s5-Qk; Wed, 28 Nov 2018 01:42:51 +0100 Received: by debian.vm (sSMTP sendmail emulation); Wed, 28 Nov 2018 01:42:50 +0100 Message-Id: <20181128004250.325095242@debian.vm> User-Agent: quilt/0.65 Date: Wed, 28 Nov 2018 01:42:13 +0100 From: Mikulas Patocka To: Jens Axboe Cc: Mike Snitzer , dm-devel@redhat.com, linux-block@vger.kernel.org, "Alasdair G. Kergon" , Christoph Hellwig , Mikulas Patocka Subject: [PATCH 2/3] block: switch to per-cpu in-flight counters MIME-Version: 1.0 Content-Disposition: inline; filename=block-percpu-inflight.patch Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Now when part_round_stats is gone, we can switch to per-cpu in-flight counters. We use the local-atomic type local_t, so that if part_inc_in_flight or part_dec_in_flight is reentrantly called from an interrupt, the value will be correct. The other counters could be corrupted due to reentrant interrupt, but the corruption only results in slight counter skew - the in_flight counter must be exact, so it needs local_t. Signed-off-by: Mikulas Patocka --- block/bio.c | 4 ++-- block/blk-core.c | 4 ++-- block/blk-merge.c | 2 +- block/genhd.c | 47 +++++++++++++++++++++++++++++++++++------------ drivers/md/dm.c | 4 +--- include/linux/genhd.h | 7 ++++--- 6 files changed, 45 insertions(+), 23 deletions(-) Index: linux-block/block/genhd.c =================================================================== --- linux-block.orig/block/genhd.c 2018-11-28 00:09:59.000000000 +0100 +++ linux-block/block/genhd.c 2018-11-28 00:09:59.000000000 +0100 @@ -45,53 +45,76 @@ static void disk_add_events(struct gendi static void disk_del_events(struct gendisk *disk); static void disk_release_events(struct gendisk *disk); -void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, int rw) +void part_inc_in_flight(struct request_queue *q, int cpu, struct hd_struct *part, int rw) { if (queue_is_mq(q)) return; - atomic_inc(&part->in_flight[rw]); + local_inc(per_cpu_ptr(part->dkstats, cpu)->in_flight); if (part->partno) - atomic_inc(&part_to_disk(part)->part0.in_flight[rw]); + local_inc(per_cpu_ptr(part_to_disk(part)->part0.dkstats, cpu)->in_flight); } -void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, int rw) +void part_dec_in_flight(struct request_queue *q, int cpu, struct hd_struct *part, int rw) { if (queue_is_mq(q)) return; - atomic_dec(&part->in_flight[rw]); + local_dec(per_cpu_ptr(part->dkstats, cpu)->in_flight); if (part->partno) - atomic_dec(&part_to_disk(part)->part0.in_flight[rw]); + local_dec(per_cpu_ptr(part_to_disk(part)->part0.dkstats, cpu)->in_flight); } void part_in_flight(struct request_queue *q, struct hd_struct *part, unsigned int inflight[2]) { + int cpu; + if (queue_is_mq(q)) { blk_mq_in_flight(q, part, inflight); return; } - inflight[0] = atomic_read(&part->in_flight[0]) + - atomic_read(&part->in_flight[1]); + inflight[0] = 0; + for_each_possible_cpu(cpu) { + inflight[0] += local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[0]) + + local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[1]); + } + if ((int)inflight[0] < 0) + inflight[0] = 0; + if (part->partno) { part = &part_to_disk(part)->part0; - inflight[1] = atomic_read(&part->in_flight[0]) + - atomic_read(&part->in_flight[1]); + inflight[1] = 0; + for_each_possible_cpu(cpu) { + inflight[1] += local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[0]) + + local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[1]); + } + if ((int)inflight[1] < 0) + inflight[1] = 0; } } void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, unsigned int inflight[2]) { + int cpu; + if (queue_is_mq(q)) { blk_mq_in_flight_rw(q, part, inflight); return; } - inflight[0] = atomic_read(&part->in_flight[0]); - inflight[1] = atomic_read(&part->in_flight[1]); + inflight[0] = 0; + inflight[1] = 0; + for_each_possible_cpu(cpu) { + inflight[0] += local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[0]); + inflight[1] += local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[1]); + } + if ((int)inflight[0] < 0) + inflight[0] = 0; + if ((int)inflight[1] < 0) + inflight[1] = 0; } struct hd_struct *__disk_get_part(struct gendisk *disk, int partno) Index: linux-block/include/linux/genhd.h =================================================================== --- linux-block.orig/include/linux/genhd.h 2018-11-28 00:09:59.000000000 +0100 +++ linux-block/include/linux/genhd.h 2018-11-28 00:09:59.000000000 +0100 @@ -17,6 +17,7 @@ #include #include #include +#include #ifdef CONFIG_BLOCK @@ -89,6 +90,7 @@ struct disk_stats { unsigned long merges[NR_STAT_GROUPS]; unsigned long io_ticks; unsigned long time_in_queue; + local_t in_flight[2]; }; #define PARTITION_META_INFO_VOLNAMELTH 64 @@ -122,7 +124,6 @@ struct hd_struct { int make_it_fail; #endif unsigned long stamp; - atomic_t in_flight[2]; #ifdef CONFIG_SMP struct disk_stats __percpu *dkstats; #else @@ -380,9 +381,9 @@ void part_in_flight(struct request_queue unsigned int inflight[2]); void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, unsigned int inflight[2]); -void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, +void part_dec_in_flight(struct request_queue *q, int cpu, struct hd_struct *part, int rw); -void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, +void part_inc_in_flight(struct request_queue *q, int cpu, struct hd_struct *part, int rw); static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk) Index: linux-block/block/bio.c =================================================================== --- linux-block.orig/block/bio.c 2018-11-28 00:09:59.000000000 +0100 +++ linux-block/block/bio.c 2018-11-28 00:09:59.000000000 +0100 @@ -1688,7 +1688,7 @@ void generic_start_io_acct(struct reques update_io_ticks(cpu, part, jiffies); part_stat_inc(cpu, part, ios[sgrp]); part_stat_add(cpu, part, sectors[sgrp], sectors); - part_inc_in_flight(q, part, op_is_write(op)); + part_inc_in_flight(q, cpu, part, op_is_write(op)); part_stat_unlock(); } @@ -1707,7 +1707,7 @@ void generic_end_io_acct(struct request_ part_stat_add(cpu, part, time_in_queue, duration); if (part->partno) part_stat_add(cpu, &part_to_disk(part)->part0, time_in_queue, duration); - part_dec_in_flight(q, part, op_is_write(req_op)); + part_dec_in_flight(q, cpu, part, op_is_write(req_op)); part_stat_unlock(); } Index: linux-block/block/blk-merge.c =================================================================== --- linux-block.orig/block/blk-merge.c 2018-11-28 00:09:59.000000000 +0100 +++ linux-block/block/blk-merge.c 2018-11-28 00:09:59.000000000 +0100 @@ -690,7 +690,7 @@ static void blk_account_io_merge(struct cpu = part_stat_lock(); part = req->part; - part_dec_in_flight(req->q, part, rq_data_dir(req)); + part_dec_in_flight(req->q, cpu, part, rq_data_dir(req)); hd_struct_put(part); part_stat_unlock(); Index: linux-block/block/blk-core.c =================================================================== --- linux-block.orig/block/blk-core.c 2018-11-28 00:09:59.000000000 +0100 +++ linux-block/block/blk-core.c 2018-11-28 00:09:59.000000000 +0100 @@ -1356,7 +1356,7 @@ void blk_account_io_done(struct request part_stat_add(cpu, part, nsecs[sgrp], now - req->start_time_ns); part_stat_add(cpu, part, time_in_queue, nsecs_to_jiffies64(now - req->start_time_ns)); part_stat_add(cpu, &part_to_disk(part)->part0, time_in_queue, nsecs_to_jiffies64(now - req->start_time_ns)); - part_dec_in_flight(req->q, part, rq_data_dir(req)); + part_dec_in_flight(req->q, cpu, part, rq_data_dir(req)); hd_struct_put(part); part_stat_unlock(); @@ -1391,7 +1391,7 @@ void blk_account_io_start(struct request part = &rq->rq_disk->part0; hd_struct_get(part); } - part_inc_in_flight(rq->q, part, rw); + part_inc_in_flight(rq->q, cpu, part, rw); rq->part = part; } Index: linux-block/drivers/md/dm.c =================================================================== --- linux-block.orig/drivers/md/dm.c 2018-11-28 00:09:59.000000000 +0100 +++ linux-block/drivers/md/dm.c 2018-11-28 00:09:59.000000000 +0100 @@ -663,8 +663,7 @@ static void start_io_acct(struct dm_io * generic_start_io_acct(md->queue, bio_op(bio), bio_sectors(bio), &dm_disk(md)->part0); - atomic_set(&dm_disk(md)->part0.in_flight[rw], - atomic_inc_return(&md->pending[rw])); + atomic_inc(&md->pending[rw]); if (unlikely(dm_stats_used(&md->stats))) dm_stats_account_io(&md->stats, bio_data_dir(bio), @@ -693,7 +692,6 @@ static void end_io_acct(struct dm_io *io * a flush. */ pending = atomic_dec_return(&md->pending[rw]); - atomic_set(&dm_disk(md)->part0.in_flight[rw], pending); pending += atomic_read(&md->pending[rw^0x1]); /* nudge anyone waiting on suspend queue */ From patchwork Wed Nov 28 00:42:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 10701675 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C21B717D5 for ; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC6542C90A for ; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A08C82C910; Wed, 28 Nov 2018 00:43:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,SUBJ_OBFU_PUNCT_FEW autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5CEE2C91F for ; Wed, 28 Nov 2018 00:43:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726418AbeK1Lmm (ORCPT ); Wed, 28 Nov 2018 06:42:42 -0500 Received: from 109-183-129-149.customers.tmcz.cz ([109.183.129.149]:56956 "EHLO leontynka.twibright.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726457AbeK1Lml (ORCPT ); Wed, 28 Nov 2018 06:42:41 -0500 Received: from debian.vm ([192.168.192.2]) by leontynka.twibright.com with smtp (Exim 4.89) (envelope-from ) id 1gRnwK-0007s7-0K; Wed, 28 Nov 2018 01:42:53 +0100 Received: by debian.vm (sSMTP sendmail emulation); Wed, 28 Nov 2018 01:42:51 +0100 Message-Id: <20181128004251.504425345@debian.vm> User-Agent: quilt/0.65 Date: Wed, 28 Nov 2018 01:42:14 +0100 From: Mikulas Patocka To: Jens Axboe Cc: Mike Snitzer , dm-devel@redhat.com, linux-block@vger.kernel.org, "Alasdair G. Kergon" , Christoph Hellwig , Mikulas Patocka Subject: [PATCH 3/3] block: return just one value from part_in_flight MIME-Version: 1.0 Content-Disposition: inline; filename=block-avoid-second-value-from-part_in_flight.patch Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The previous patches deleted all the code that needed the second value returned from part_in_flight - now the kernel only uses the first value. Consequently, part_in_flight (and blk_mq_in_flight) may be changed so that it only returns one value. This patch just refactors the code, there's no functional change. Signed-off-by: Mikulas Patocka --- block/blk-mq.c | 6 ++++-- block/blk-mq.h | 3 +-- block/genhd.c | 32 +++++++++++--------------------- block/partition-generic.c | 6 +++--- include/linux/genhd.h | 3 +-- 5 files changed, 20 insertions(+), 30 deletions(-) Index: linux-block/block/blk-mq.c =================================================================== --- linux-block.orig/block/blk-mq.c 2018-11-28 00:39:16.000000000 +0100 +++ linux-block/block/blk-mq.c 2018-11-28 00:39:16.000000000 +0100 @@ -113,13 +113,15 @@ static bool blk_mq_check_inflight(struct return true; } -void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, - unsigned int inflight[2]) +unsigned int blk_mq_in_flight(struct request_queue *q, struct hd_struct *part) { + unsigned inflight[2]; struct mq_inflight mi = { .part = part, .inflight = inflight, }; inflight[0] = inflight[1] = 0; blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight, &mi); + + return inflight[0]; } static bool blk_mq_check_inflight_rw(struct blk_mq_hw_ctx *hctx, Index: linux-block/block/blk-mq.h =================================================================== --- linux-block.orig/block/blk-mq.h 2018-11-28 00:39:16.000000000 +0100 +++ linux-block/block/blk-mq.h 2018-11-28 00:39:16.000000000 +0100 @@ -184,8 +184,7 @@ static inline bool blk_mq_hw_queue_mappe return hctx->nr_ctx && hctx->tags; } -void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, - unsigned int inflight[2]); +unsigned int blk_mq_in_flight(struct request_queue *q, struct hd_struct *part); void blk_mq_in_flight_rw(struct request_queue *q, struct hd_struct *part, unsigned int inflight[2]); Index: linux-block/block/genhd.c =================================================================== --- linux-block.orig/block/genhd.c 2018-11-28 00:39:16.000000000 +0100 +++ linux-block/block/genhd.c 2018-11-28 00:42:19.000000000 +0100 @@ -65,34 +65,24 @@ void part_dec_in_flight(struct request_q local_dec(per_cpu_ptr(part_to_disk(part)->part0.dkstats, cpu)->in_flight); } -void part_in_flight(struct request_queue *q, struct hd_struct *part, - unsigned int inflight[2]) +unsigned int part_in_flight(struct request_queue *q, struct hd_struct *part) { int cpu; + int inflight; if (queue_is_mq(q)) { - blk_mq_in_flight(q, part, inflight); - return; + return blk_mq_in_flight(q, part); } - inflight[0] = 0; + inflight = 0; for_each_possible_cpu(cpu) { - inflight[0] += local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[0]) + + inflight += local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[0]) + local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[1]); } - if ((int)inflight[0] < 0) - inflight[0] = 0; + if (inflight < 0) + inflight = 0; - if (part->partno) { - part = &part_to_disk(part)->part0; - inflight[1] = 0; - for_each_possible_cpu(cpu) { - inflight[1] += local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[0]) + - local_read(&per_cpu_ptr(part->dkstats, cpu)->in_flight[1]); - } - if ((int)inflight[1] < 0) - inflight[1] = 0; - } + return (unsigned int)inflight; } void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, @@ -1348,7 +1338,7 @@ static int diskstats_show(struct seq_fil struct disk_part_iter piter; struct hd_struct *hd; char buf[BDEVNAME_SIZE]; - unsigned int inflight[2]; + unsigned int inflight; /* if (&disk_to_dev(gp)->kobj.entry == block_class.devices.next) @@ -1360,7 +1350,7 @@ static int diskstats_show(struct seq_fil disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0); while ((hd = disk_part_iter_next(&piter))) { - part_in_flight(gp->queue, hd, inflight); + inflight = part_in_flight(gp->queue, hd); seq_printf(seqf, "%4d %7d %s " "%lu %lu %lu %u " "%lu %lu %lu %u " @@ -1376,7 +1366,7 @@ static int diskstats_show(struct seq_fil part_stat_read(hd, merges[STAT_WRITE]), part_stat_read(hd, sectors[STAT_WRITE]), (unsigned int)part_stat_read_msecs(hd, STAT_WRITE), - inflight[0], + inflight, jiffies_to_msecs(part_stat_read(hd, io_ticks)), jiffies_to_msecs(part_stat_read(hd, time_in_queue)), part_stat_read(hd, ios[STAT_DISCARD]), Index: linux-block/block/partition-generic.c =================================================================== --- linux-block.orig/block/partition-generic.c 2018-11-28 00:39:16.000000000 +0100 +++ linux-block/block/partition-generic.c 2018-11-28 00:39:16.000000000 +0100 @@ -120,9 +120,9 @@ ssize_t part_stat_show(struct device *de { struct hd_struct *p = dev_to_part(dev); struct request_queue *q = part_to_disk(p)->queue; - unsigned int inflight[2]; + unsigned int inflight; - part_in_flight(q, p, inflight); + inflight = part_in_flight(q, p); return sprintf(buf, "%8lu %8lu %8llu %8u " "%8lu %8lu %8llu %8u " @@ -137,7 +137,7 @@ ssize_t part_stat_show(struct device *de part_stat_read(p, merges[STAT_WRITE]), (unsigned long long)part_stat_read(p, sectors[STAT_WRITE]), (unsigned int)part_stat_read_msecs(p, STAT_WRITE), - inflight[0], + inflight, jiffies_to_msecs(part_stat_read(p, io_ticks)), jiffies_to_msecs(part_stat_read(p, time_in_queue)), part_stat_read(p, ios[STAT_DISCARD]), Index: linux-block/include/linux/genhd.h =================================================================== --- linux-block.orig/include/linux/genhd.h 2018-11-28 00:39:16.000000000 +0100 +++ linux-block/include/linux/genhd.h 2018-11-28 00:39:16.000000000 +0100 @@ -377,8 +377,7 @@ static inline void free_part_stats(struc #define part_stat_sub(cpu, gendiskp, field, subnd) \ part_stat_add(cpu, gendiskp, field, -subnd) -void part_in_flight(struct request_queue *q, struct hd_struct *part, - unsigned int inflight[2]); +unsigned int part_in_flight(struct request_queue *q, struct hd_struct *part); void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, unsigned int inflight[2]); void part_dec_in_flight(struct request_queue *q, int cpu, struct hd_struct *part,