Re: [PATCH v4 1/4] mmc: core: Add panic-context host operations for pstore backends

From: Ulf Hansson

Date: Wed Apr 15 2026 - 05:31:08 EST


On Fri, 20 Mar 2026 at 21:33, Kamal Dasu <kamal.dasu@xxxxxxxxxxxx> wrote:
>
> Add three new optional callbacks to struct mmc_host_ops for panic-safe
> MMC I/O:
>
> - panic_prepare: drain in-flight requests and prepare for polled I/O
> - panic_poll_completion: poll for request completion without interrupts
> - panic_complete: restore normal host state after panic I/O
>
> Add mmc_panic_claim_host() which uses WRITE_ONCE() to claim the host
> without taking the spin lock, since during panic other CPUs are stopped
> and may hold the lock.
>
> Signed-off-by: Kamal Dasu <kamal.dasu@xxxxxxxxxxxx>
> ---
> drivers/mmc/core/core.c | 23 +++++++++++++++++++++++
> include/linux/mmc/host.h | 12 ++++++++++++
> 2 files changed, 35 insertions(+)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 860378bea557..5326b246b4f2 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -860,6 +860,29 @@ void mmc_release_host(struct mmc_host *host)
> }
> EXPORT_SYMBOL(mmc_release_host);
>
> +/**
> + * mmc_panic_claim_host - force-claim a host in panic context
> + * @host: mmc host to claim
> + *
> + * Force-claims the MMC host without locking. During kernel panic
> + * other CPUs are stopped and may be holding mmc_host->lock (e.g.
> + * inside __mmc_claim_host or mmc_release_host). Unlike sdhci_host->lock
> + * which is freed by the hardware drain+reset, mmc_host->lock has no
> + * hardware counterpart, so we must bypass it with WRITE_ONCE.
> + */
> +void mmc_panic_claim_host(struct mmc_host *host)
> +{
> + if (!host)
> + return;
> +
> + WRITE_ONCE(host->claimed, 1);
> + host->claimer = &host->default_ctx;
> + host->claimer->task = current;
> + WRITE_ONCE(host->claim_cnt, 1);
> + WRITE_ONCE(host->ongoing_mrq, NULL);
> +}
> +EXPORT_SYMBOL(mmc_panic_claim_host);

The above doesn't account for whether someone else has already claimed
the host. I believe we should check that to better understand our
current state.

If the host is claimed, it's probably due to ongoing read/write I/O.
Then, how do we gracefully terminate those requests?

If the host isn't claimed, the mmc host (and mmc card) may have been
runtime PM suspended. We should take that into account, because
runtime resuming the host in atomic context is most likely not going
to work.

> +
> /*
> * This is a helper function, which fetches a runtime pm reference for the
> * card device and also claims the host.
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index ba84f02c2a10..cd44b62d29cb 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -272,6 +272,16 @@ struct mmc_host_ops {
> * negative errno in case of a failure or zero for success.
> */
> int (*uhs2_control)(struct mmc_host *host, enum sd_uhs2_operation op);
> +
> + /*
> + * Optional panic-context ops for pstore backends that write to MMC
> + * during kernel panic with interrupts disabled.
> + */
> + int (*panic_prepare)(struct mmc_host *host);
> + bool (*panic_poll_completion)(struct mmc_host *host,
> + struct mmc_request *mrq);
> + void (*panic_complete)(struct mmc_host *host,
> + struct mmc_request *mrq);
> };
>
> struct mmc_cqe_ops {
> @@ -758,4 +768,6 @@ int mmc_send_abort_tuning(struct mmc_host *host, u32 opcode);
> int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
> int mmc_read_tuning(struct mmc_host *host, unsigned int blksz, unsigned int blocks);
>
> +void mmc_panic_claim_host(struct mmc_host *host);
> +
> #endif /* LINUX_MMC_HOST_H */
> --
> 2.34.1
>

Kind regards
Uffe