dm: factor out updating of the variable in_flight This patch moves updating in_flight to a separate function. Note that due to a race condition, in_flight may be non-zero if the device is idle. This bug existed in the code even before this patch. Nothing really depends on the in_flight value so it doesn't matter. Signed-off-by: Mikulas Patocka --- drivers/md/dm.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) Index: linux-4.13-rc5/drivers/md/dm.c =================================================================== --- linux-4.13-rc5.orig/drivers/md/dm.c +++ linux-4.13-rc5/drivers/md/dm.c @@ -510,6 +510,16 @@ int md_in_flight(struct mapped_device *m atomic_read(&md->pending[WRITE]); } +/* + * Note: this is racy (we may end up with non-zero value even if the device is + * idle), but it doesn't matter because nothing depends on this value. + */ +static void update_in_flight(struct mapped_device *md, int rw) +{ + atomic_set(&dm_disk(md)->part0.in_flight[rw], + atomic_read(&md->pending[rw])); +} + static void start_io_acct(struct dm_io *io) { struct mapped_device *md = io->md; @@ -522,8 +532,9 @@ static void start_io_acct(struct dm_io * cpu = part_stat_lock(); part_round_stats(cpu, &dm_disk(md)->part0); part_stat_unlock(); - atomic_set(&dm_disk(md)->part0.in_flight[rw], - atomic_inc_return(&md->pending[rw])); + + atomic_inc(&md->pending[rw]); + update_in_flight(md, rw); if (unlikely(dm_stats_used(&md->stats))) dm_stats_account_io(&md->stats, bio_data_dir(bio), @@ -551,7 +562,9 @@ 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); + + update_in_flight(md, rw); + pending += atomic_read(&md->pending[rw^0x1]); /* nudge anyone waiting on suspend queue */