On Fri, 27 Mar 2015 12:15:15 +0100 Ulf Hansson <ulf.hansson@xxxxxxxxxx> wrote: > Currently those host drivers which have deployed runtime PM, deals with > the runtime PM reference counting entirely by themselves. > > Since host drivers don't know when the core will send the next request > through some of the host_ops callbacks, they need to handle runtime PM > get/put between each an every request. > > In quite many cases this has some negative effects, since it leads to a > high frequency of scheduled runtime PM suspend operations. That due to > the runtime PM reference count will normally reach zero in-between > every request. I don't understand why this is a problem. All the drivers use put_autosuspend, so the suspend doesn't happen for (typically) 50ms, so the actually suspend won't happen if there is a sequence of requests. Is it just the scheduling of a suspend - even without the suspend happening - that is causing problems? If so, maybe the runtime_pm code needs optimising? Thanks, NeilBrown > > We can decrease that frequency, by enabling the core to deal with > runtime PM reference counting of the host device. Since the core often > knows that it will send a seqeunce of requests, it makes sense for it > to keep a runtime PM reference count during these periods. > > More exactly, let's increase the runtime PM reference count by invoking > pm_runtime_get_sync() from __mmc_claim_host(). Restore that action by > invoking pm_runtime_mark_last_busy() and pm_runtime_put_autosuspend() > in mmc_release_host(). In this way a runtime PM reference count will be > kept during the complete cycle of a claim -> release host. > > Signed-off-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx> > --- > drivers/mmc/core/core.c | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c > index 709ada9..c296bc0 100644 > --- a/drivers/mmc/core/core.c > +++ b/drivers/mmc/core/core.c > @@ -897,6 +897,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) > DECLARE_WAITQUEUE(wait, current); > unsigned long flags; > int stop; > + bool pm = false; > > might_sleep(); > > @@ -916,13 +917,18 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) > host->claimed = 1; > host->claimer = current; > host->claim_cnt += 1; > + if (host->claim_cnt == 1) > + pm = true; > } else > wake_up(&host->wq); > spin_unlock_irqrestore(&host->lock, flags); > remove_wait_queue(&host->wq, &wait); > + > + if (pm) > + pm_runtime_get_sync(mmc_dev(host)); > + > return stop; > } > - > EXPORT_SYMBOL(__mmc_claim_host); > > /** > @@ -947,6 +953,8 @@ void mmc_release_host(struct mmc_host *host) > host->claimer = NULL; > spin_unlock_irqrestore(&host->lock, flags); > wake_up(&host->wq); > + pm_runtime_mark_last_busy(mmc_dev(host)); > + pm_runtime_put_autosuspend(mmc_dev(host)); > } > } > EXPORT_SYMBOL(mmc_release_host);
Attachment:
pgpFCp0z80Fv5.pgp
Description: OpenPGP digital signature