linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner
@ 2020-04-17 21:15 Douglas Anderson
  2020-04-18 16:15 ` Matthias Kaehlcke
  2020-04-20 20:31 ` Bjorn Andersson
  0 siblings, 2 replies; 5+ messages in thread
From: Douglas Anderson @ 2020-04-17 21:15 UTC (permalink / raw)
  To: bjorn.andersson, agross
  Cc: swboyd, mkshah, Douglas Anderson, Evan Green, Srinivas Rao L,
	linux-arm-msm, linux-kernel

Adding an item into the cache should never be able to make the cache
cleaner.  Use "|=" rather than "=" to update the dirty flag.

Fixes: bb7000677a1b ("soc: qcom: rpmh: Update dirty flag only when data changes")
Reported-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

 drivers/soc/qcom/rpmh.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index 3abbb08cd6e1..d1626a1328d7 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -151,10 +151,10 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
 		break;
 	}
 
-	ctrlr->dirty = (req->sleep_val != old_sleep_val ||
-			req->wake_val != old_wake_val) &&
-			req->sleep_val != UINT_MAX &&
-			req->wake_val != UINT_MAX;
+	ctrlr->dirty |= (req->sleep_val != old_sleep_val ||
+			 req->wake_val != old_wake_val) &&
+			 req->sleep_val != UINT_MAX &&
+			 req->wake_val != UINT_MAX;
 
 unlock:
 	spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
-- 
2.26.1.301.g55bc3eb7cb9-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner
  2020-04-17 21:15 [PATCH] soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner Douglas Anderson
@ 2020-04-18 16:15 ` Matthias Kaehlcke
  2020-04-20 20:31 ` Bjorn Andersson
  1 sibling, 0 replies; 5+ messages in thread
From: Matthias Kaehlcke @ 2020-04-18 16:15 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: bjorn.andersson, agross, swboyd, mkshah, Evan Green,
	Srinivas Rao L, linux-arm-msm, linux-kernel

On Fri, Apr 17, 2020 at 02:15:47PM -0700, Douglas Anderson wrote:
> Adding an item into the cache should never be able to make the cache
> cleaner.  Use "|=" rather than "=" to update the dirty flag.
> 
> Fixes: bb7000677a1b ("soc: qcom: rpmh: Update dirty flag only when data changes")
> Reported-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> 
>  drivers/soc/qcom/rpmh.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
> index 3abbb08cd6e1..d1626a1328d7 100644
> --- a/drivers/soc/qcom/rpmh.c
> +++ b/drivers/soc/qcom/rpmh.c
> @@ -151,10 +151,10 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
>  		break;
>  	}
>  
> -	ctrlr->dirty = (req->sleep_val != old_sleep_val ||
> -			req->wake_val != old_wake_val) &&
> -			req->sleep_val != UINT_MAX &&
> -			req->wake_val != UINT_MAX;
> +	ctrlr->dirty |= (req->sleep_val != old_sleep_val ||
> +			 req->wake_val != old_wake_val) &&
> +			 req->sleep_val != UINT_MAX &&
> +			 req->wake_val != UINT_MAX;
>  
>  unlock:
>  	spin_unlock_irqrestore(&ctrlr->cache_lock, flags);

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner
  2020-04-17 21:15 [PATCH] soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner Douglas Anderson
  2020-04-18 16:15 ` Matthias Kaehlcke
@ 2020-04-20 20:31 ` Bjorn Andersson
  2020-04-20 20:47   ` Doug Anderson
  1 sibling, 1 reply; 5+ messages in thread
From: Bjorn Andersson @ 2020-04-20 20:31 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: agross, swboyd, mkshah, Evan Green, Srinivas Rao L,
	linux-arm-msm, linux-kernel

On Fri 17 Apr 14:15 PDT 2020, Douglas Anderson wrote:

> Adding an item into the cache should never be able to make the cache
> cleaner.  Use "|=" rather than "=" to update the dirty flag.
> 

This is correct...

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

> Fixes: bb7000677a1b ("soc: qcom: rpmh: Update dirty flag only when data changes")
> Reported-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> 
>  drivers/soc/qcom/rpmh.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
> index 3abbb08cd6e1..d1626a1328d7 100644
> --- a/drivers/soc/qcom/rpmh.c
> +++ b/drivers/soc/qcom/rpmh.c
> @@ -151,10 +151,10 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
>  		break;
>  	}
>  
> -	ctrlr->dirty = (req->sleep_val != old_sleep_val ||
> -			req->wake_val != old_wake_val) &&
> -			req->sleep_val != UINT_MAX &&
> -			req->wake_val != UINT_MAX;
> +	ctrlr->dirty |= (req->sleep_val != old_sleep_val ||
> +			 req->wake_val != old_wake_val) &&
> +			 req->sleep_val != UINT_MAX &&
> +			 req->wake_val != UINT_MAX;

...but this logic says dirty "if either sleep or wake has changed and
both sleep and wake are requested".

So what if we have an entry with only sleep wake changed, then the
controller won't be dirty and hence the hardware won't know about this
request - until another "fully specified" request comes in, which would
cause the controller to be dirty and flush out the "partially specified"
request as well.

Is this really the expected behavior?

Regards,
Bjorn

>  
>  unlock:
>  	spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
> -- 
> 2.26.1.301.g55bc3eb7cb9-goog
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner
  2020-04-20 20:31 ` Bjorn Andersson
@ 2020-04-20 20:47   ` Doug Anderson
  2020-04-21  6:57     ` Bjorn Andersson
  0 siblings, 1 reply; 5+ messages in thread
From: Doug Anderson @ 2020-04-20 20:47 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Stephen Boyd, Maulik Shah, Evan Green,
	Srinivas Rao L, linux-arm-msm, LKML

Hi,

On Mon, Apr 20, 2020 at 1:30 PM Bjorn Andersson
<bjorn.andersson@linaro.org> wrote:
>
> On Fri 17 Apr 14:15 PDT 2020, Douglas Anderson wrote:
>
> > Adding an item into the cache should never be able to make the cache
> > cleaner.  Use "|=" rather than "=" to update the dirty flag.
> >
>
> This is correct...
>
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
>
> > Fixes: bb7000677a1b ("soc: qcom: rpmh: Update dirty flag only when data changes")
> > Reported-by: Stephen Boyd <swboyd@chromium.org>
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > ---
> >
> >  drivers/soc/qcom/rpmh.c | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
> > index 3abbb08cd6e1..d1626a1328d7 100644
> > --- a/drivers/soc/qcom/rpmh.c
> > +++ b/drivers/soc/qcom/rpmh.c
> > @@ -151,10 +151,10 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
> >               break;
> >       }
> >
> > -     ctrlr->dirty = (req->sleep_val != old_sleep_val ||
> > -                     req->wake_val != old_wake_val) &&
> > -                     req->sleep_val != UINT_MAX &&
> > -                     req->wake_val != UINT_MAX;
> > +     ctrlr->dirty |= (req->sleep_val != old_sleep_val ||
> > +                      req->wake_val != old_wake_val) &&
> > +                      req->sleep_val != UINT_MAX &&
> > +                      req->wake_val != UINT_MAX;
>
> ...but this logic says dirty "if either sleep or wake has changed and
> both sleep and wake are requested".
>
> So what if we have an entry with only sleep wake changed, then the
> controller won't be dirty and hence the hardware won't know about this
> request - until another "fully specified" request comes in, which would
> cause the controller to be dirty and flush out the "partially specified"
> request as well.
>
> Is this really the expected behavior?

IIRC, this has to do with how is_req_valid() works and how it's called
from rpmh_flush().  ...but since I clearly screwed up the "|=" in the
past let's see if I screwed this up too.  ...errr, what I mean to say
is that I never make any mistakes.  Ever.  How dare you accuse me of
such a thing?  ;-)

So is_req_valid() says that a request is valid if all three of these are true
* Sleep is not UINT_MAX
* Wake is not UINT_MAX
* Sleep is not equal to wake

If a request is not valid then rpmh_flush will ignore it, it won't be
sent, and it's as if it wasn't even in the cache.  Also: It's not
expected that anyone will ever change a value _to_ UINT_MAX, so once
something is initialized it's never uninitialized (NOTE: I don't think
anything actually enforces this).

The above means that until both sleep and wake have changed away from
their default of UINT_MAX that they can't really dirty the cache
because we act as if they're not even in the cache.  Once they get
something then the cache gets dirty if either sleep changes or wake
changes.


So I think the logic is right...  Does that make sense?


-Doug

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner
  2020-04-20 20:47   ` Doug Anderson
@ 2020-04-21  6:57     ` Bjorn Andersson
  0 siblings, 0 replies; 5+ messages in thread
From: Bjorn Andersson @ 2020-04-21  6:57 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Andy Gross, Stephen Boyd, Maulik Shah, Evan Green,
	Srinivas Rao L, linux-arm-msm, LKML

On Mon 20 Apr 13:47 PDT 2020, Doug Anderson wrote:

> Hi,
> 
> On Mon, Apr 20, 2020 at 1:30 PM Bjorn Andersson
> <bjorn.andersson@linaro.org> wrote:
> >
> > On Fri 17 Apr 14:15 PDT 2020, Douglas Anderson wrote:
> >
> > > Adding an item into the cache should never be able to make the cache
> > > cleaner.  Use "|=" rather than "=" to update the dirty flag.
> > >
> >
> > This is correct...
> >
> > Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> >
> > > Fixes: bb7000677a1b ("soc: qcom: rpmh: Update dirty flag only when data changes")
> > > Reported-by: Stephen Boyd <swboyd@chromium.org>
> > > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > > ---
> > >
> > >  drivers/soc/qcom/rpmh.c | 8 ++++----
> > >  1 file changed, 4 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
> > > index 3abbb08cd6e1..d1626a1328d7 100644
> > > --- a/drivers/soc/qcom/rpmh.c
> > > +++ b/drivers/soc/qcom/rpmh.c
> > > @@ -151,10 +151,10 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
> > >               break;
> > >       }
> > >
> > > -     ctrlr->dirty = (req->sleep_val != old_sleep_val ||
> > > -                     req->wake_val != old_wake_val) &&
> > > -                     req->sleep_val != UINT_MAX &&
> > > -                     req->wake_val != UINT_MAX;
> > > +     ctrlr->dirty |= (req->sleep_val != old_sleep_val ||
> > > +                      req->wake_val != old_wake_val) &&
> > > +                      req->sleep_val != UINT_MAX &&
> > > +                      req->wake_val != UINT_MAX;
> >
> > ...but this logic says dirty "if either sleep or wake has changed and
> > both sleep and wake are requested".
> >
> > So what if we have an entry with only sleep wake changed, then the
> > controller won't be dirty and hence the hardware won't know about this
> > request - until another "fully specified" request comes in, which would
> > cause the controller to be dirty and flush out the "partially specified"
> > request as well.
> >
> > Is this really the expected behavior?
> 
> IIRC, this has to do with how is_req_valid() works and how it's called
> from rpmh_flush().  ...but since I clearly screwed up the "|=" in the
> past let's see if I screwed this up too.  ...errr, what I mean to say
> is that I never make any mistakes.  Ever.  How dare you accuse me of
> such a thing?  ;-)
> 
> So is_req_valid() says that a request is valid if all three of these are true
> * Sleep is not UINT_MAX
> * Wake is not UINT_MAX
> * Sleep is not equal to wake
> 
> If a request is not valid then rpmh_flush will ignore it, it won't be
> sent, and it's as if it wasn't even in the cache.  Also: It's not
> expected that anyone will ever change a value _to_ UINT_MAX, so once
> something is initialized it's never uninitialized (NOTE: I don't think
> anything actually enforces this).
> 
> The above means that until both sleep and wake have changed away from
> their default of UINT_MAX that they can't really dirty the cache
> because we act as if they're not even in the cache.  Once they get
> something then the cache gets dirty if either sleep changes or wake
> changes.
> 
> 
> So I think the logic is right...  Does that make sense?
> 

Okay, that makes sense. Iirc how the RPMh deals with entering and
exiting the sleep state having one without the other shouldn't be valid,
so it sounds like we're good here.

Thanks for the explanation, applied the patch.

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-04-21  6:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-17 21:15 [PATCH] soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner Douglas Anderson
2020-04-18 16:15 ` Matthias Kaehlcke
2020-04-20 20:31 ` Bjorn Andersson
2020-04-20 20:47   ` Doug Anderson
2020-04-21  6:57     ` Bjorn Andersson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).