Age | Commit message (Collapse) | Author |
|
Let's keep only those logical CPUs with same initial CPU cluster to create
a uniform scheduler profile without having to modify any of the probed
topology and compute capacity data. This has the potential to create
a non contiguous CPU numbering space when the switcher is active with
potential impact on buggy user space tools. It is however better to fix
those tools rather than making the switcher more intrusive.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
Up to now, the logical CPU was somehow tied to the physical CPU number
within a cluster which caused problems when forcing the boot on an A7.
The pairing is completely independent from physical CPU numbers now.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
This patch adds config fragments used to enable most of the features used by
big LITTLE IKS.
Signed-off-by: Naresh Kamboju <naresh.kamboju@linaro.org>
|
|
|
|
When operating in IKS mode 'freq_table[MAX_CLUSTERS]' is allocated
memory to store the virtual frequency table. When unregistering the
bL cpufreq driver that memory needs to be freed.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
|
|
When not operating in IKS mode 'clk' and 'freq_table' should be cleaned
for all present clusters, something the 'return' statement was
preventing.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
|
|
When declaring char name[9] = "cluster";
name[7] is equal to the string termination character '\0'.
But later on doing:
name[7] = cluster_id + '0';
clobbers the termination character, leaving non terminated
strings in the system and potentially causing undertermined
behavior.
By initialising name[9] to "clusterX" the 8th character is
set to '\0' and affecting the 7th character with the cluster
number doesn't overwite anything.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
[ np: The C standard says that the reminder of an initialized array of
a known size should be initialized to zero and therefore this patch is
unneeded, however this patch makes the intent more explicit to others
reading the code. ]
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
|
|
Currently following is the frequency range we have for IKS:
A7 (actual freq): 350 MHz -> 1 GHz
A15 (actual freq): 500 MHz-> 1.2 GHz
A15 (virtual freq): 1 GHz -> 2.4 GHz
Problem: From user space it looks like the cpu can support upto 2.4 GHz
physically, which is incorrect. Over that benchmarking tests done by many people
consider the highest freq available in their results, which would make our
results poor.
Instead of using virtual A15 freqs, lets use virtual A7 freqs. That can be
easily done by making virtual A7 freqs half of their actual value. And so our
new range would be: 175 MHz to 1.2 GHz.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reported-by: Praveen Prakash <praveen.prakash@arm.com>
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
It is possible that different cpus may race against setting frequency of the
same cluster. We need per-cluster locks to prevent that.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
|
find_cluster_maxfreq() looks overly complex, lets simplify it.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
|
There is no actual need of keeping two variables here. Lets keep only one of
them.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
|
Consider following scenario:
- current freq of CPU 0 & 1: 1 GHz, both on cluster A7
- request: CPU0 to 700 MHz (we don't change freq as max is 1 GHz)
- request: CPU1 to 2 GHz, we migrate CPU1 to cluster A15.
At this point we could have reduced frequency of cluster A7 to 700 MHz, as it is
the max now. This patch does it. :)
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
|
on/off
When a cpu goes down, exit would be called for it. Similarly for every cpu up
init would be called. This would result in same freq table and clk structure to
get freed/allocated again. There is no way for freq table/clk structures to
change between these calls.
Also, when we disable switcher, firstly cpufreq unregister would be called and
hence exit for all cpus and then register would be called, i.e. init would be
called.
For saving time/energy for both cases, lets not free table/clk until module exit
is not done.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
|
notifiers
Cpufreq driver must be unregistered/registered on switcher on/off to get correct
freq tables for all cpus. This patch does it.
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
|
|
This patch adds IKS (In Kernel Switcher) support to cpufreq driver. This
creates separate freq table for A7-A15 cpu pair. A15 frequency is vitalized and
is doubled, so that it touches boundaries with A7 frequencies.
Based on Earlier Work from Sudeep.
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
|
cpufreq_stat has registered notifiers with both cpufreq and cpu core. It adds
cpu/cpu0/cpufreq/stats/ directory with a notifier of cpufreq CPUFREQ_NOTIFY and
removes this directory with a notifier to cpu core.
On bL_switcher enable/disable, cpufreq drivers notifiers gets called and they
call cpufreq_unregister(), followed by cpufreq_register(). For unregister stats
directories per cpu aren't removed, because cpu never went to dead state and cpu
notifier isn't called.
When cpufreq_register() is called, we try to add these directories again and
that simply fails, as directories were already present.
Fix these issues by registering cpufreq_stats too with bL_switcher notifiers, so
that they get unregistered and registered on switcher enable/disable.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
|
1) The memory obtained via alloc_percpu() is defined (and zeroed) only
for those CPUs in cpu_possible_mask. For example, it is wrong to
itterate using:
for (i = 0; i < NR_CPUS; i++)
per_cpu_ptr(cpu_pmus, i)->mpidr = -1;
This is guaranteed to corrupt memory for those CPU numbers not marked
possible during CPU enumeration.
2) In cpu_pmu_free_irq(), an occasional cpu_pmu->mpidr of -1 (meaning
uninitialized) was nevertheless passed to find_logical_cpu() which
ended up returning very creative CPU numbers. This was then used
with this line:
if (!cpumask_test_and_clear_cpu(cpu, &pmu->active_irqs))
This corrupted memory due to the pmu->active_irqs overflow, and
provided rather random condition results.
What made this bug even nastier is the fact that a slight change in code
placement due to compiler version, kernel config options or even added
debugging traces could totally change the bug symptom.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
This patch checks whether any counters are active in the PMU's per-
CPU event_mask before attempting save/restore. In practice, this
means that the save/restore is skipped if there is no active perf
session.
If there are no active counters, nothing is saved or restored. The
PMU is still reset and quiesced on the restore path, as previously.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
This patch determines the (mpidr,irq) pairings associated with each
PMU from the DT at probe time, and uses this information to work
out which IRQs to request for which logical CPU when enabling an
event on a PMU.
This patch also ensures that each PMU's init function is called on
a CPU of the correct type.
Previously, this was relying on luck.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
This patch adds preliminary, highly experimental perf support for
CONFIG_BL_SWITCHER=y.
In this configuration, every PMU is registered as valid for every
logical CPU, in a way which covers all the combinations which will
be seen at runtime, regardless of whether the switcher is enabled
or not.
Tracking of which PMUs are active at a given point in time is
delegated to the lower-level abstractions in perf_event_v7.c.
Warning: this patch does not handle PMU interrupt affinities
correctly.
Because of the way the switcher pairs up CPUs, this
does not cause a problem when the switcher is active; however,
interrupts may be directed to the wrong CPU when the switcher is
disabled.
This will result in spurious interrupts and wrong event
counts.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
Where the ARM Architecture exposes PM*SET and PM*CLR, these really
manipulate the same underlying register.
This patch uses the PM*SET register for storing the logical state
when the PMU is not active, and mainpulates that state when the
code attempts to access the corresponding PM*CLR register.
PMOVSR is a special case: this is a reset-only register, so the
logical copy of PMOVSR is always used.
These changes result a small number of unused fields in the
armv7_pmu_logical_state structre. For now, this is considered to
be harmless -- it may be tidied up later.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
This hack is required in order to be able to manipulate the CPU
logical state safely in the absence of the b.L switcher, for test
purposes.
The other similar checks are already present in the b.L MP perf
support patches.
Normally, only the physical PMU state should be mainpulated in a
kernel which doesn't include the switcher, so it may be possible to
remove this patch later.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
We need a allocate some per-cpu-pmu data outside atomic context,
along with other actions required for setting up the cpu_pmu
struct.
This code does not need to run on any particular CPU, so
we call this after the per-CPU init method is called.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
This patch aims to provide basic register file functionality for
ARMv7 CPU PMUs while the PMU is offline.
It is incomplete and
lacks the necessary plumbing to actually make use of this, but the
extra code needed is not expected to be large or complex.
Save/restore are ported over the register emulation framework,
since the offline logical state of the CPU matches exactly what
needs to be captures in save/restore.
Because this patch is rather invasive, it should be
dropped in the future in favour of higher-level abstraction before merging upstream.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
In a system where Linux logical CPUs can migrate between different
physical CPUs, multiple CPU PMUs can logically count events for
each logical CPU, as logical CPUs migrate from one cluster to
another.
This patch allows multiple PMUs to be registered against each CPU.
The pairing of a PMU and a CPU is reperesented by a struct
arm_cpu_pmu, with existing per-CPU state used by perf moving into
this structure.
arm_cpu_pmus are per-cpu-allocated, and hang off
the relevant arm_pmu structure.
This arrangement allows us to find all the CPU-PMU pairings for a
given PMU, but not for a given CPU.
Do do the latter, a list of
all registered CPU PMUs is maintained, and we iterate over that
when we need to find all of a CPU's CPU PMUs.
This is not elegent,
but it shouldn't be a heavy cost since the number of different CPU
PMUs across the system is currently expected to be low (i.e., 2 or
fewer).
This could be improved later.
As a side-effect, the get_hw_events() method no longer has enough
context to provide an answer, because there may be multiple
candidate PMUs for a CPU.
This patch adds the struct arm_pmu * for
the relevant PMU to this interface to resolve this problem,
resulting in trivial changes to various ARM PMU implementations.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
This adds core support for saving and restoring CPU PMU registers
for suspend/resume support i.e. deeper C-states in cpuidle terms.
This patch adds support only to ARMv7 PMU registers save/restore.
It needs to be extended to xscale and ARMv6 if needed.
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
|
|
This patch sets the cpu affinity for the perf IRQs in the logical order
within the cluster. However interupts are assumed to be specified in the
same logical order within the cluster.
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
|
|
In a system with multiple heterogeneous CPU PMUs and each PMUs can handle
events on a subset of CPUs, probably belonging a the same cluster.
This patch introduces a cpumask to track which CPUs each PMU supports.
It also updates armpmu_event_init to reject cpu-specific events being
initialised for unsupported CPUs. Since process-specific events can be
initialised for all the CPU PMUs,armpmu_start/stop/add are modified to
prevent from being added on unsupported CPUs.
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
|
|
In order to support multiple, heterogeneous CPU PMUs and distinguish
them, they cannot be registered as PERF_TYPE_RAW type. Instead we can
get perf core to allocate a new idr type id for each PMU.
Userspace applications can refer sysfs entried to find a PMU's type,
which can then be used in tracking events on individual PMUs.
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
|
|
A single global CPU PMU pointer is not useful in a system with multiple,
heterogeneous CPU PMUs as we need to access the relevant PMU depending
on the current CPU.
This patch replaces the single global CPU PMU pointer with per-cpu
pointers and changes the OProfile accessors to refer to the PMU affine
to CPU0.
Signed-off-by: Sudeep KarkadaNagesha <Sudeep.KarkadaNagesha@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
|
|
When the switcher is active, there is no straightforward way to
figure out which logical CPU a given physical CPU maps to.
This patch provides a function
bL_switcher_get_logical_index(mpidr), which is analogous to
get_logical_index().
This function returns the logical CPU on which the specified
physical CPU is grouped (or -EINVAL if unknown).
If the switcher
is inactive or not present, -EUNATCH is returned instead.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
Add in-modules tests on arm-bl-cpufreq cpufreq driver.
To build the tests, add the following config option:
ARM_BL_CPUFREQ_TEST=y
The tests will run when the driver is loaded, but they are not run
by default. To run the tests, you need to pass the option
test_config=1 to the arm-bl-cpufreq driver when loading it.
Signed-off-by: Mathieu Briand <mathieu.briand@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
|
|
This patch registers the frequency table for each CPU so that the
table and transition statistics are visible through sysfs, and to
governor code.
Since the frequency table is static and never deallocated while the
driver is loaded, there is no call to cpufreq_frequency_table_put_
attr(). A .exit method which calls this function would be needed
if the frequency table ever becomes dynamic.
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
Some governors refuse to work unless a cpufreq driver advertises a
finite transition latency value.
We can't set this to something sensible until we have real hardware
to calibrate on. In the meantime, we can define this to an
arbitrary value to permit experimentation with governors such as
conservative and ondemand.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
This patch adds a very simple cpufreq-based frontend to the ARM
big.LITTLE switcher.
This driver simply simulates two performance points corresponding
to the big and little clusters.
There is currently no interface for reporting what the dummy
frequencies exposed by the driver actually mean in terms of real
cluster / performance point combinations. For the very simple case
supported, cpuinfo_max_freq corresponds to big and cpuinfo_min_freq
corresponds to LITTLE.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
Conflicts:
arch/arm/Kconfig
arch/arm/common/Makefile
|
|
Using late_initcall is too late for IKS.
Requested-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Jon Medhurst <tixy@linaro.org>
|
|
Only the basic to aid debugging.
Usage:
echo <cpuid>,<clusterid> > /dev/b.L_switcher
where <cpuid> is between 0 and 3, and <clusterid> is 0 for the
A15 cluster and 1 for the A7 cluster.
Signed-off-by: nicolas Pitre <nico@linaro.org>
|
|
This patch exports a bL_switcher_trace_trigger() function to
provide a means for drivers using the trace events to get the
current status when starting a trace session.
Calling this function is equivalent to pinging the trace_trigger
file in sysfs.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
When tracing switching, an external tracer needs a way to bootstrap
its knowledge of the logical<->physical CPU mapping.
This patch adds a sysfs attribute trace_trigger. A write to this
attribute will generate a power:cpu_migrate_current event for each
online CPU, indicating the current physical CPU for each logical
CPU.
Activating or deactivating the switcher also generates these
events, so that the tracer knows about the resulting remapping of
affected CPUs.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
|
|
This patch adds simple trace events to the b.L switcher code
to allow tracing of CPU migration events.
To make use of the trace events, you will need:
CONFIG_FTRACE=y
CONFIG_ENABLE_DEFAULT_TRACERS=y
The following events are added:
* power:cpu_migrate_begin
* power:cpu_migrate_finish
each with the following data:
u64 timestamp;
u32 cpu_hwid;
power:cpu_migrate_begin occurs immediately before the
switcher-specific migration operations start.
power:cpu_migrate_finish occurs immediately when migration is
completed.
The cpu_hwid field contains the ID fields of the MPIDR.
* For power:cpu_migrate_begin, cpu_hwid is the ID of the outbound
physical CPU (equivalent to (from_phys_cpu,from_phys_cluster)).
* For power:cpu_migrate_finish, cpu_hwid is the ID of the inbound
physical CPU (equivalent to (to_phys_cpu,to_phys_cluster)).
By design, the cpu_hwid field is masked in the same way as the
device tree cpu node reg property, allowing direct correlation to
the DT description of the hardware.
The timestamp is added in order to minimise timing noise. An
accurate system-wide clock should be used for generating this
(hopefully getnstimeofday is appropriate, but it could be changed).
It could be any monotonic shared clock, since the aim is to allow
accurate deltas to be computed. We don't necessarily care about
accurate synchronisation with wall clock time.
In practice, each switch takes place on a single logical CPU,
and the trace infrastructure should guarantee that events are
well-ordered with respect to a single logical CPU.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
Some subsystems will need to respond synchronously to runtime
enabling and disabling of the switcher.
This patch adds a dedicated notifier interface to support such
subsystems. Pre- and post- enable/disable notifications are sent
to registered callbacks, allowing safe transition of non-b.L-
transparent subsystems across these control transitions.
Notifier callbacks may veto switcher (de)activation on pre notifications
only. Post notifications won't revert the action.
If enabling or disabling of the switcher fails after the pre-change
notification has been sent, subsystems which have registered
notifiers can be left in an inappropriate state.
This patch sends a suitable post-change notification on failure,
indicating that the old state has been reestablished.
For example, a failed initialisation will result in the following
sequence:
BL_NOTIFY_PRE_ENABLE
/* switcher initialisation fails */
BL_NOTIFY_POST_DISABLE
It is the responsibility of notified subsystems to respond in an
appropriate way.
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
Some subsystems will need to know for sure whether the switcher is
enabled or disabled during certain critical regions.
This patch provides a simple mutex-based mechanism to discover
whether the switcher is enabled and temporarily lock out further
enable/disable:
* bL_switcher_get_enabled() returns true iff the switcher is
enabled and temporarily inhibits enable/disable.
* bL_switcher_put_enabled() permits enable/disable of the switcher
again after a previous call to bL_switcher_get_enabled().
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
In some cases, a significant delay may be observed between the moment
a request for a CPU to come up is made and the moment it is ready to
start executing kernel code. This is especially true when a whole
cluster has to be powered up which may take in the order of miliseconds.
It is therefore a good idea to let the outbound CPU continue to execute
code in the mean time, and be notified when the inbound is ready before
performing the actual switch.
This is achieved by registering a completion block with the appropriate
IPI callback, and programming the sending of an IPI by the early assembly
code prior to entering the main kernel code. Once the IPI is delivered
to the outbound CPU, the completion block is "completed" and the switcher
thread is resumed.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
This allows to poke a predetermined value into a specific address
upon entering the early boot code in bL_head.S.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
We need a mechanism to let an inbound CPU signal that it is alive before
even getting into the kernel environment i.e. from early assembly code.
Using an IPI is the simplest way to achieve that.
This adds some basic infrastructure to register a struct completion
pointer to be "completed" when the dedicated IPI for this task is
received.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
The regular gic_raise_softirq() takes as input a CPU mask which is not
adequate when we need to send an IPI to a CPU which is not represented
in the kernel to GIC mapping. That is the case with the b.L switcher
when GIC migration to the inbound CPU has not yet occurred.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
In order to have early assembly code signal other CPUs in the system,
we need to get the physical address for the SGIR register used to
send IPIs. Because the register will be used with a precomputed CPU
interface ID number, there is no need for any locking in the assembly
code where this register is written to.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
Let's wait for the inbound to come up and snoop some of our cache.
That should be a bit more efficient than going down right away.
Monitoring the CCI event counters could be a better approach eventually.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|
|
Trying to support both the switcher and CPU hotplug at the same time
is quickly becoming very complex for little gain. So let's simply veto
any hotplug requests when the switcher is active.
This restriction might be loosened a bit eventually.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
|