Hi Thomas et al,
I was analyzing few traces with 'trace-cmd' and realized that timings
weren't matching properly. For example consider this trace:
1 cat-1867 [000] d.h1 149.750891: hrtimer_expire_entry:
hrtimer=ee7b3740 function=tick_sched_timer now=149740008694
2 cat-1867 [000] d.h1 149.750900: softirq_raise: vec=1
[action=TIMER]
3 cat-1867 [000] d.h1 149.750905: softirq_raise: vec=9
[action=RCU]
4 cat-1867 [000] d.h2 149.750910: sched_stat_runtime:
comm=cat pid=1867 runtime=1463250 [ns] vruntime=4777557704 [ns]
5 cat-1867 [000] d.h1 149.750914: softirq_raise: vec=7
[action=SCHED]
6 cat-1867 [000] d.h1 149.750919: hrtimer_expire_exit:
hrtimer=ee7b3740
7 cat-1867 [000] d.h2 149.750922: hrtimer_start:
hrtimer=ee7b3740 function=tick_sched_timer expires=149745000000
softexpires=149745000000
Line 1: now=149.740008694 and trace-time: 149.750891. diff 10ms (consistently)
Line 7: trace-time: 149.750922 and expires: 149.745000000, diff 5ms
So, either there is a mismatch of trace-times and required to be
fixed? (@Steven)
Or we are almost always adding the tick-sched hrtimer in past?
I wasn't sure and tried to go through tick-sched and hrtimer core
code again and this is what I realized.
At certain points we are trying to make sure that 'jiffies' are updated
for current-time with loops like:
Lowres mode:
while (tick_nohz_reprogram(ts, now)) {
now = ktime_get();
tick_do_update_jiffies64(now);
}
tick_nohz_reprogram() does check if expires is in past and returns
-ETIME (right?). And so we are guaranteed to updated jiffies to
current time and reprogram clkevt device in future.
Highres mode:
- First of all this kind of loop is missing from tick-handler:
tick_sched_timer() as we are relying on hrtimer core to restart hrtimer
for us and so we aren't trying to updated jiffies to latest values. And
so we might (maybe always as shown in my traces) enqueue hrtimer
in past.
- At some places we do have a while loop:
static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
{
...
while (1) {
/* Forward the time to expire in the future */
hrtimer_forward(&ts->sched_timer, now, tick_period);
if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
hrtimer_start_expires(&ts->sched_timer,
HRTIMER_MODE_ABS_PINNED);
/* Check, if the timer was already in the past */
if (hrtimer_active(&ts->sched_timer))
break;
} else {
...
}
...
}
}
But I couldn't make out that this while loop will actually run for
hres mode. Unlike tick_nohz_reprogram(), hrtimer_start_expires()
never fails and calls enqueue_hrtimer() which does this:
timer->state |= HRTIMER_STATE_ENQUEUED;
And so hrtimer_active() is guaranteed to return 'true' ? From the
comment over hrtimer_active() here it looks we are trying to make
sure that we aren't adding hrtimer in past, but code doesn't look
like that.
And so there is a possibility that hrtimers are getting added in past.
I tried to go to the initial commit: 79bf2bb (tick-management:
dyntick / highres functionality) and see if things were different there.
But they weren't.
Sorry for the long mail :)
--
viresh
Commit 64c862a83... added new alloc variants to the devres managed
API. These should be included in the list of managed API found in
devres.txt.
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
Cc: Randy Dunlap <rdunlap(a)infradead.org>
Cc: Grant Likely <grant.likely(a)linaro.org>
Cc: Rob Herring <robh+dt(a)kernel.org>
Cc: Joe Perches <joe(a)perches.com>
Cc: linux-doc(a)vger.kernel.org
---
Documentation/driver-model/devres.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 1525e30..91f5633 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -234,7 +234,10 @@ certainly invest a bit more effort into libata core layer).
-----------------------------
MEM
+ devm_kmalloc()
devm_kzalloc()
+ devm_kmalloc_array()
+ devm_kcalloc()
devm_kfree()
devm_kmemdup()
devm_get_free_pages()
--
1.9.3
When expiry is set to KTIME_MAX, we cancel the 'tick-sched' hrtimer in highres
mode and skip reprogramming clockevent device in lowres mode. But, the
clockevent device is already reprogrammed from tick-handler.
We will get interrupted atleast one more time.
In highres mode, as there is no hrtimer to service, hrtimer_interrupt() will
return without calling tick-handler.
But the problem is somewhat bigger in lowres mode. We unconditionally reschedule
tick everytime tick_nohz_handler() is called and so even if tick_stopped is set,
we never enter full dynticks mode.
To fix this, skip rescheduling next tick from tick-handler when we are running
tickless.
OTOH, when expires isn't equal to KTIME_MAX, we avoid reprogramming the clkdev
from the tick when it is stopped because it's going to be reprogrammed from
irq_exit() anyway. So we could avoid one useless device write.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
kernel/time/tick-sched.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 6558b7a..a4a45e0 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -956,6 +956,12 @@ static void tick_nohz_handler(struct clock_event_device *dev)
tick_sched_do_timer(now);
tick_sched_handle(ts, regs);
+ /*
+ * Skip reprogramming next event if we are running tickless.
+ */
+ if (ts->tick_stopped)
+ return;
+
while (tick_nohz_reprogram(ts, now)) {
now = ktime_get();
tick_do_update_jiffies64(now);
--
2.0.0.rc2
Changes in v4:
- Add device_remove hook, so hisi-smmu and smmu-v3 can reclaim other resources.
like dynamic allocted memory. And s1cbt and s2cbt memory are now allocated in
driver(Previously, I hope BIOS to do this).
- Fix bugs according to review comments. CB_FAR_LOW, CB_FAR_HIGH are (n) << 3.
- Change context_map in struct arm_smmu_device to dynamic memory allocation.
- Merge original patch 3 and 4 into one patch.
Changes in v3:
- Split arm-smmu.c into three files: arm-smmu.h arm-smmu-base.c arm-smmu.c.
To build stardard arm-smmu driver, use these three files.
To build hisilicon smmu driver, replace arm-smmu.c with hisi-smmu.c.
Now, hisi smmu driver is not dependent on arm smmu driver. They can seperate
exist, or coexist, when both building and running time.
- Give up Hisilicon private properties.
- Place hooks from global variable into struct arm_smmu_device.
And deleted three hooks: tlb_sync, flush_pgtable and dt_cfg_probe.
- Share the codes which are used to limit the size of smmu ias,oas,ubs.
- Add two little patchs about code style, variable types, etc.
Changes in v2:
- Split Hisilicon smmu implementation in a separate file, hisi-smmu.c
- Refactor arm-smmu.c. Some direct call hardware dependent functions replaced
with hooks. And move common struct and marco definition into arm-smmu.h
- Merge the description of Hisilicon private properties into arm,smmu.txt
I tried to merge hisi-smmu driver into arm-smmu.c, but it looks impossible.
The biggest problem is that too many registers are diffrent: the base address,
the field definition, or present only on one side. And if I use #if, hisi-smmu
and arm-smmu can not coexist in one binary file. Almost need 20 #if.
In addition, SMMUv3 is also not compatible with v2. And something is similar
with hisi-smmu: registers definition and fault handler is different with v2,
but can reuse fdt configuration and memory map. Hence, arm-smmu-base.c and
arm-smmu.h should be shared by all SMMUs(v2, v3 and hisi), and each smmu will
own a private file, like: arm-smmu.c(for v1 and v2), arm-smmu-v3.c, hisi-smmu.c
In this patch, arm-smmu.h is not suitable for v3. Because it contains macros
about v2 registers. SMMUv3 draft have not given detailed registers definition.
So I don't know how many macros can be reused. In fact, I think all marcos
which are not used in arm-smmu-base.c and arm-smmu.h, should place into each
private file, and abide duplication(After all, it is hardware dependent. It
will not bring any maintenance headaches, except when need rename the marcos).
Zhen Lei (5):
iommu/arm: change some structure member types in arm_smmu_device
iommu/arm: eliminate errors reported by checkpatch
iommu/arm: split arm-smmu.c into three files
iommu/hisilicon: Add support for Hisilicon Ltd. System MMU
architecture
documentation/iommu: Add description of Hisilicon SMMU private
binding
.../devicetree/bindings/iommu/arm,smmu.txt | 2 +
drivers/iommu/Kconfig | 14 +
drivers/iommu/Makefile | 2 +
drivers/iommu/arm-smmu-base.c | 1067 +++++++++++++++
drivers/iommu/arm-smmu.c | 1406 +-------------------
drivers/iommu/arm-smmu.h | 438 ++++++
drivers/iommu/hisi-smmu.c | 541 ++++++++
7 files changed, 2103 insertions(+), 1367 deletions(-)
create mode 100644 drivers/iommu/arm-smmu-base.c
create mode 100644 drivers/iommu/arm-smmu.h
create mode 100644 drivers/iommu/hisi-smmu.c
--
1.8.0
Stephen Boyd sent few patches today around a new cpufreq driver for Qualcomm's
Krait SoC: https://lkml.org/lkml/2014/6/24/918.
Krait couldn't use existing cpufreq-cpu0 driver as it doesn't have support for
SoC's with multiple clusters or SoC's which don't share clock line for all CPUs.
And I thought about trying updating cpu0 driver to see if we can get rid of this
limitation easily and use it for Krait as well.
It took me longer than I thought, around 4 hours to get this working on my dual
A15 exynos board.
First patch adds some space for driver specific data in 'struct cpufreq_policy'
and second one updates cpufreq-cpu0..
@Stephen: Can you please test this on Krait and see if it works?
Pushed here:
Rebased over rc2:
git://git.linaro.org/people/viresh.kumar/linux.git cpufreq/cpu0-krait
For guys looking to test on exynos, rebased over linux-next + some patches from
Thomas Abraham to use cpufreq-cpu0 for exynos:
git://git.linaro.org/people/viresh.kumar/linux.git cpufreq/cpu0-exynos
In case this is acceptable and bug free, next step would be to get cpufreq-cpu0
renamed a bit as its not about CPU0 anymore. Any suggestions on that would be
great :), cpufreq_generic.c ?
Thanks.
Viresh Kumar (2):
cpufreq: Add support for per-policy driver data
cpufreq: cpu0: Extend support beyond CPU0
.../devicetree/bindings/cpufreq/cpufreq-cpu0.txt | 8 +-
drivers/cpufreq/Kconfig | 5 +-
drivers/cpufreq/cpufreq-cpu0.c | 280 +++++++++++++--------
include/linux/cpufreq.h | 3 +
4 files changed, 193 insertions(+), 103 deletions(-)
--
2.0.0.rc2
Hi,
This patch adds support for PCI to AArch64. It is based on my v8 patch
that adds support for creating generic host bridge structure from
device tree. With that in place, I was able to boot a platform that
has PCIe host bridge support and use a PCIe network card.
Changes from v7:
- Rebased to v3.16-rc3
- Removed pci_ioremap_io() function as it is provided by my v8 generic
PCI host bridge patches under a different name.
Changes from v6:
- Guard the pci_domain_nr() inline implementation with #ifdef CONFIG_PCI as
to avoid conflict with default empty version present in include/linux/pci.h.
Thanks to Jingoo Han for catching this.
Changes from v5:
- Removed pcibios_fixup_bridge_ranges() as the week default version is fine.
- Removed the ALIGN() call in pcibios_align_resource()
- Stopped exporting pcibios_align_resource()
Changes from v4:
- Fixed the pci_domain_nr() implementation for arm64. Now we use
find_pci_host_bride() to find the host bridge before we retrieve
the domain number.
Changes from v3:
- Added Acks accumulated so far ;)
- Still carrying Catalin's patch for moving the PCI_IO_BASE until it
lands in linux-next or mainline, in order to ease applying the series
Changes from v2:
- Implement an arch specific version of pci_register_io_range() and
pci_address_to_pio().
- Return 1 from pci_proc_domain().
Changes from v1:
- Added Catalin's patch for moving the PCI_IO_BASE location and extend
its size to 16MB
- Integrated Arnd's version of pci_ioremap_io that uses a bitmap for
keeping track of assigned IO space and returns an io_offset. At the
moment the code is added in arch/arm64 but it can be moved in drivers/pci.
- Added a fix for the generic ioport_map() function when !CONFIG_GENERIC_IOMAP
as suggested by Arnd.
v7 thread here: https://lkml.org/lkml/2014/3/14/320
v6 thread here: https://lkml.org/lkml/2014/3/5/41
v5 thread here: https://lkml.org/lkml/2014/3/4/307
v4 thread here: https://lkml.org/lkml/2014/3/3/298
v3 thread here: https://lkml.org/lkml/2014/2/28/211
v2 thread here: https://lkml.org/lkml/2014/2/27/255
v1 thread here: https://lkml.org/lkml/2014/2/3/389
The API used is different from the one used by ARM architecture. There is
no pci_common_init_dev() function and no hw_pci structure, as that is no
longer needed. Here is an example of what the probe function of a generic
host bridge could look like:
static int myhostbridge_probe(struct platform_device *pdev)
{
int err;
struct device_node *dev;
struct pci_host_bridge *bridge;
struct myhostbridge_port *pp;
resource_size_t lastbus;
dev = pdev->dev.of_node;
if (!of_device_is_available(dev)) {
pr_warn("%s: disabled\n", dev->full_name);
return -ENODEV;
}
pp = kzalloc(sizeof(struct myhostbridge_port), GFP_KERNEL);
if (!pp)
return -ENOMEM;
bridge = of_create_pci_host_bridge(&pdev->dev, &myhostbridge_ops, pp);
if (IS_ERR(bridge)) {
err = PTR_ERR(bridge);
goto bridge_create_fail;
}
err = myhostbridge_setup(bridge->bus);
if (err)
goto bridge_setup_fail;
/* We always enable PCI domains and we keep domain 0 backward
* compatible in /proc for video cards
*/
pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
lastbus = pci_scan_child_bus(bridge->bus);
pci_bus_update_busn_res_end(bridge->bus, lastbus);
pci_assign_unassigned_bus_resources(bridge->bus);
pci_bus_add_devices(bridge->bus);
return 0;
bridge_setup_fail:
put_device(&bridge->dev);
device_unregister(&bridge->dev);
bridge_create_fail:
kfree(pp);
return err;
}
Liviu Dudau (1):
arm64: Add architectural support for PCI
arch/arm64/Kconfig | 19 ++++++++++++++++-
arch/arm64/include/asm/Kbuild | 1 +
arch/arm64/include/asm/io.h | 3 ++-
arch/arm64/include/asm/pci.h | 49 +++++++++++++++++++++++++++++++++++++++++++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/pci.c | 38 +++++++++++++++++++++++++++++++++
6 files changed, 109 insertions(+), 2 deletions(-)
create mode 100644 arch/arm64/include/asm/pci.h
create mode 100644 arch/arm64/kernel/pci.c
--
2.0.0