mmc: block: Fix pending_writes underflow on non-CQE hosts#7508
Open
mairacanal wants to merge 1 commit into
Open
mmc: block: Fix pending_writes underflow on non-CQE hosts#7508mairacanal wants to merge 1 commit into
mairacanal wants to merge 1 commit into
Conversation
The posted-write accounting mirrors in_flight[], but on the plain blk-mq completion path (hosts with neither CQE nor HSQ) pending_writes is decremented twice per write: once in mmc_blk_mq_complete_rq() and again in mmc_blk_mq_dec_in_flight(). Both run for a single request, since mmc_blk_mq_post_req() first triggers the .complete callback via blk_mq_complete_request() and then calls mmc_blk_mq_dec_in_flight(). As in_flight[] is only decremented in the latter, pending_writes drifts one below in_flight[] for every completed write and underflows. This stayed hidden on the CQE/HSQ hosts the feature targets, where completion goes solely through mmc_blk_cqe_complete_rq() and decrements once. It surfaces on plain-mq hosts such as the bcm2835-sdhost, tripping the WARN_ON_ONCE() on the first write once the rootfs is remounted read-write: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 84 at drivers/mmc/core/queue.c:350 mmc_mq_queue_rq+0x2a0/0x2f8 Modules linked in: sch_fq_codel uinput i2c_dev zram lz4_compress fuse drm drm_panel_orientation_quirks backlight nfnetlink ipv6 libsha1 CPU: 0 UID: 0 PID: 84 Comm: kworker/0:1H Not tainted 6.18.38-v8-tile-alloc-256-32+ raspberrypi#15 PREEMPT Hardware name: Raspberry Pi 3 Model B Plus Rev 1.3 (DT) Workqueue: kblockd blk_mq_requeue_work pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : mmc_mq_queue_rq+0x2a0/0x2f8 lr : mmc_mq_queue_rq+0x284/0x2f8 Call trace: mmc_mq_queue_rq+0x2a0/0x2f8 (P) blk_mq_dispatch_rq_list+0x2c8/0x718 __blk_mq_sched_dispatch_requests+0xec/0x570 blk_mq_sched_dispatch_requests+0x3c/0x88 blk_mq_run_hw_queue+0xf4/0x128 blk_mq_run_hw_queues+0xc4/0x140 blk_mq_requeue_work+0x188/0x1c0 process_scheduled_works+0x180/0x3d0 worker_thread+0x268/0x3e8 kthread+0x140/0x250 ret_from_fork+0x10/0x20 ---[ end trace 0000000000000000 ]--- Decrement pending_writes only where in_flight[] is decremented, dropping the redundant decrement in mmc_blk_mq_complete_rq() so the counter tracks in_flight[] exactly. The CQE path is unaffected. Fixes: e6c1e86 ("mmc: restrict posted write counts for SD cards in CQ mode") Signed-off-by: Maíra Canal <mcanal@igalia.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The posted-write accounting mirrors
in_flight[], but on the plain blk-mq completion path (hosts with neither CQE nor HSQ) pending_writes is decremented twice per write: once inmmc_blk_mq_complete_rq()and again inmmc_blk_mq_dec_in_flight(). Both run for a single request, sincemmc_blk_mq_post_req()first triggers the .complete callback viablk_mq_complete_request()and then callsmmc_blk_mq_dec_in_flight(). Asin_flight[]is only decremented in the latter, pending_writes drifts one belowin_flight[]for every completed write and underflows.This stayed hidden on the CQE/HSQ hosts the feature targets, where completion goes solely through
mmc_blk_cqe_complete_rq()and decrements once. It surfaces on plain-mq hosts such as the bcm2835-sdhost, tripping theWARN_ON_ONCE()on the first write once the rootfs is remounted read-write:Decrement pending_writes only where
in_flight[]is decremented, dropping the redundant decrement in mmc_blk_mq_complete_rq() so the counter tracksin_flight[]exactly. The CQE path is unaffected.I found this warning while booting my Raspberry Pi 3B+ from a SD card. The warning appears during the system boot and bring up and it appears to be harmless, that is: I was able to boot normally even with the warning. However, while investigating the origins of the warning, I found this refcount issue. After this patch, the warning no longer appears.
Let me know your thoughts.