Message ID | 1476951579-26125-5-git-send-email-ulf.hansson@linaro.org |
---|---|
State | New |
Headers | show |
On 20/10/16 11:19, Ulf Hansson wrote: > When polling for busy after sending a MMC_SWITCH command, both the optional > ->card_busy() callback and CMD13 are being used in conjunction. > > This doesn't make sense. Instead it's more reasonable to rely solely on the > ->card_busy() callback when it exists. Let's change that and instead use > the CMD13 as a fall-back. In this way we avoid sending CMD13, unless it's > really needed. > > Within this context, let's also take the opportunity to make some > additional clean-ups and clarifications to the related code. > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> > --- > drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++---------------- > 1 file changed, 14 insertions(+), 16 deletions(-) > > diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c > index a84a880..481bbdb 100644 > --- a/drivers/mmc/core/mmc_ops.c > +++ b/drivers/mmc/core/mmc_ops.c > @@ -495,34 +495,32 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, > timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1; > do { > /* > - * Due to the possibility of being preempted after > - * sending the status command, check the expiration > - * time first. > + * Due to the possibility of being preempted while polling, > + * check the expiration time first. > */ > expired = time_after(jiffies, timeout); > - if (send_status) { > + > + if (host->ops->card_busy) { > + busy = host->ops->card_busy(host); I didn't really have time to look at these patches, sorry :-(. But this loop looks like it could use a cond_resched() > + } else { > err = __mmc_send_status(card, &status, ignore_crc); > if (err) > return err; > - } > - if (host->ops->card_busy) { > - if (!host->ops->card_busy(host)) > - break; > - busy = true; > + busy = R1_CURRENT_STATE(status) == R1_STATE_PRG; > } > > - /* Timeout if the device never leaves the program state. */ > - if (expired && > - (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy)) { > - pr_err("%s: Card stuck in programming state! %s\n", > + /* Timeout if the device still remains busy. */ > + if (expired && busy) { > + pr_err("%s: Card stuck being busy! %s\n", > mmc_hostname(host), __func__); > return -ETIMEDOUT; > } > - } while (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy); > + } while (busy); > > - err = mmc_switch_status_error(host, status); > + if (host->ops->card_busy && send_status) > + return mmc_switch_status(card); > > - return err; > + return mmc_switch_status_error(host, status); > } > > /** > -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Oct 20, 2016 at 10:19 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote: > When polling for busy after sending a MMC_SWITCH command, both the optional > ->card_busy() callback and CMD13 are being used in conjunction. > > This doesn't make sense. Instead it's more reasonable to rely solely on the > ->card_busy() callback when it exists. Let's change that and instead use > the CMD13 as a fall-back. In this way we avoid sending CMD13, unless it's > really needed. > > Within this context, let's also take the opportunity to make some > additional clean-ups and clarifications to the related code. > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Tried these four patches but it doesn't make my root mount before 20 minutes on the Dragonboard, but I don't know if that was the intention even? Just cleanup? Sorry if I got it wrong... Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 24 October 2016 at 09:49, Linus Walleij <linus.walleij@linaro.org> wrote: > On Thu, Oct 20, 2016 at 10:19 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote: > >> When polling for busy after sending a MMC_SWITCH command, both the optional >> ->card_busy() callback and CMD13 are being used in conjunction. >> >> This doesn't make sense. Instead it's more reasonable to rely solely on the >> ->card_busy() callback when it exists. Let's change that and instead use >> the CMD13 as a fall-back. In this way we avoid sending CMD13, unless it's >> really needed. >> >> Within this context, let's also take the opportunity to make some >> additional clean-ups and clarifications to the related code. >> >> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> > > Tried these four patches but it doesn't make my root mount before > 20 minutes on the Dragonboard, but I don't know if that was the > intention even? Just cleanup? Sorry if I got it wrong... Apologize if this was confusing, these changes was not intended to fix your reported problem. They are clean-ups and the last change improves the polling loop for switch commands a bit. I will post a patch for the reported regression asap and will keep you on cc. Appreciate if you could help in testing! Kind regards Uffe -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 21 October 2016 at 11:19, Adrian Hunter <adrian.hunter@intel.com> wrote: > On 20/10/16 11:19, Ulf Hansson wrote: >> When polling for busy after sending a MMC_SWITCH command, both the optional >> ->card_busy() callback and CMD13 are being used in conjunction. >> >> This doesn't make sense. Instead it's more reasonable to rely solely on the >> ->card_busy() callback when it exists. Let's change that and instead use >> the CMD13 as a fall-back. In this way we avoid sending CMD13, unless it's >> really needed. >> >> Within this context, let's also take the opportunity to make some >> additional clean-ups and clarifications to the related code. >> >> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> >> --- >> drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++---------------- >> 1 file changed, 14 insertions(+), 16 deletions(-) >> >> diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c >> index a84a880..481bbdb 100644 >> --- a/drivers/mmc/core/mmc_ops.c >> +++ b/drivers/mmc/core/mmc_ops.c >> @@ -495,34 +495,32 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, >> timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1; >> do { >> /* >> - * Due to the possibility of being preempted after >> - * sending the status command, check the expiration >> - * time first. >> + * Due to the possibility of being preempted while polling, >> + * check the expiration time first. >> */ >> expired = time_after(jiffies, timeout); >> - if (send_status) { >> + >> + if (host->ops->card_busy) { >> + busy = host->ops->card_busy(host); > > I didn't really have time to look at these patches, sorry :-(. But this > loop looks like it could use a cond_resched() Yes, something like that is definitely needed! Although, I suggest we do that improvement on top of this change, if you are fine with that approach? The reason is that I am also pondering over, whether it could make sense to poll with a dynamically increased interval. At least when using ->card_busy(). Let's say by starting at 1 us interval, then at each poll attempt we double the interval time. We would then rather use a combination of udelay(), usleep_range() and msleep() to accomplish what you propose. Does that make sense to you? Kind regards Uffe -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 25/10/16 11:45, Ulf Hansson wrote: > On 21 October 2016 at 11:19, Adrian Hunter <adrian.hunter@intel.com> wrote: >> On 20/10/16 11:19, Ulf Hansson wrote: >>> When polling for busy after sending a MMC_SWITCH command, both the optional >>> ->card_busy() callback and CMD13 are being used in conjunction. >>> >>> This doesn't make sense. Instead it's more reasonable to rely solely on the >>> ->card_busy() callback when it exists. Let's change that and instead use >>> the CMD13 as a fall-back. In this way we avoid sending CMD13, unless it's >>> really needed. >>> >>> Within this context, let's also take the opportunity to make some >>> additional clean-ups and clarifications to the related code. >>> >>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> >>> --- >>> drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++---------------- >>> 1 file changed, 14 insertions(+), 16 deletions(-) >>> >>> diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c >>> index a84a880..481bbdb 100644 >>> --- a/drivers/mmc/core/mmc_ops.c >>> +++ b/drivers/mmc/core/mmc_ops.c >>> @@ -495,34 +495,32 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, >>> timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1; >>> do { >>> /* >>> - * Due to the possibility of being preempted after >>> - * sending the status command, check the expiration >>> - * time first. >>> + * Due to the possibility of being preempted while polling, >>> + * check the expiration time first. >>> */ >>> expired = time_after(jiffies, timeout); >>> - if (send_status) { >>> + >>> + if (host->ops->card_busy) { >>> + busy = host->ops->card_busy(host); >> >> I didn't really have time to look at these patches, sorry :-(. But this >> loop looks like it could use a cond_resched() > > Yes, something like that is definitely needed! Although, I suggest we > do that improvement on top of this change, if you are fine with that > approach? Sure > > The reason is that I am also pondering over, whether it could make > sense to poll with a dynamically increased interval. At least when > using ->card_busy(). > Let's say by starting at 1 us interval, then at each poll attempt we > double the interval time. We would then rather use a combination of > udelay(), usleep_range() and msleep() to accomplish what you propose. > Does that make sense to you? That potentially doubles the operation time. It might be nicer to limit the worst case e.g. sleep 1/8th of the total time spent looping s64 sleep_us; ktime_t start_time = ktime_get(); do { ... sleep_us = ktime_us_delta(ktime_get(), start_time) >> 3; sleep_us = sleep_us ? : 1; ... } while(busy); -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index a84a880..481bbdb 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -495,34 +495,32 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1; do { /* - * Due to the possibility of being preempted after - * sending the status command, check the expiration - * time first. + * Due to the possibility of being preempted while polling, + * check the expiration time first. */ expired = time_after(jiffies, timeout); - if (send_status) { + + if (host->ops->card_busy) { + busy = host->ops->card_busy(host); + } else { err = __mmc_send_status(card, &status, ignore_crc); if (err) return err; - } - if (host->ops->card_busy) { - if (!host->ops->card_busy(host)) - break; - busy = true; + busy = R1_CURRENT_STATE(status) == R1_STATE_PRG; } - /* Timeout if the device never leaves the program state. */ - if (expired && - (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy)) { - pr_err("%s: Card stuck in programming state! %s\n", + /* Timeout if the device still remains busy. */ + if (expired && busy) { + pr_err("%s: Card stuck being busy! %s\n", mmc_hostname(host), __func__); return -ETIMEDOUT; } - } while (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy); + } while (busy); - err = mmc_switch_status_error(host, status); + if (host->ops->card_busy && send_status) + return mmc_switch_status(card); - return err; + return mmc_switch_status_error(host, status); } /**
When polling for busy after sending a MMC_SWITCH command, both the optional ->card_busy() callback and CMD13 are being used in conjunction. This doesn't make sense. Instead it's more reasonable to rely solely on the ->card_busy() callback when it exists. Let's change that and instead use the CMD13 as a fall-back. In this way we avoid sending CMD13, unless it's really needed. Within this context, let's also take the opportunity to make some additional clean-ups and clarifications to the related code. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> --- drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) -- 1.9.1