Skip to content

himci: finish the request when the FIFO reset times out - #58

Merged
widgetii merged 2 commits into
hisilicon-hi3516cv200from
himci/finish-the-request-hi3516cv200
Sep 22, 2026
Merged

widgetii merged 2 commits into
hisilicon-hi3516cv200from
himci/finish-the-request-hi3516cv200

Conversation

@widgetii

Copy link
Copy Markdown
Member

The same one-line fault as #57, in this branch's copy of himci.c.

himci_request() has ten ways out. Nine reach request_end, which calls
himci_finish_request() and through it mmc_request_done(). The tenth — the
FIFO-reset loop on the data path — is a bare return, so nothing completes the
request: the MMC core waits forever on an uninterruptible
wait_for_completion(), the caller becomes an unkillable D state, and
because the host is never released every later request queues behind it. On a
camera that is recording stopping until someone cuts the power.

The fix sets the data error the way every other timeout in this driver does
(-ETIMEDOUT) and jumps to request_end. No DMA to unwind — himci_idma_start()
is below this point.

Found by reading, not by triggering. #57 explains why forcing the path costs
a board nobody can reach; the same applies here. The path leaves
fifo reset is timeout! in dmesg, which is what to grep for if it shows up in
the field.

Scope

I checked which branches actually ship this driver rather than patching every
one that contains the text. CONFIG_HIMCI=y appears in the firmware's board
configs for hi3516cv200 and hi3518ev200 — this branch — and for hi3516cv500 (#57). It is set nowhere
for hisilicon-hi3516ev200 or hisilicon-hi3536dv100, and neither branch even
carries a himci variant its SoC selects, so the driver cannot be built there and
those two are left alone.

Testing

Compile-tested with the hi3516cv200 board kernel config (CONFIG_HIMCI=y, arm-openipc-linux-musleabi,
make drivers/mmc/host/himci/himci.o), no new warnings. No hardware for this
SoC here; the change is textually identical to the one on #57, which was
exercised on an hi3516av300 to the extent that normal SD traffic, a CMD13
passthrough and a 512-byte CMD56 read all behave unchanged.

Same one-line fault as #57 on hisilicon-hi3516cv500, in this
branch's copy of the driver.

himci_request() has ten ways out and nine of them reach request_end, which
calls himci_finish_request() and through it mmc_request_done(). The tenth, in
the FIFO-reset loop on the data path, is a bare return.

Nothing else completes the request. The MMC core is sitting in
mmc_wait_for_req() on an uninterruptible wait_for_completion(), so the caller
becomes an unkillable D state, and because the host is never released every
later request queues behind it. On a camera that is recording stopping and
staying stopped until someone cuts the power.

Set the data error the way every other timeout in this driver does and jump to
request_end. There is no DMA to unwind: himci_idma_start() is below this
point.

Found by reading, not by triggering it; see #57 for why forcing the path costs
a board nobody can reach. The path leaves "fifo reset is timeout!" in dmesg,
which is what to grep for if it is ever seen in the field.

Compile-tested with hi3516cv200 and hi3518ev200' kernel config (CONFIG_HIMCI=y,
arm-openipc-linux-musleabi, make drivers/mmc/host/himci/himci.o) with no new
warnings.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Complete HIMCI requests after FIFO reset timeouts

🐞 Bug fix 🕐 Less than 10 minutes

Grey Divider

AI Description

• Completes MMC requests when FIFO reset polling exceeds the retry limit.
• Reports -ETIMEDOUT through centralized cleanup, preventing permanent host stalls.
• Compile-tested with the hi3516cv200 and hi3518ev200 kernel configuration.
Diagram

sequenceDiagram
    participant Core as MMC Core
    participant Request as HIMCI Request
    participant FIFO as FIFO Reset
    participant Finish as Request Finish
    Core->>Request: Submit request
    Request->>FIFO: Poll reset
    alt Reset timeout
        FIFO-->>Request: Retry limit reached
        Request->>Request: Set ETIMEDOUT
        Request->>Finish: Enter request_end
        Finish-->>Core: Complete request
    else Reset succeeds
        FIFO-->>Request: Reset complete
        Request->>Request: Start DMA
    end
Loading
High-Level Assessment

The centralized request_end path is the appropriate solution because it preserves the driver's established completion and interrupt-cleanup behavior. Directly calling himci_finish_request() or duplicating cleanup at the timeout site would risk bypassing or diverging from common teardown logic.

Files changed (1) +16 / -1

Bug fix (1) +16 / -1
himci.cComplete timed-out FIFO reset requests +16/-1

Complete timed-out FIFO reset requests

• The FIFO reset timeout now records '-ETIMEDOUT' on the request data and branches to the shared completion path. An explanatory comment documents how the former early return stranded the MMC waiter and blocked subsequent host requests.

drivers/mmc/host/himci/himci.c

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. FIFO timeouts leak buffer mappings ✓ Resolved 🐞 Bug ☼ Reliability
Description
The FIFO-reset timeout branch jumps to request_end after himci_setup_data() has called
dma_map_sg(), while himci_finish_request() does not unmap that data. Each reset timeout
therefore leaves its scatterlist mapping active, and completing the request allows subsequent
requests to repeat the leak.
Code

drivers/mmc/host/himci/himci.c[R925-926]

+				mrq->data->error = -ETIMEDOUT;
+				goto request_end;
Evidence
himci_setup_data() maps the request scatterlist at lines 429-431 before the FIFO-reset loop. The
matching dma_unmap_sg() exists only in himci_data_done() at line 657, whereas
himci_finish_request() at lines 602-613 merely clears pointers and calls mmc_request_done(); the
newly added direct jump therefore bypasses the only normal unmap path.

drivers/mmc/host/himci/himci.c[429-431]
drivers/mmc/host/himci/himci.c[650-672]
drivers/mmc/host/himci/himci.c[602-613]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The FIFO-reset timeout completes the request without releasing the scatterlist DMA mapping created by `himci_setup_data()`. Because completion permits later requests to run, a persistent reset failure can leak another mapping on every request.
## Fix Focus Areas
- drivers/mmc/host/himci/himci.c[925-926]
- drivers/mmc/host/himci/himci.c[650-672]
## Recommended Fix
After assigning `-ETIMEDOUT`, call `himci_data_done(host, 0)` before jumping to `request_end`. This uses the driver's existing cleanup path to unmap the scatterlist, preserve the timeout error, set `bytes_xfered` to zero, and clear `host->data`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can route each action level your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread drivers/mmc/host/himci/himci.c
From review of the previous commit, and a fault in it.

himci_setup_data() does two things that have to be undone: it maps the
scatterlist for the device, and it takes host->data. himci_data_done() is the
only thing that gives either back. Jumping to request_end from the FIFO-reset
timeout skipped it, so the buffer went back to the MMC core still mapped for
the device, and host->data was left pointing at a request that had just been
completed.

Call it, with no status bits, so it unmaps, clears host->data, zeroes
bytes_xfered and keeps the -ETIMEDOUT set above rather than deciding an error
of its own. Still no himci_idma_stop(): the engine is genuinely not running
there, because himci_idma_start() is below this point.

Worth noting while this is open: the command-error paths further down have the
same shape. When himci_exec_cmd() fails or the command completes with an
error, the data branch calls himci_idma_stop() and falls through to
request_end without himci_data_done(), so those leak the mapping too. That is
older than this change and is left alone here rather than folded into a
one-line fix.

Compile-tested as before, no new warnings.
@widgetii

Copy link
Copy Markdown
Member Author

Right, and it is a fault in the fix rather than in the old code. Addressed in
the follow-up commit.

himci_setup_data() does two things that have to be undone: it maps the
scatterlist for the device, and it takes host->data. himci_data_done() is
the only thing that gives either back. Jumping to request_end skipped it, so
the buffer went back to the MMC core still mapped for the device — and
host->data was left pointing at a request that had just been completed, which
is the worse half: a later himci_data_done() or an IRQ would have dereferenced
it.

It now calls himci_data_done(host, 0) before the jump. With no status bits
neither error branch inside it fires, so it unmaps, clears host->data, zeroes
bytes_xfered and keeps the -ETIMEDOUT set just above rather than deciding an
error of its own. Still no himci_idma_stop(): the engine genuinely is not
running there, because himci_idma_start() is below this point.

Worth recording while this is open, since it is the same class and I looked:
the command-error paths further down leak the same mapping. When
himci_exec_cmd() fails, or the command completes with an error, the data
branch calls himci_idma_stop() and falls through to request_end without
himci_data_done(). That is older than this change and is left alone rather
than folded into a one-line fix — happy to send it separately if you want it.

Compile-tested as before, no new warnings.

@widgetii
widgetii merged commit 866d8a9 into hisilicon-hi3516cv200 Sep 22, 2026
@widgetii
widgetii deleted the himci/finish-the-request-hi3516cv200 branch September 22, 2026 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant