Changes in v2: - define __generic_start/end_io_acct() as static - remove input parameters sectors of generic_start_precise_io_acct()
Li Nan (2): block: add precise io accouting apis dm: switch to precise io accounting
include/linux/bio.h | 6 ++++++ block/bio.c | 49 +++++++++++++++++++++++++++++++++++++++------ drivers/md/dm.c | 8 ++++---- 3 files changed, 53 insertions(+), 10 deletions(-)
hulk inclusion category: bugfix bugzilla: 188421, https://gitee.com/openeuler/kernel/issues/I7WMMI CVE: NA
--------------------------------
Currently, for bio-based device, 'ios' and 'sectors' is counted while io is started, while 'nsecs' is counted while io is done.
This behaviour is obviously wrong, however we can't fix exist kapis because this will require new parameter, which will cause kapi broken. Hence this patch add some new apis, which will make sure io accounting for bio-based device is precise.
Signed-off-by: Li Nan linan122@huawei.com --- include/linux/bio.h | 6 ++++++ block/bio.c | 49 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/include/linux/bio.h b/include/linux/bio.h index 361b1bcd3deb..6a41b7b70d88 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -497,6 +497,12 @@ void generic_start_io_acct(struct request_queue *q, int op, void generic_end_io_acct(struct request_queue *q, int op, struct hd_struct *part, unsigned long start_time); +void generic_start_precise_io_acct(struct request_queue *q, int op, + struct hd_struct *part); +void generic_end_precise_io_acct(struct request_queue *q, int op, + struct hd_struct *part, + unsigned long start_time, + unsigned long secotors);
#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE # error "You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform" diff --git a/block/bio.c b/block/bio.c index 9d70ebe4122c..06193e854577 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1733,8 +1733,9 @@ void update_io_ticks(int cpu, struct hd_struct *part, unsigned long now, bool en } }
-void generic_start_io_acct(struct request_queue *q, int op, - unsigned long sectors, struct hd_struct *part) +static void __generic_start_io_acct(struct request_queue *q, int op, + unsigned long sectors, + struct hd_struct *part, bool precise) { const int sgrp = op_stat_group(op); int cpu = part_stat_lock(); @@ -1743,16 +1744,33 @@ void generic_start_io_acct(struct request_queue *q, int op, part_round_stats(q, cpu, part); else update_io_ticks(cpu, part, jiffies, false); - part_stat_inc(cpu, part, ios[sgrp]); - part_stat_add(cpu, part, sectors[sgrp], sectors); + if (!precise) { + 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_stat_unlock(); } + +void generic_start_io_acct(struct request_queue *q, int op, + unsigned long sectors, struct hd_struct *part) +{ + __generic_start_io_acct(q, op, sectors, part, false); +} 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) +void generic_start_precise_io_acct(struct request_queue *q, int op, + struct hd_struct *part) +{ + __generic_start_io_acct(q, op, 0, part, true); +} +EXPORT_SYMBOL(generic_start_precise_io_acct); + +static void __generic_end_io_acct(struct request_queue *q, int req_op, + struct hd_struct *part, + unsigned long start_time, + unsigned long sectors, bool precise) { unsigned long now = jiffies; unsigned long duration = now - start_time; @@ -1765,13 +1783,32 @@ void generic_end_io_acct(struct request_queue *q, int req_op, update_io_ticks(cpu, part, now, true); part_stat_add(cpu, part, time_in_queue, duration); } + if (precise) { + part_stat_inc(cpu, part, ios[sgrp]); + part_stat_add(cpu, part, sectors[sgrp], sectors); + } part_stat_add(cpu, part, nsecs[sgrp], jiffies_to_nsecs(duration)); part_dec_in_flight(q, part, op_is_write(req_op));
part_stat_unlock(); } + +void generic_end_io_acct(struct request_queue *q, int req_op, + struct hd_struct *part, unsigned long start_time) +{ + __generic_end_io_acct(q, req_op, part, start_time, 0, false); +} EXPORT_SYMBOL(generic_end_io_acct);
+void generic_end_precise_io_acct(struct request_queue *q, int req_op, + struct hd_struct *part, + unsigned long start_time, + unsigned long sectors) +{ + __generic_end_io_acct(q, req_op, part, start_time, sectors, true); +} +EXPORT_SYMBOL(generic_end_precise_io_acct); + #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE void bio_flush_dcache_pages(struct bio *bi) {
hulk inclusion category: bugfix bugzilla: 188421, https://gitee.com/openeuler/kernel/issues/I7WMMI CVE: NA
--------------------------------
'ios' and 'sectors' is counted in bio_start_io_acct() while io is started insted of io is done. Hence switch to precise io accounting to count them when io is done.
Signed-off-by: Li Nan linan122@huawei.com --- drivers/md/dm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 0aa6fd33abf1..1d2ae304f096 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -621,8 +621,8 @@ static void start_io_acct(struct dm_io *io)
io->start_time = jiffies;
- generic_start_io_acct(md->queue, bio_op(bio), bio_sectors(bio), - &dm_disk(md)->part0); + generic_start_precise_io_acct(md->queue, bio_op(bio), + &dm_disk(md)->part0);
atomic_set(&dm_disk(md)->part0.in_flight[rw], atomic_inc_return(&md->pending[rw])); @@ -640,8 +640,8 @@ static void end_io_acct(struct mapped_device *md, struct bio *bio, int pending; int rw = bio_data_dir(bio);
- generic_end_io_acct(md->queue, bio_op(bio), &dm_disk(md)->part0, - start_time); + generic_end_precise_io_acct(md->queue, bio_op(bio), &dm_disk(md)->part0, + start_time, bio_sectors(bio));
if (unlikely(dm_stats_used(&md->stats))) dm_stats_account_io(&md->stats, bio_data_dir(bio),
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/2046 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/E...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/2046 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/E...