Message ID | 1586154741-8293-4-git-send-email-mkshah@codeaurora.org (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Invoke rpmh_flush for non OSI targets | expand |
Quoting Maulik Shah (2020-04-05 23:32:18) > TCSes have previously programmed data when rpmh_flush is called. rpmh_flush() > This can cause old data to trigger along with newly flushed. > > Fix this by cleaning SLEEP and WAKE TCSes before new data is flushed. > > With this there is no need to invoke rpmh_rsc_invalidate() call from > rpmh_invalidate(). > > Simplify rpmh_invalidate() by moving invalidate_batch() inside. > > Fixes: 600513dfeef3 ("drivers: qcom: rpmh: cache sleep/wake state requests") > Signed-off-by: Maulik Shah <mkshah@codeaurora.org> > Reviewed-by: Douglas Anderson <dianders@chromium.org> > --- > drivers/soc/qcom/rpmh.c | 41 ++++++++++++++++++----------------------- > 1 file changed, 18 insertions(+), 23 deletions(-) > > diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c > index 03630ae..a75f3df 100644 > --- a/drivers/soc/qcom/rpmh.c > +++ b/drivers/soc/qcom/rpmh.c > @@ -498,24 +492,25 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) > } > > /** > - * rpmh_invalidate: Invalidate all sleep and active sets > - * sets. > + * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache > * > * @dev: The device making the request > * > - * Invalidate the sleep and active values in the TCS blocks. > + * Invalidate the sleep and wake values in batch_cache. > */ > int rpmh_invalidate(const struct device *dev) > { > struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); > - int ret; > - > - invalidate_batch(ctrlr); > + struct batch_cache_req *req, *tmp; > + unsigned long flags; > > - do { > - ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr)); > - } while (ret == -EAGAIN); > + spin_lock_irqsave(&ctrlr->cache_lock, flags); > + list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) > + kfree(req); > + INIT_LIST_HEAD(&ctrlr->batch_cache); > + ctrlr->dirty = true; > + spin_unlock_irqrestore(&ctrlr->cache_lock, flags); > > - return ret; > + return 0; Now this always returns 0. Maybe it should become a void function, but doing that requires a change in the interconnect code so maybe do it later.
Hi, On 4/10/2020 1:53 AM, Stephen Boyd wrote: > Quoting Maulik Shah (2020-04-05 23:32:18) >> TCSes have previously programmed data when rpmh_flush is called. > rpmh_flush() Ok, i will update in v17. > >> This can cause old data to trigger along with newly flushed. >> >> Fix this by cleaning SLEEP and WAKE TCSes before new data is flushed. >> >> With this there is no need to invoke rpmh_rsc_invalidate() call from >> rpmh_invalidate(). >> >> Simplify rpmh_invalidate() by moving invalidate_batch() inside. >> >> Fixes: 600513dfeef3 ("drivers: qcom: rpmh: cache sleep/wake state requests") >> Signed-off-by: Maulik Shah <mkshah@codeaurora.org> >> Reviewed-by: Douglas Anderson <dianders@chromium.org> >> --- >> drivers/soc/qcom/rpmh.c | 41 ++++++++++++++++++----------------------- >> 1 file changed, 18 insertions(+), 23 deletions(-) >> >> diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c >> index 03630ae..a75f3df 100644 >> --- a/drivers/soc/qcom/rpmh.c >> +++ b/drivers/soc/qcom/rpmh.c >> @@ -498,24 +492,25 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) >> } >> >> /** >> - * rpmh_invalidate: Invalidate all sleep and active sets >> - * sets. >> + * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache >> * >> * @dev: The device making the request >> * >> - * Invalidate the sleep and active values in the TCS blocks. >> + * Invalidate the sleep and wake values in batch_cache. >> */ >> int rpmh_invalidate(const struct device *dev) >> { >> struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); >> - int ret; >> - >> - invalidate_batch(ctrlr); >> + struct batch_cache_req *req, *tmp; >> + unsigned long flags; >> >> - do { >> - ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr)); >> - } while (ret == -EAGAIN); >> + spin_lock_irqsave(&ctrlr->cache_lock, flags); >> + list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) >> + kfree(req); >> + INIT_LIST_HEAD(&ctrlr->batch_cache); >> + ctrlr->dirty = true; >> + spin_unlock_irqrestore(&ctrlr->cache_lock, flags); >> >> - return ret; >> + return 0; > Now this always returns 0. Maybe it should become a void function, but > doing that requires a change in the interconnect code so maybe do it > later. Sure i will add in my To-Do list. Thanks, Maulik
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index 03630ae..a75f3df 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -317,19 +317,6 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr) return ret; } -static void invalidate_batch(struct rpmh_ctrlr *ctrlr) -{ - struct batch_cache_req *req, *tmp; - unsigned long flags; - - spin_lock_irqsave(&ctrlr->cache_lock, flags); - list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) - kfree(req); - INIT_LIST_HEAD(&ctrlr->batch_cache); - ctrlr->dirty = true; - spin_unlock_irqrestore(&ctrlr->cache_lock, flags); -} - /** * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the * batch to finish. @@ -467,6 +454,13 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) return 0; } + /* Invalidate the TCSes first to avoid stale data */ + do { + ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr)); + } while (ret == -EAGAIN); + if (ret) + return ret; + /* First flush the cached batch requests */ ret = flush_batch(ctrlr); if (ret) @@ -498,24 +492,25 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) } /** - * rpmh_invalidate: Invalidate all sleep and active sets - * sets. + * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache * * @dev: The device making the request * - * Invalidate the sleep and active values in the TCS blocks. + * Invalidate the sleep and wake values in batch_cache. */ int rpmh_invalidate(const struct device *dev) { struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); - int ret; - - invalidate_batch(ctrlr); + struct batch_cache_req *req, *tmp; + unsigned long flags; - do { - ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr)); - } while (ret == -EAGAIN); + spin_lock_irqsave(&ctrlr->cache_lock, flags); + list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) + kfree(req); + INIT_LIST_HEAD(&ctrlr->batch_cache); + ctrlr->dirty = true; + spin_unlock_irqrestore(&ctrlr->cache_lock, flags); - return ret; + return 0; } EXPORT_SYMBOL(rpmh_invalidate);