lkml.org 
[lkml]   [2014]   [Sep]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4/6] PID: Add new function pointers to read multiple registers
    Date
    There are cases where it is more efficient to read multiple
    counters or registers at once. To enable such reads, add new
    function pointers for the backend drivers. This is especially
    useful when the registers are memory mapped (e.g. in PCC) and
    the platform is signalled via a Doorbell to update multiple
    registers at once. In contrast, we'd have to ring the Doorbell
    for every register Read.

    Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
    ---
    drivers/cpufreq/intel_pid_ctrl.c | 49 ++++++++++++++++++++++++++++++++++------
    drivers/cpufreq/pid_ctrl.c | 34 ++++++----------------------
    drivers/cpufreq/pid_ctrl.h | 2 ++
    3 files changed, 51 insertions(+), 34 deletions(-)

    diff --git a/drivers/cpufreq/intel_pid_ctrl.c b/drivers/cpufreq/intel_pid_ctrl.c
    index a858981..73faaf8 100644
    --- a/drivers/cpufreq/intel_pid_ctrl.c
    +++ b/drivers/cpufreq/intel_pid_ctrl.c
    @@ -37,6 +37,7 @@ struct vid_data {
    };

    static struct vid_data vid_data;
    +static struct cpu_defaults *cpuinfo;

    struct perf_limits limits = {
    .no_turbo = 0,
    @@ -171,6 +172,37 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate)
    wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val);
    }

    +static void intel_get_pstates(struct cpudata *cpu)
    +{
    + cpu->pstate.min_pstate = cpuinfo->funcs.get_min();
    + cpu->pstate.max_pstate = cpuinfo->funcs.get_max();
    +
    + if (cpuinfo->funcs.get_turbo)
    + cpu->pstate.turbo_pstate = cpuinfo->funcs.get_turbo();
    + else
    + cpu->pstate.turbo_pstate = cpu->pstate.max_pstate;
    +}
    +
    +static void intel_get_sample(struct cpudata *cpu)
    +{
    + u64 aperf, mperf;
    +
    + rdmsrl(MSR_IA32_APERF, aperf);
    + rdmsrl(MSR_IA32_MPERF, mperf);
    +
    + aperf = aperf >> FRAC_BITS;
    + mperf = mperf >> FRAC_BITS;
    +
    + cpu->sample.aperf = aperf;
    + cpu->sample.mperf = mperf;
    +
    + cpu->sample.aperf -= cpu->prev_aperf;
    + cpu->sample.mperf -= cpu->prev_mperf;
    +
    + cpu->prev_aperf = aperf;
    + cpu->prev_mperf = mperf;
    +}
    +
    static struct cpu_defaults core_params = {
    .pid_policy = {
    .sample_rate_ms = 10,
    @@ -181,9 +213,11 @@ static struct cpu_defaults core_params = {
    .i_gain_pct = 0,
    },
    .funcs = {
    + .get_turbo = core_get_turbo_pstate,
    + .get_sample = intel_get_sample,
    + .get_pstates = intel_get_pstates,
    .get_max = core_get_max_pstate,
    .get_min = core_get_min_pstate,
    - .get_turbo = core_get_turbo_pstate,
    .set = core_set_pstate,
    },
    };
    @@ -198,9 +232,11 @@ static struct cpu_defaults byt_params = {
    .i_gain_pct = 4,
    },
    .funcs = {
    + .get_turbo = byt_get_turbo_pstate,
    + .get_sample = intel_get_sample,
    + .get_pstates = intel_get_pstates,
    .get_max = byt_get_max_pstate,
    .get_min = byt_get_min_pstate,
    - .get_turbo = byt_get_turbo_pstate,
    .set = byt_set_pstate,
    },
    };
    @@ -327,7 +363,6 @@ static inline bool intel_pid_ctrl_platform_pwr_mgmt_exists(void)
    static int __init intel_pid_ctrl_init(void)
    {
    const struct x86_cpu_id *id;
    - struct cpu_defaults *cpu_info;

    if (no_load)
    return -ENODEV;
    @@ -343,15 +378,15 @@ static int __init intel_pid_ctrl_init(void)
    if (intel_pid_ctrl_platform_pwr_mgmt_exists())
    return -ENODEV;

    - cpu_info = (struct cpu_defaults *)id->driver_data;
    + cpuinfo = (struct cpu_defaults *)id->driver_data;

    - if (intel_pid_ctrl_msrs_not_valid(cpu_info))
    + if (intel_pid_ctrl_msrs_not_valid(cpuinfo))
    return -ENODEV;

    pr_info("Intel PID controller driver initializing.\n");

    - register_pid_params(&cpu_info->pid_policy);
    - register_cpu_funcs(&cpu_info->funcs);
    + register_pid_params(&cpuinfo->pid_policy);
    + register_cpu_funcs(&cpuinfo->funcs);

    return 0;
    }
    diff --git a/drivers/cpufreq/pid_ctrl.c b/drivers/cpufreq/pid_ctrl.c
    index 8eb9739..a011f05 100644
    --- a/drivers/cpufreq/pid_ctrl.c
    +++ b/drivers/cpufreq/pid_ctrl.c
    @@ -311,14 +311,7 @@ static inline void pid_ctrl_pstate_decrease(struct cpudata *cpu, int steps)

    static void pid_ctrl_get_cpu_pstates(struct cpudata *cpu)
    {
    - cpu->pstate.min_pstate = pstate_funcs.get_min();
    - cpu->pstate.max_pstate = pstate_funcs.get_max();
    -
    - if (pstate_funcs.get_turbo)
    - cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
    - else
    - cpu->pstate.turbo_pstate = cpu->pstate.max_pstate;
    -
    + pstate_funcs.get_pstates(cpu);
    pid_ctrl_set_pstate(cpu, cpu->pstate.min_pstate);
    }

    @@ -342,25 +335,12 @@ static inline void pid_ctrl_calc_busy(struct cpudata *cpu)

    static inline void pid_ctrl_sample(struct cpudata *cpu)
    {
    - u64 aperf, mperf;
    -
    - rdmsrl(MSR_IA32_APERF, aperf);
    - rdmsrl(MSR_IA32_MPERF, mperf);
    -
    - aperf = aperf >> FRAC_BITS;
    - mperf = mperf >> FRAC_BITS;
    -
    cpu->last_sample_time = cpu->sample.time;
    cpu->sample.time = ktime_get();
    - cpu->sample.aperf = aperf;
    - cpu->sample.mperf = mperf;
    - cpu->sample.aperf -= cpu->prev_aperf;
    - cpu->sample.mperf -= cpu->prev_mperf;

    - pid_ctrl_calc_busy(cpu);
    + pstate_funcs.get_sample(cpu);

    - cpu->prev_aperf = aperf;
    - cpu->prev_mperf = mperf;
    + pid_ctrl_calc_busy(cpu);
    }

    static inline void pid_ctrl_set_sample_time(struct cpudata *cpu)
    @@ -585,8 +565,8 @@ EXPORT_SYMBOL_GPL(register_pid_params);

    void register_cpu_funcs(struct pstate_funcs *funcs)
    {
    - pstate_funcs.get_max = funcs->get_max;
    - pstate_funcs.get_min = funcs->get_min;
    + pstate_funcs.get_pstates = funcs->get_pstates;
    + pstate_funcs.get_sample = funcs->get_sample;
    pstate_funcs.get_turbo = funcs->get_turbo;
    pstate_funcs.set = funcs->set;
    }
    @@ -596,8 +576,8 @@ static int __init pid_ctrl_init(void)
    {
    int cpu, rc = 0;

    - if (!pstate_funcs.get_max ||
    - !pstate_funcs.get_min ||
    + if (!pstate_funcs.get_pstates ||
    + !pstate_funcs.get_sample ||
    !pstate_funcs.set ||
    !pid_params.sample_rate_ms) {
    pr_err("Err registering pstate func accessors\n");
    diff --git a/drivers/cpufreq/pid_ctrl.h b/drivers/cpufreq/pid_ctrl.h
    index 40b352a..7f732e6 100644
    --- a/drivers/cpufreq/pid_ctrl.h
    +++ b/drivers/cpufreq/pid_ctrl.h
    @@ -73,6 +73,8 @@ struct cpudata {
    struct pstate_funcs {
    int (*get_max)(void);
    int (*get_min)(void);
    + void (*get_pstates)(struct cpudata *);
    + void (*get_sample)(struct cpudata *);
    int (*get_turbo)(void);
    void (*set)(struct cpudata*, int pstate);
    };
    --
    1.9.1


    \
     
     \ /
      Last update: 2014-09-10 00:41    [W:2.599 / U:1.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site