2021-05-05 14:15:13

by Christian Loehle

[permalink] [raw]
Subject: [PATCH] mmc: block: ioctl: No busywaiting of non-TRAN CMDs

Prevent busywaiting for TRAN state indication
after issuing a command that will not transition
to TRAN state.

Signed-off-by: Christian Loehle <[email protected]>
---
drivers/mmc/core/block.c | 3 ++-
drivers/mmc/core/block.h | 5 +++++
2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 689eb9afeeed..9baf95639688 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -593,7 +593,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,

memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp));

- if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
+ if ((idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B)
+ && TRAN_TRANSITION_CMD(cmd.opcode)) {
/*
* Ensure RPMB/R1B command has completed by polling CMD13
* "Send Status".
diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h
index 31153f656f41..51b806384ab0 100644
--- a/drivers/mmc/core/block.h
+++ b/drivers/mmc/core/block.h
@@ -17,4 +17,9 @@ struct work_struct;

void mmc_blk_mq_complete_work(struct work_struct *work);

+#define TRAN_TRANSITION_CMD(cmd) !(cmd == MMC_SEND_STATUS \
+ || cmd == MMC_SEND_CID \
+ || cmd == MMC_ALL_SEND_CID \
+ || cmd == MMC_SEND_CSD)
+
#endif
--
2.31.1

Hyperstone GmbH | Line-Eid-Strasse 3 | 78467 Konstanz
Managing Directors: Dr. Jan Peter Berns.
Commercial register of local courts: Freiburg HRB381782


2021-05-06 06:18:17

by Avri Altman

[permalink] [raw]
Subject: RE: [PATCH] mmc: block: ioctl: No busywaiting of non-TRAN CMDs

> Prevent busywaiting for TRAN state indication
> after issuing a command that will not transition
> to TRAN state.
>
> Signed-off-by: Christian Loehle <[email protected]>
> ---
> drivers/mmc/core/block.c | 3 ++-
> drivers/mmc/core/block.h | 5 +++++
> 2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> index 689eb9afeeed..9baf95639688 100644
> --- a/drivers/mmc/core/block.c
> +++ b/drivers/mmc/core/block.c
> @@ -593,7 +593,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card
> *card, struct mmc_blk_data *md,
>
> memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp));
>
> - if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
> + if ((idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B)
> + && TRAN_TRANSITION_CMD(cmd.opcode)) {
> /*
> * Ensure RPMB/R1B command has completed by polling CMD13
> * "Send Status".
> diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h
> index 31153f656f41..51b806384ab0 100644
> --- a/drivers/mmc/core/block.h
> +++ b/drivers/mmc/core/block.h
> @@ -17,4 +17,9 @@ struct work_struct;
>
> void mmc_blk_mq_complete_work(struct work_struct *work);
>
> +#define TRAN_TRANSITION_CMD(cmd) !(cmd == MMC_SEND_STATUS \
> + || cmd == MMC_SEND_CID \
> + || cmd == MMC_ALL_SEND_CID \
> + || cmd == MMC_SEND_CSD)
> +
You might want to use a static inline here to allow type checking.
If you decide to leave it as a macro however, need to add () on each term.

Thanks,
Avri

> #endif
> --
> 2.31.1
>
> Hyperstone GmbH | Line-Eid-Strasse 3 | 78467 Konstanz
> Managing Directors: Dr. Jan Peter Berns.
> Commercial register of local courts: Freiburg HRB381782

2021-05-07 14:05:26

by Christian Loehle

[permalink] [raw]
Subject: [PATCH v2] mmc: block: ioctl: No busywaiting of non-TRAN CMDs

Prevent busywaiting for TRAN state indication
after issuing a command that will not transition
to TRAN state.

Signed-off-by: Christian Loehle <[email protected]>
---
drivers/mmc/core/block.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 689eb9afeeed..48be2ca5e3d1 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -446,6 +446,20 @@ static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
return err;
}

+static inline bool is_tran_transition_cmd(struct mmc_command *cmd,
+ struct mmc_card *card)
+{
+ /* Cards will not be in TRAN after completing identification commands
+ * or MMC_SEND_STATUS if they are not selected.
+ */
+ return !(cmd->opcode == MMC_SEND_CID
+ || cmd->opcode == MMC_ALL_SEND_CID
+ || cmd->opcode == MMC_SEND_CSD
+ || (cmd->opcode == MMC_SEND_STATUS &&
+ MMC_EXTRACT_INDEX_FROM_ARG(cmd->arg) != card->rca));
+
+}
+
static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
struct mmc_blk_ioc_data *idata)
{
@@ -593,7 +607,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,

memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp));

- if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
+ if ((idata->rpmb || (cmd.flags & MMC_RSP_R1B))
+ && is_tran_transition_cmd(&cmd, card)) {
/*
* Ensure RPMB/R1B command has completed by polling CMD13
* "Send Status".
--
2.31.1

Hyperstone GmbH | Line-Eid-Strasse 3 | 78467 Konstanz
Managing Directors: Dr. Jan Peter Berns.
Commercial register of local courts: Freiburg HRB381782

2021-05-07 15:31:07

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH v2] mmc: block: ioctl: No busywaiting of non-TRAN CMDs

On Fri, 7 May 2021 at 12:34, Christian Löhle <[email protected]> wrote:
>
> Prevent busywaiting for TRAN state indication
> after issuing a command that will not transition
> to TRAN state.
>
> Signed-off-by: Christian Loehle <[email protected]>
> ---
> drivers/mmc/core/block.c | 17 ++++++++++++++++-
> 1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> index 689eb9afeeed..48be2ca5e3d1 100644
> --- a/drivers/mmc/core/block.c
> +++ b/drivers/mmc/core/block.c
> @@ -446,6 +446,20 @@ static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
> return err;
> }
>
> +static inline bool is_tran_transition_cmd(struct mmc_command *cmd,
> + struct mmc_card *card)
> +{
> + /* Cards will not be in TRAN after completing identification commands
> + * or MMC_SEND_STATUS if they are not selected.
> + */
> + return !(cmd->opcode == MMC_SEND_CID
> + || cmd->opcode == MMC_ALL_SEND_CID
> + || cmd->opcode == MMC_SEND_CSD
> + || (cmd->opcode == MMC_SEND_STATUS &&
> + MMC_EXTRACT_INDEX_FROM_ARG(cmd->arg) != card->rca));
> +
> +}
> +
> static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
> struct mmc_blk_ioc_data *idata)
> {
> @@ -593,7 +607,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
>
> memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp));
>
> - if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
> + if ((idata->rpmb || (cmd.flags & MMC_RSP_R1B))
> + && is_tran_transition_cmd(&cmd, card)) {

None of the commands you are checking for should have an R1B response
according to the spec, I think.

That said, I don't think we should do these kinds of sanity checks in
the kernel for the mmc ioctls, that just doesn't scale.

> /*
> * Ensure RPMB/R1B command has completed by polling CMD13
> * "Send Status".
> --

Kind regards
Uffe

2021-05-11 16:12:44

by Christian Loehle

[permalink] [raw]
Subject: Re: [PATCH v2] mmc: block: ioctl: No busywaiting of non-TRAN CMDs

On Friday, May 7, 2021 1:34 PM,Ulf Hansson <[email protected]> wrote:
>
> None of the commands you are checking for should have an R1B response
> according to the spec, I think.
>
> That said, I don't think we should do these kinds of sanity checks in
> the kernel for the mmc ioctls, that just doesn't scale.

You are absolutely correct, my bad, I had a userspace program setting the
flags wrong.
Even for a SEND_STATUS R1B is only expected if the card was not selected
and should be set accordingly by the userspace.

Regards,
Christian
Hyperstone GmbH | Line-Eid-Strasse 3 | 78467 Konstanz
Managing Directors: Dr. Jan Peter Berns.
Commercial register of local courts: Freiburg HRB381782