- Robustify the user backtrace code, as done on other architectures.
- Provide the symbols resolution when triggering from tracepoints.
Big thanks to Steve Capper for the help in debugging and rephrasing the
commits descriptions.
Stress tested with perf record and tracepoints triggering (-e <tracepoint>),
with unwinding using fp (--call-graph fp) and dwarf info (--call-graph dwarf).
Jean Pihet (3):
ARM: perf: Check that current->mm is alive before getting user
callchain
ARM: perf: disable the pagefault handler when reading from user space
ARM: perf: allow tracing with kernel tracepoints events
arch/arm/include/asm/perf_event.h | 19 +++++++++++++++++++
arch/arm/kernel/perf_event.c | 13 +++++++++++--
2 files changed, 30 insertions(+), 2 deletions(-)
--
1.8.1.2
hrtimer_start*() family never fails to enqueue a hrtimer to a clock-base. In
case the hrtimer was in past and getting added on this_cpu's clock-base, we
raise a softirq and exit.
At several places in the kernel, we try to make sure if hrtimer was added
properly or not by calling hrtimer_active(), like:
hrtimer_start(timer, expires, mode);
if (hrtimer_active(timer)) {
/* Added successfully */
} else {
/* Was added in the past */
}
As hrtimer_start*() never fails, hrtimer_active() is guaranteed to return
'true'. So, there is no point calling hrtimer_active().
Also this is done in while loop at several places, which isn't required if
hrtimer_start*() never fails. Drop those loops as well.
This patch only updates tick-sched.c file currently, others will be fixed if
above explanation holds true.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
This was also raised here and didn't attract many:
https://www.lkml.org/lkml/2014/7/3/559
Pushed here:
git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/linux.git
tick/remove-stale-hrtimer_active
kernel/time/tick-sched.c | 45 ++++++++++++++++++---------------------------
1 file changed, 18 insertions(+), 27 deletions(-)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 6558b7a..66ca5ab 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -658,9 +658,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
hrtimer_start(&ts->sched_timer, expires,
HRTIMER_MODE_ABS_PINNED);
- /* Check, if the timer was already in the past */
- if (hrtimer_active(&ts->sched_timer))
- goto out;
+ goto out;
} else if (!tick_program_event(expires, 0))
goto out;
/*
@@ -844,24 +842,25 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
hrtimer_cancel(&ts->sched_timer);
hrtimer_set_expires(&ts->sched_timer, ts->last_tick);
- while (1) {
- /* Forward the time to expire in the future */
- hrtimer_forward(&ts->sched_timer, now, tick_period);
+ /* 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 {
- if (!tick_program_event(
- hrtimer_get_expires(&ts->sched_timer), 0))
- break;
- }
+ if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
+ hrtimer_start_expires(&ts->sched_timer,
+ HRTIMER_MODE_ABS_PINNED);
+ return;
+ }
+
+ while (1) {
+ if (!tick_program_event(hrtimer_get_expires(&ts->sched_timer),
+ 0))
+ break;
/* Reread time and update jiffies */
now = ktime_get();
tick_do_update_jiffies64(now);
+
+ /* Forward the time to expire in the future */
+ hrtimer_forward(&ts->sched_timer, now, tick_period);
}
}
@@ -1104,7 +1103,6 @@ early_param("skew_tick", skew_tick);
void tick_setup_sched_timer(void)
{
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
- ktime_t now = ktime_get();
/*
* Emulate tick processing via per-CPU hrtimers:
@@ -1123,15 +1121,8 @@ void tick_setup_sched_timer(void)
hrtimer_add_expires_ns(&ts->sched_timer, offset);
}
- for (;;) {
- hrtimer_forward(&ts->sched_timer, now, tick_period);
- 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;
- now = ktime_get();
- }
+ hrtimer_forward(&ts->sched_timer, ktime_get(), tick_period);
+ hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED);
#ifdef CONFIG_NO_HZ_COMMON
if (tick_nohz_enabled) {
--
2.0.0.rc2
Changes in v5:
- Put all registers(exclude translation table associated) definition into each
smmu private file.
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 allocate memory.
- 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
All marcos which are not used in arm-smmu-base.c and not shared by all SMMUs,
have been placed into each private file, some are duplicated. But I think it
will not bring any maintenance headaches, except when need rename the marcos.
After all, it is hardware dependent.
Zhen Lei (5):
iommu/arm: change some structure member types in arm_smmu_device
iommu/arm: eliminate errors reported by checkpatch
iommu/arm: apart arm-smmu.c to share code with other SMMUs
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 | 1085 +++++++++++++++++
drivers/iommu/arm-smmu.c | 1247 +-------------------
drivers/iommu/arm-smmu.h | 258 ++++
drivers/iommu/hisi-smmu.c | 575 +++++++++
7 files changed, 1985 insertions(+), 1198 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
From: Mark Brown <broonie(a)linaro.org>
Even though we mostly use GPIO descriptors internally we still use
gpio_request_one() to request so we need to pair that with gpio_free() to
release the GPIO.
Reported-by: Linus Walleij <linus.walleij(a)linaro.org>
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
drivers/regulator/core.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c563d93125cd..80381409f856 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1710,7 +1710,12 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
if (pin->gpiod == rdev->ena_pin->gpiod) {
if (pin->request_count <= 1) {
pin->request_count = 0;
- gpiod_put(pin->gpiod);
+ /*
+ * Since we requested with gpio_request_one()
+ * we still need to free with gpio_free()
+ * for now.
+ */
+ gpio_free(desc_to_gpio(pin->gpiod));
list_del(&pin->list);
kfree(pin);
} else {
--
2.0.0