1. 27 12月, 2022 1 次提交
  2. 25 9月, 2022 1 次提交
  3. 25 8月, 2022 1 次提交
  4. 30 5月, 2022 2 次提交
  5. 20 5月, 2022 2 次提交
  6. 07 5月, 2022 2 次提交
    • P
      cpufreq: CPPC: Register EM based on efficiency class information · 740fcdc2
      Pierre Gondois 提交于
      Performance states and energy consumption values are not advertised
      in ACPI. In the GicC structure of the MADT table, the "Processor
      Power Efficiency Class field" (called efficiency class from now)
      allows to describe the relative energy efficiency of CPUs.
      
      To leverage the EM and EAS, the CPPC driver creates a set of
      artificial performance states and registers them in the Energy Model
      (EM), such as:
      - Every 20 capacity unit, a performance state is created.
      - The energy cost of each performance state gradually increases.
      No power value is generated as only the cost is used in the EM.
      
      During task placement, a task can raise the frequency of its whole
      pd. This can make EAS place a task on a pd with CPUs that are
      individually less energy efficient.
      As cost values are artificial, and to place tasks on CPUs with the
      lower efficiency class, a gap in cost values is generated for adjacent
      efficiency classes.
      E.g.:
      - efficiency class = 0, capacity is in [0-1024], so cost values
        are in [0: 51] (one performance state every 20 capacity unit)
      - efficiency class = 1, capacity is in [0-1024], cost values
        are in [1*gap+0: 1*gap+51].
      
      The value of the cost gap is chosen to absorb a the energy of 4 CPUs
      at their maximum capacity. This means that between:
      1- a pd of 4 CPUs, each of them being used at almost their full
         capacity. Their efficiency class is N.
      2- a CPU using almost none of its capacity. Its efficiency class is
         N+1
      EAS will choose the first option.
      
      This patch also populates the (struct cpufreq_driver).register_em
      callback if the valid efficiency_class ACPI values are provided.
      Signed-off-by: NPierre Gondois <Pierre.Gondois@arm.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      740fcdc2
    • P
      cpufreq: CPPC: Add per_cpu efficiency_class · d3c3db41
      Pierre Gondois 提交于
      In ACPI, describing power efficiency of CPUs can be done through the
      following arm specific field:
      ACPI 6.4, s5.2.12.14 'GIC CPU Interface (GICC) Structure',
      'Processor Power Efficiency Class field':
        Describes the relative power efficiency of the associated pro-
        cessor. Lower efficiency class numbers are more efficient than
        higher ones (e.g. efficiency class 0 should be treated as more
        efficient than efficiency class 1). However, absolute values
        of this number have no meaning: 2 isn’t necessarily half as
        efficient as 1.
      
      The efficiency_class field is stored in the GicC structure of the
      ACPI MADT table and it's currently supported in Linux for arm64 only.
      Thus, this new functionality is introduced for arm64 only.
      
      To allow the cppc_cpufreq driver to know and preprocess the
      efficiency_class values of all the CPUs, add a per_cpu efficiency_class
      variable to store them.
      
      At least 2 different efficiency classes must be present,
      otherwise there is no use in creating an Energy Model.
      
      The efficiency_class values are squeezed in [0:#efficiency_class-1]
      while conserving the order. For instance, efficiency classes of:
        [111, 212, 250]
      will be mapped to:
        [0 (was 111), 1 (was 212), 2 (was 250)].
      
      Each policy being independently registered in the driver, populating
      the per_cpu efficiency_class is done only once at the driver
      initialization. This prevents from having each policy re-searching the
      efficiency_class values of other CPUs. The EM will be registered in a
      following patch.
      
      The patch also exports acpi_cpu_get_madt_gicc() to fetch the GicC
      structure of the ACPI MADT table for each CPU.
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NPierre Gondois <Pierre.Gondois@arm.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      d3c3db41
  7. 10 2月, 2022 1 次提交
    • P
      cpufreq: CPPC: Fix performance/frequency conversion · ec1c7ad4
      Pierre Gondois 提交于
      CPUfreq governors request CPU frequencies using information
      on current CPU usage. The CPPC driver converts them to
      performance requests. Frequency targets are computed as:
      	target_freq = (util / cpu_capacity) * max_freq
      target_freq is then clamped between [policy->min, policy->max].
      
      The CPPC driver converts performance values to frequencies
      (and vice-versa) using cppc_cpufreq_perf_to_khz() and
      cppc_cpufreq_khz_to_perf(). These functions both use two different
      factors depending on the range of the input value. For
      cppc_cpufreq_khz_to_perf():
      - (NOMINAL_PERF / NOMINAL_FREQ) or
      - (LOWEST_PERF / LOWEST_FREQ)
      and for cppc_cpufreq_perf_to_khz():
      - (NOMINAL_FREQ / NOMINAL_PERF) or
      - ((NOMINAL_PERF - LOWEST_FREQ) / (NOMINAL_PERF - LOWEST_PERF))
      
      This means:
      1- the functions are not inverse for some values:
         (perf_to_khz(khz_to_perf(x)) != x)
      2- cppc_cpufreq_perf_to_khz(LOWEST_PERF) can sometimes give
         a different value from LOWEST_FREQ due to integer approximation
      3- it is implied that performance and frequency are proportional
         (NOMINAL_FREQ / NOMINAL_PERF) == (LOWEST_PERF / LOWEST_FREQ)
      
      This patch changes the conversion functions to an affine function.
      This fixes the 3 points above.
      Suggested-by: NLukasz Luba <lukasz.luba@arm.com>
      Suggested-by: NMorten Rasmussen <morten.rasmussen@arm.com>
      Signed-off-by: NPierre Gondois <Pierre.Gondois@arm.com>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      ec1c7ad4
  8. 04 10月, 2021 1 次提交
  9. 01 7月, 2021 4 次提交
  10. 14 6月, 2021 1 次提交
  11. 22 3月, 2021 2 次提交
    • T
      cpufreq: cppc: simplify default delay_us setting · 2b53d1bd
      Tom Saeger 提交于
      Simplify case when setting default in cppc_cpufreq_get_transition_delay_us.
      Signed-off-by: NTom Saeger <tom.saeger@oracle.com>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      2b53d1bd
    • V
      cpufreq: CPPC: Add support for frequency invariance · 4c38f2df
      Viresh Kumar 提交于
      The Frequency Invariance Engine (FIE) is providing a frequency scaling
      correction factor that helps achieve more accurate load-tracking.
      
      Normally, this scaling factor can be obtained directly with the help of
      the cpufreq drivers as they know the exact frequency the hardware is
      running at. But that isn't the case for CPPC cpufreq driver.
      
      Another way of obtaining that is using the arch specific counter
      support, which is already present in kernel, but that hardware is
      optional for platforms.
      
      This patch updates the CPPC driver to register itself with the topology
      core to provide its own implementation (cppc_scale_freq_tick()) of
      topology_scale_freq_tick() which gets called by the scheduler on every
      tick. Note that the arch specific counters have higher priority than
      CPPC counters, if available, though the CPPC driver doesn't need to have
      any special handling for that.
      
      On an invocation of cppc_scale_freq_tick(), we schedule an irq work
      (since we reach here from hard-irq context), which then schedules a
      normal work item and cppc_scale_freq_workfn() updates the per_cpu
      arch_freq_scale variable based on the counter updates since the last
      tick.
      
      To allow platforms to disable this CPPC counter-based frequency
      invariance support, this is all done under CONFIG_ACPI_CPPC_CPUFREQ_FIE,
      which is enabled by default.
      
      This also exports sched_setattr_nocheck() as the CPPC driver can be
      built as a module.
      
      Cc: linux-acpi@vger.kernel.org
      Reviewed-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Tested-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Tested-by: NVincent Guittot <vincent.guittot@linaro.org>
      Acked-by: NRafael J. Wysocki <rafael@kernel.org>
      Signed-off-by: NViresh Kumar <viresh.kumar@linaro.org>
      4c38f2df
  12. 16 12月, 2020 4 次提交
    • I
      cppc_cpufreq: replace per-cpu data array with a list · a28b2bfc
      Ionela Voinescu 提交于
      The cppc_cpudata per-cpu storage was inefficient (1) additional to causing
      functional issues (2) when CPUs are hotplugged out, due to per-cpu data
      being improperly initialised.
      
      (1) The amount of information needed for CPPC performance control in its
          cpufreq driver depends on the domain (PSD) coordination type:
      
          ANY:    One set of CPPC control and capability data (e.g desired
                  performance, highest/lowest performance, etc) applies to all
                  CPUs in the domain.
      
          ALL:    Same as ANY. To be noted that this type is not currently
                  supported. When supported, information about which CPUs
                  belong to a domain is needed in order for frequency change
                  requests to be sent to each of them.
      
          HW:     It's necessary to store CPPC control and capability
                  information for all the CPUs. HW will then coordinate the
                  performance state based on their limitations and requests.
      
          NONE:   Same as HW. No HW coordination is expected.
      
          Despite this, the previous initialisation code would indiscriminately
          allocate memory for all CPUs (all_cpu_data) and unnecessarily
          duplicate performance capabilities and the domain sharing mask and type
          for each possible CPU.
      
      (2) With the current per-cpu structure, when having ANY coordination,
          the cppc_cpudata cpu information is not initialised (will remain 0)
          for all CPUs in a policy, other than policy->cpu. When policy->cpu is
          hotplugged out, the driver will incorrectly use the uninitialised (0)
          value of the other CPUs when making frequency changes. Additionally,
          the previous values stored in the perf_ctrls.desired_perf will be
          lost when policy->cpu changes.
      
      Therefore replace the array of per cpu data with a list. The memory for
      each structure is allocated at policy init, where a single structure
      can be allocated per policy, not per cpu. In order to accommodate the
      struct list_head node in the cppc_cpudata structure, the now unused cpu
      and cur_policy variables are removed.
      
      For example, on a arm64 Juno platform with 6 CPUs: (0, 1, 2, 3) in PSD1,
      (4, 5) in PSD2 - ANY coordination, the memory allocation comparison shows:
      
      Before patch:
      
       - ANY coordination:
         total    slack      req alloc/free  caller
             0        0        0     0/1     _kernel_size_le_hi32+0x0xffff800008ff7810
             0        0        0     0/6     _kernel_size_le_hi32+0x0xffff800008ff7808
           128       80       48     1/0     _kernel_size_le_hi32+0x0xffff800008ffc070
           768        0      768     6/0     _kernel_size_le_hi32+0x0xffff800008ffc0e4
      
      After patch:
      
       - ANY coordination:
          total    slack      req alloc/free  caller
           256        0      256     2/0     _kernel_size_le_hi32+0x0xffff800008fed410
             0        0        0     0/2     _kernel_size_le_hi32+0x0xffff800008fed274
      
      Additional notes:
       - A pointer to the policy's cppc_cpudata is stored in policy->driver_data
       - Driver registration is skipped if _CPC entries are not present.
      Signed-off-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Tested-by: NMian Yousaf Kaukab <ykaukab@suse.de>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      a28b2bfc
    • I
      cppc_cpufreq: expose information on frequency domains · cfdc589f
      Ionela Voinescu 提交于
      Use the existing sysfs attribute "freqdomain_cpus" to expose
      information to userspace about CPUs in the same frequency domain.
      Signed-off-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      Tested-by: NMian Yousaf Kaukab <ykaukab@suse.de>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      cfdc589f
    • I
      cppc_cpufreq: clarify support for coordination types · bf76bb20
      Ionela Voinescu 提交于
      The previous coordination type handling in the cppc_cpufreq init code
      created some confusion: the comment mentioned "Support only SW_ANY for
      now" while only the SW_ALL/ALL case resulted in a failure. The other
      coordination types (HW_ALL/HW, NONE) were silently supported.
      
      Clarify support for coordination types while describing in comments the
      intended behavior.
      Signed-off-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      Tested-by: NMian Yousaf Kaukab <ykaukab@suse.de>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      bf76bb20
    • I
      cppc_cpufreq: use policy->cpu as driver of frequency setting · d2641a5c
      Ionela Voinescu 提交于
      Considering only the currently supported coordination types (ANY, HW,
      NONE), this change only makes a difference for the ANY type, when
      policy->cpu is hotplugged out. In that case the new policy->cpu will
      be different from ((struct cppc_cpudata *)policy->driver_data)->cpu.
      
      While in this case the controls of *ANY* CPU could be used to drive
      frequency changes, it's more consistent to use policy->cpu as the
      leading CPU, as used in all other cppc_cpufreq functions. Additionally,
      the debug prints in cppc_set_perf() would no longer create confusion
      when referring to a CPU that is hotplugged out.
      Signed-off-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      Tested-by: NMian Yousaf Kaukab <ykaukab@suse.de>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      d2641a5c
  13. 17 11月, 2020 3 次提交
  14. 30 7月, 2020 2 次提交
  15. 05 6月, 2020 1 次提交
    • X
      cpufreq: CPPC: add SW BOOST support · 54e74df5
      Xiongfeng Wang 提交于
      To add SW BOOST support for CPPC, we need to get the max frequency of
      boost mode and non-boost mode. ACPI spec 6.2 section 8.4.7.1 describes
      the following two CPC registers.
      
      "Highest performance is the absolute maximum performance an individual
      processor may reach, assuming ideal conditions. This performance level
      may not be sustainable for long durations, and may only be achievable if
      other platform components are in a specific state; for example, it may
      require other processors be in an idle state.
      
      Nominal Performance is the maximum sustained performance level of the
      processor, assuming ideal operating conditions. In absence of an
      external constraint (power, thermal, etc.) this is the performance level
      the platform is expected to be able to maintain continuously. All
      processors are expected to be able to sustain their nominal performance
      state simultaneously."
      
      To add SW BOOST support for CPPC, we can use Highest Performance as the
      max performance in boost mode and Nominal Performance as the max
      performance in non-boost mode. If the Highest Performance is greater
      than the Nominal Performance, we assume SW BOOST is supported.
      
      The current CPPC driver does not support SW BOOST and use 'Highest
      Performance' as the max performance the CPU can achieve. 'Nominal
      Performance' is used to convert 'performance' to 'frequency'. That
      means, if firmware enable boost and provide a value for Highest
      Performance which is greater than Nominal Performance, boost feature is
      enabled by default.
      
      Because SW BOOST is disabled by default, so, after this patch, boost
      feature is disabled by default even if boost is enabled by firmware.
      Signed-off-by: NXiongfeng Wang <wangxiongfeng2@huawei.com>
      Suggested-by: NViresh Kumar <viresh.kumar@linaro.org>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      [ rjw: Subject ]
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      54e74df5
  16. 27 1月, 2020 1 次提交
    • R
      cpufreq: Avoid creating excessively large stack frames · 1e4f63ae
      Rafael J. Wysocki 提交于
      In the process of modifying a cpufreq policy, the cpufreq core makes
      a copy of it including all of the internals which is stored on the
      CPU stack.  Because struct cpufreq_policy is relatively large, this
      may cause the size of the stack frame to exceed the 2 KB limit and
      so the GCC complains when -Wframe-larger-than= is used.
      
      In fact, it is not necessary to copy the entire policy structure
      in order to modify it, however.
      
      First, because cpufreq_set_policy() obtains the min and max policy
      limits from frequency QoS now, it is not necessary to pass the limits
      to it from the callers.  The only things that need to be passed to it
      from there are the new governor pointer or (if there is a built-in
      governor in the driver) the "policy" value representing the governor
      choice.  They both can be passed as individual arguments, though, so
      make cpufreq_set_policy() take them this way and rework its callers
      accordingly.  This avoids making copies of cpufreq policies in the
      callers of cpufreq_set_policy().
      
      Second, cpufreq_set_policy() still needs to pass the new policy
      data to the ->verify() callback of the cpufreq driver whose task
      is to sanitize the min and max policy limits.  It still does not
      need to make a full copy of struct cpufreq_policy for this purpose,
      but it needs to pass a few items from it to the driver in case they
      are needed (different drivers have different needs in that respect
      and all of them have to be covered).  For this reason, introduce
      struct cpufreq_policy_data to hold copies of the members of
      struct cpufreq_policy used by the existing ->verify() driver
      callbacks and pass a pointer to a temporary structure of that
      type to ->verify() (instead of passing a pointer to full struct
      cpufreq_policy to it).
      
      While at it, notice that intel_pstate and longrun don't really need
      to verify the "policy" value in struct cpufreq_policy, so drop those
      check from them to avoid copying "policy" into struct
      cpufreq_policy_data (which allows it to be slightly smaller).
      
      Also while at it fix up white space in a couple of places and make
      cpufreq_set_policy() static (as it can be so).
      
      Fixes: 3000ce3c ("cpufreq: Use per-policy frequency QoS")
      Link: https://lore.kernel.org/linux-pm/CAMuHMdX6-jb1W8uC2_237m8ctCpsnGp=JCxqt8pCWVqNXHmkVg@mail.gmail.comReported-by: Nkbuild test robot <lkp@intel.com>
      Reported-by: NGeert Uytterhoeven <geert@linux-m68k.org>
      Cc: 5.4+ <stable@vger.kernel.org> # 5.4+
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      1e4f63ae
  17. 30 12月, 2019 2 次提交
  18. 05 6月, 2019 1 次提交
  19. 18 2月, 2019 1 次提交
  20. 03 10月, 2018 1 次提交
  21. 18 7月, 2018 1 次提交
  22. 13 6月, 2018 1 次提交
    • K
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook 提交于
      The kzalloc() function has a 2-factor argument form, kcalloc(). This
      patch replaces cases of:
      
              kzalloc(a * b, gfp)
      
      with:
              kcalloc(a * b, gfp)
      
      as well as handling cases of:
      
              kzalloc(a * b * c, gfp)
      
      with:
      
              kzalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kzalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kzalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kzalloc
      + kcalloc
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(sizeof(THING) * C2, ...)
      |
        kzalloc(sizeof(TYPE) * C2, ...)
      |
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(C1 * C2, ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      6396bb22
  23. 30 4月, 2018 1 次提交
    • P
      cpufreq / CPPC: Set platform specific transition_delay_us · d4f3388a
      Prashanth Prakash 提交于
      Add support to specify platform specific transition_delay_us instead
      of using the transition delay derived from PCC.
      
      With commit 3d41386d (cpufreq: CPPC: Use transition_delay_us
      depending transition_latency) we are setting transition_delay_us
      directly and not applying the LATENCY_MULTIPLIER. Because of that,
      on Qualcomm Centriq we can end up with a very high rate of frequency
      change requests when using the schedutil governor (default
      rate_limit_us=10 compared to an earlier value of 10000).
      
      The PCC subspace describes the rate at which the platform can accept
      commands on the CPPC's PCC channel. This includes read and write
      command on the PCC channel that can be used for reasons other than
      frequency transitions. Moreover the same PCC subspace can be used by
      multiple freq domains and deriving transition_delay_us from it as we
      do now can be sub-optimal.
      
      Moreover if a platform does not use PCC for desired_perf register then
      there is no way to compute the transition latency or the delay_us.
      
      CPPC does not have a standard defined mechanism to get the transition
      rate or the latency at the moment.
      
      Given the above limitations, it is simpler to have a platform specific
      transition_delay_us and rely on PCC derived value only if a platform
      specific value is not available.
      Signed-off-by: NPrashanth Prakash <pprakash@codeaurora.org>
      Cc: 4.14+ <stable@vger.kernel.org> # 4.14+
      Fixes: 3d41386d (cpufreq: CPPC: Use transition_delay_us depending transition_latency)
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      d4f3388a
  24. 24 4月, 2018 1 次提交
  25. 10 4月, 2018 2 次提交