Skip to content

Commit c007062

Browse files
YuKuai-huaweiaxboe
authored andcommitted
block: fix false warning in bdev_count_inflight_rw()
While bdev_count_inflight is interating all cpus, if some IOs are issued from traversed cpu and then completed from the cpu that is not traversed yet: cpu0 cpu1 bdev_count_inflight //for_each_possible_cpu // cpu0 is 0 infliht += 0 // issue a io blk_account_io_start // cpu0 inflight ++ cpu2 // the io is done blk_account_io_done // cpu2 inflight -- // cpu 1 is 0 inflight += 0 // cpu2 is -1 inflight += -1 ... In this case, the total inflight will be -1, causing lots of false warning. Fix the problem by removing the warning. Noted there is still a valid warning for nvme-mpath(From Yi) that is not fixed yet. Fixes: f5482ee ("block: WARN if bdev inflight counter is negative") Reported-by: Yi Zhang <[email protected]> Closes: https://lore.kernel.org/linux-block/[email protected]/T/#mae89155a5006463d0a21a4a2c35ae0034b26a339 Reported-and-tested-by: Calvin Owens <[email protected]> Closes: https://lore.kernel.org/linux-block/[email protected]/T/#m1d935a00070bf95055d0ac84e6075158b08acaef Reported-by: Dave Chinner <[email protected]> Closes: https://lore.kernel.org/linux-block/[email protected]/ Signed-off-by: Yu Kuai <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 5990b77 commit c007062

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

block/genhd.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,23 +128,27 @@ static void part_stat_read_all(struct block_device *part,
128128
static void bdev_count_inflight_rw(struct block_device *part,
129129
unsigned int inflight[2], bool mq_driver)
130130
{
131+
int write = 0;
132+
int read = 0;
131133
int cpu;
132134

133135
if (mq_driver) {
134136
blk_mq_in_driver_rw(part, inflight);
135-
} else {
136-
for_each_possible_cpu(cpu) {
137-
inflight[READ] += part_stat_local_read_cpu(
138-
part, in_flight[READ], cpu);
139-
inflight[WRITE] += part_stat_local_read_cpu(
140-
part, in_flight[WRITE], cpu);
141-
}
137+
return;
138+
}
139+
140+
for_each_possible_cpu(cpu) {
141+
read += part_stat_local_read_cpu(part, in_flight[READ], cpu);
142+
write += part_stat_local_read_cpu(part, in_flight[WRITE], cpu);
142143
}
143144

144-
if (WARN_ON_ONCE((int)inflight[READ] < 0))
145-
inflight[READ] = 0;
146-
if (WARN_ON_ONCE((int)inflight[WRITE] < 0))
147-
inflight[WRITE] = 0;
145+
/*
146+
* While iterating all CPUs, some IOs may be issued from a CPU already
147+
* traversed and complete on a CPU that has not yet been traversed,
148+
* causing the inflight number to be negative.
149+
*/
150+
inflight[READ] = read > 0 ? read : 0;
151+
inflight[WRITE] = write > 0 ? write : 0;
148152
}
149153

150154
/**

0 commit comments

Comments
 (0)