linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Fabio Baltieri <fabio.baltieri@linaro.org>
To: Viresh Kumar <viresh.kumar@linaro.org>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>,
	cpufreq@vger.kernel.org, linux-pm@vger.kernel.org,
	Linus Walleij <linus.walleij@linaro.org>,
	swarren@wwwdotorg.org, linaro-dev@lists.linaro.org,
	Nicolas Pitre <nicolas.pitre@linaro.org>,
	mathieu.poirier@linaro.org, Joseph Lo <josephl@nvidia.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v7 2/4] cpufreq: ondemand: call dbs_check_cpu only when necessary
Date: Wed, 30 Jan 2013 17:46:14 +0100	[thread overview]
Message-ID: <20130130164614.GC30559@balto.lan> (raw)
In-Reply-To: <CAKohpok0iDffNM31W2r97Wtq4DR+TdPwYWTAdJH7AyLqHm0UPA@mail.gmail.com>

On Wed, Jan 30, 2013 at 09:21:41PM +0530, Viresh Kumar wrote:
> On 30 January 2013 18:30, Fabio Baltieri <fabio.baltieri@linaro.org> wrote:
> > Modify ondemand timer to not resample CPU utilization if recently
> > sampled from another SW coordinated core.
> >
> > Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org>
> 
> I might be wrong but i have some real concerns over this patch.
> 
> This is what i believe is your idea:
> - because a cpu can sleep, create timer per cpu
> - then check load again only when no other cpu in policy->cpus has
>   checked load within sampling time interval.
> 
> Correct?

Yes.

> > ---
> >  drivers/cpufreq/cpufreq_governor.c |  3 ++
> >  drivers/cpufreq/cpufreq_governor.h |  1 +
> >  drivers/cpufreq/cpufreq_ondemand.c | 58 +++++++++++++++++++++++++++++++-------
> >  3 files changed, 52 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
> > index 8393d6e..46f96a4 100644
> > --- a/drivers/cpufreq/cpufreq_governor.c
> > +++ b/drivers/cpufreq/cpufreq_governor.c
> > @@ -289,6 +289,9 @@ second_time:
> >                 }
> >                 mutex_unlock(&dbs_data->mutex);
> >
> > +               /* Initiate timer time stamp */
> > +               cpu_cdbs->time_stamp = ktime_get();
> 
> We have updated time_stamp only for policy->cpu's cdbs.

Yes, see below.

> >                 for_each_cpu(j, policy->cpus)
> >                         dbs_timer_init(dbs_data, j, *sampling_rate);
> >                 break;
> 
> > diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
> > index 93bb56d..13ceb3c 100644
> > --- a/drivers/cpufreq/cpufreq_ondemand.c
> > +++ b/drivers/cpufreq/cpufreq_ondemand.c
> > @@ -216,23 +216,23 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
> >         }
> >  }
> >
> > -static void od_dbs_timer(struct work_struct *work)
> > +static void od_timer_update(struct od_cpu_dbs_info_s *dbs_info, bool sample,
> > +                           struct delayed_work *dw)
> >  {
> > -       struct od_cpu_dbs_info_s *dbs_info =
> > -               container_of(work, struct od_cpu_dbs_info_s, cdbs.work.work);
> >         unsigned int cpu = dbs_info->cdbs.cpu;
> >         int delay, sample_type = dbs_info->sample_type;
> >
> > -       mutex_lock(&dbs_info->cdbs.timer_mutex);
> > -
> >         /* Common NORMAL_SAMPLE setup */
> >         dbs_info->sample_type = OD_NORMAL_SAMPLE;
> >         if (sample_type == OD_SUB_SAMPLE) {
> >                 delay = dbs_info->freq_lo_jiffies;
> > -               __cpufreq_driver_target(dbs_info->cdbs.cur_policy,
> > -                       dbs_info->freq_lo, CPUFREQ_RELATION_H);
> > +               if (sample)
> > +                       __cpufreq_driver_target(dbs_info->cdbs.cur_policy,
> > +                                               dbs_info->freq_lo,
> > +                                               CPUFREQ_RELATION_H);
> >         } else {
> > -               dbs_check_cpu(&od_dbs_data, cpu);
> > +               if (sample)
> > +                       dbs_check_cpu(&od_dbs_data, cpu);
> >                 if (dbs_info->freq_lo) {
> >                         /* Setup timer for SUB_SAMPLE */
> >                         dbs_info->sample_type = OD_SUB_SAMPLE;
> > @@ -243,11 +243,49 @@ static void od_dbs_timer(struct work_struct *work)
> >                 }
> >         }
> >
> > -       schedule_delayed_work_on(smp_processor_id(), &dbs_info->cdbs.work,
> > -                       delay);
> > +       schedule_delayed_work_on(smp_processor_id(), dw, delay);
> > +}
> 
> All good until now.
> 
> > +
> > +static void od_timer_coordinated(struct od_cpu_dbs_info_s *dbs_info_local,
> > +                                struct delayed_work *dw)
> > +{
> > +       struct od_cpu_dbs_info_s *dbs_info;
> > +       ktime_t time_now;
> > +       s64 delta_us;
> > +       bool sample = true;
> > +
> 
> --start--
> 
> > +       /* use leader CPU's dbs_info */
> > +       dbs_info = &per_cpu(od_cpu_dbs_info, dbs_info_local->cdbs.cpu);
> > +       mutex_lock(&dbs_info->cdbs.timer_mutex);
> > +
> > +       time_now = ktime_get();
> > +       delta_us = ktime_us_delta(time_now, dbs_info->cdbs.time_stamp);
> > +
> > +       /* Do nothing if we recently have sampled */
> > +       if (delta_us < (s64)(od_tuners.sampling_rate / 2))
> > +               sample = false;
> > +       else
> > +               dbs_info->cdbs.time_stamp = time_now;
> > +
> 
> --end--
> 
> Instead of two routines (this and the one below), we can have one and can
> put the above code in the if (coordinated cpus case). That will save some
> redundant code.

Ok but then you have two dbs_infos mixing up in the same code and it
start to become harder to read (first version was with a single function
I think).

> Another issue that i see is: Current routine will be called from timer handler
> of every cpu and so above calculations will happen for every cpu. Here, you
> are taking the diff of last timestamp of cpu "x" with cpu "x" current timestamp,
> but what you should have really done is the diff b/w current timestamp with
> the timestamp of last change on any cpu in policy->cpus.

Isn't that how it works now?  The current cpu ktime is not checked
against its own, but against the "leader" cpu (dbs_info_local->cdbs.cpu),
that's why it's initialized only for the first.

Maybe I should have used dbs_info_leader/dbs_info instead of
dbs_info_local/dbs_info.

> Over that, timestamp for all cpu's isn't initialized early in the code
> at GOV_START.
> 
> Am i correct?

As above.

Fabio

> > +       od_timer_update(dbs_info, sample, dw);
> >         mutex_unlock(&dbs_info->cdbs.timer_mutex);
> >  }
> >
> > +static void od_dbs_timer(struct work_struct *work)
> > +{
> > +       struct delayed_work *dw = to_delayed_work(work);
> > +       struct od_cpu_dbs_info_s *dbs_info =
> > +               container_of(work, struct od_cpu_dbs_info_s, cdbs.work.work);
> > +
> > +       if (dbs_sw_coordinated_cpus(&dbs_info->cdbs)) {
> > +               od_timer_coordinated(dbs_info, dw);
> > +       } else {
> > +               mutex_lock(&dbs_info->cdbs.timer_mutex);
> > +               od_timer_update(dbs_info, true, dw);
> > +               mutex_unlock(&dbs_info->cdbs.timer_mutex);
> > +       }
> > +}
> > +

-- 
Fabio Baltieri

  reply	other threads:[~2013-01-30 16:46 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-30 12:59 [PATCH v7 0/5] cpufreq: handle SW coordinated CPUs Fabio Baltieri
2013-01-30 13:00 ` [PATCH v7 1/4] " Fabio Baltieri
2013-01-30 15:02   ` Viresh Kumar
2013-01-30 16:23     ` Fabio Baltieri
2013-01-30 16:51       ` Viresh Kumar
2013-01-30 16:57         ` Fabio Baltieri
2013-01-30 21:44           ` Rafael J. Wysocki
2013-01-30 13:00 ` [PATCH v7 2/4] cpufreq: ondemand: call dbs_check_cpu only when necessary Fabio Baltieri
2013-01-30 15:51   ` Viresh Kumar
2013-01-30 16:46     ` Fabio Baltieri [this message]
     [not found]       ` <20130130164614.GC30559-lYxsXyORJ9v/PtFMR13I2A@public.gmane.org>
2013-01-30 17:11         ` Viresh Kumar
2013-01-31  8:39           ` Fabio Baltieri
     [not found]             ` <20130131083825.GA30667-lYxsXyORJ9v/PtFMR13I2A@public.gmane.org>
2013-01-31  8:42               ` Viresh Kumar
2013-01-31  9:06                 ` Fabio Baltieri
2013-01-31  9:11                   ` Viresh Kumar
2013-01-30 13:00 ` [PATCH v7 3/4] cpufreq: conservative: " Fabio Baltieri
2013-01-30 15:53   ` Viresh Kumar
2013-01-30 16:53     ` Fabio Baltieri
     [not found]       ` <20130130165321.GD30559-lYxsXyORJ9v/PtFMR13I2A@public.gmane.org>
2013-01-30 17:12         ` Viresh Kumar
     [not found] ` <1359550803-18577-1-git-send-email-fabio.baltieri-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-01-30 13:00   ` [PATCH v7 4/4] cpufreq: ondemand: use all CPUs in update_sampling_rate Fabio Baltieri

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130130164614.GC30559@balto.lan \
    --to=fabio.baltieri@linaro.org \
    --cc=cpufreq@vger.kernel.org \
    --cc=josephl@nvidia.com \
    --cc=linaro-dev@lists.linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mathieu.poirier@linaro.org \
    --cc=nicolas.pitre@linaro.org \
    --cc=rjw@sisk.pl \
    --cc=swarren@wwwdotorg.org \
    --cc=viresh.kumar@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).