* Re: [PATCH 3/4] perf/POWER7: Make event translations available in sysfs
From: Sukadev Bhattiprolu @ 2012-11-14 18:20 UTC (permalink / raw)
To: Jiri Olsa
Cc: Peter Zijlstra, robert.richter, Anton Blanchard, linux-kernel,
linuxppc-dev, Ingo Molnar, Paul Mackerras,
Arnaldo Carvalho de Melo
In-Reply-To: <20121114102534.GA2220@krava.brq.redhat.com>
Jiri Olsa [jolsa@redhat.com] wrote:
| On Wed, Nov 07, 2012 at 11:19:28AM -0800, Sukadev Bhattiprolu wrote:
|
| SNIP
|
| > +struct perf_pmu_events_attr {
| > + struct device_attribute attr;
| > + u64 id;
| > +};
| > +
| > +extern ssize_t power_events_sysfs_show(struct device *dev,
| > + struct device_attribute *attr, char *page);
| > +
| > +#define EVENT_VAR(_id) event_attr_##_id
| > +#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
| > +
| > +#define EVENT_ATTR(_name, _id) \
| > + static struct perf_pmu_events_attr EVENT_VAR(_id) = { \
| > + .attr = __ATTR(_name, 0444, power_events_sysfs_show, NULL),\
| > + .id = PM_##_id, \
| > + };
|
| this is duplicating the x86 code, perhaps it could be moved
| to include/linux/perf_event.h and shared globaly
Ok.
Can we remove the assumption that the event id is a generic event that
has PERF_COUNT_HW_ prefix and also let the architectures pass in a "show"
function ? This would allow architectures to display any arch specific
events that don't yet have a generic counterpart.
IOW, can we do something like this (untested) and make PERF_EVENT_ATTR global:
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 4428fd1..25298f7 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1354,12 +1354,15 @@ static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *at
#define EVENT_VAR(_id) event_attr_##_id
#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
-#define EVENT_ATTR(_name, _id) \
+#define PERF_EVENT_ATTR(_name, _id, _show) \
static struct perf_pmu_events_attr EVENT_VAR(_id) = { \
- .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \
- .id = PERF_COUNT_HW_##_id, \
+ .attr = __ATTR(_name, 0444, _show, NULL), \
+ .id = _id, \
};
+#define EVENT_ATTR(_name, _id) \
+ PERF_EVENT_ATTR(_name, PERF_COUNT_HW_##_id, events_sysfs_show)
+
EVENT_ATTR(cpu-cycles, CPU_CYCLES );
EVENT_ATTR(instructions, INSTRUCTIONS );
EVENT_ATTR(cache-references, CACHE_REFERENCES );
|
|
| > diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
| > index aa2465e..19b23bd 100644
| > --- a/arch/powerpc/perf/core-book3s.c
| > +++ b/arch/powerpc/perf/core-book3s.c
| > @@ -1305,6 +1305,16 @@ static int power_pmu_event_idx(struct perf_event *event)
| > return event->hw.idx;
| > }
| >
| > +ssize_t power_events_sysfs_show(struct device *dev,
| > + struct device_attribute *attr, char *page)
| > +{
| > + struct perf_pmu_events_attr *pmu_attr;
| > +
| > + pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
| > +
| > + return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
|
| whitespace issues
Will fix. Thanks for the review.
Sukadev
^ permalink raw reply related
* Re: [PATCH] cpuidle: Measure idle state durations with monotonic clock
From: Julius Werner @ 2012-11-14 17:15 UTC (permalink / raw)
To: Daniel Lezcano
Cc: Kevin Hilman, Deepthi Dharwar, Trinabh Gupta, Lists Linaro-dev,
linux-pm, linux-kernel, Rafael J. Wysocki, linux-acpi,
Srivatsa S. Bhat, Andrew Morton, linuxppc-dev, Sameer Nanda,
Len Brown
In-Reply-To: <50A37ADD.8040000@linaro.org>
> Maybe you can remove all these computations and set the flag
> en_core_tk_irqen for the driver ? That will be handled by the cpuidle
> framework, no ?
>
> Same comment for the intel_idle driver.
Yeah, I thought about that, too. I was a little too afraid of touching
the sched_clock_idle_wakeup_event() parameter that is tied to the
measurement, but it seems to have been vestigial for some time now and
other drivers also just set it 0. I will whip up another version of
the patch (won't change the PPC further though, if this version works
I would just leave it at that... thanks for testing, Deepthi).
^ permalink raw reply
* [PATCH 1/1] powerpc: dts: virtex440: add ethernet phy to virtex440-ml507
From: Gernot Vormayr @ 2012-11-14 16:59 UTC (permalink / raw)
To: Grant Likely, Benjamin Herrenschmidt, Paul Mackerras
Cc: linuxppc-dev, linux-kernel, Gernot Vormayr
This adds the marvel phy which is present on the ml507 board.
Without this ethtool causes kernel-oopses.
Tested on ml507 board.
Signed-off-by: Gernot Vormayr <gvormayr@gmail.com>
---
arch/powerpc/boot/dts/virtex440-ml507.dts | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/boot/dts/virtex440-ml507.dts b/arch/powerpc/boot/dts/virtex440-ml507.dts
index 52d8c1a..fc7073b 100644
--- a/arch/powerpc/boot/dts/virtex440-ml507.dts
+++ b/arch/powerpc/boot/dts/virtex440-ml507.dts
@@ -272,6 +272,12 @@
xlnx,temac-type = <0>;
xlnx,txcsum = <1>;
xlnx,txfifo = <0x1000>;
+ phy-handle = <&phy7>;
+ clock-frequency = <100000000>;
+ phy7: phy@7 {
+ compatible = "marvell,88e1111";
+ reg = <7>;
+ } ;
} ;
} ;
IIC_EEPROM: i2c@81600000 {
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] TTY: hvc_console, fix port reference count going to zero prematurely
From: Greg KH @ 2012-11-14 15:09 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev, Paul Mackerras, Jiri Slaby, anton, alan
In-Reply-To: <1352897279.23412.22.camel@pasglop>
On Wed, Nov 14, 2012 at 11:47:59PM +1100, Benjamin Herrenschmidt wrote:
> On Wed, 2012-11-14 at 10:45 +0100, Jiri Slaby wrote:
>
> > > This fixes it by removing the extra kref_put() and tty_kref_put() calls.
> >
> > Oh yeah. Thanks.
> >
> > Acked-by: Jiri Slaby <jslaby@suse.cz>
>
> So who's merging it ?
Give me a chance to at least wake up please :)
I will.
greg k-h
^ permalink raw reply
* Re: [PATCH] Centralise CONFIG_ARCH_NO_VIRT_TO_BUS
From: Bjorn Helgaas @ 2012-11-14 14:53 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-arch, Stephen Rothwell, linux-sh, linux-kernel,
David S. Miller, Paul Mundt, Paul Mackerras, sparclinux,
Andrew Morton, linuxppc-dev, H Hartley Sweeten
In-Reply-To: <CAMuHMdXu2VJhB+1uFApeBrYS3t2cfpPMaTz12F=A_FNJB1Q60w@mail.gmail.com>
On Tue, Nov 13, 2012 at 3:32 AM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> On Mon, Nov 12, 2012 at 10:26 PM, Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>> diff --git a/arch/Kconfig b/arch/Kconfig
>> index 366ec06..9bc00e7 100644
>> --- a/arch/Kconfig
>> +++ b/arch/Kconfig
>> @@ -271,6 +271,13 @@ config ARCH_WANT_OLD_COMPAT_IPC
>> select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
>> bool
>>
>> +config ARCH_NO_VIRT_TO_BUS
>> + bool
>> + help
>> + An architecture should select this if it cannot (or will not)
>> + implement virt_to_bus(). All new architectures should probably
>> + select this.
>
> Don't we typically put the burden of selecting Kconfig flags for deprecated
> features on the existing architectures that provide the deprecated features?
>
> I.e. shouldn't it be ARCH_HAS_VIRT_TO_BUS, selected by the architectures
> that need it, instead?
I like this idea.
^ permalink raw reply
* Re: [PATCH 1/5] Add /proc device tree updating to of node add/remove
From: Grant Likely @ 2012-11-14 14:38 UTC (permalink / raw)
To: Nathan Fontenot, devicetree-discuss, cbe-oss-dev, LKML,
linuxppc-dev
In-Reply-To: <506BA905.4090000@linux.vnet.ibm.com>
On Tue, 02 Oct 2012 21:55:01 -0500, Nathan Fontenot <nfont@linux.vnet.ibm.com> wrote:
> When adding or removing a device tree node we should also update
> the device tree in /proc/device-tree. This action is already done in the
> generic OF code for adding/removing properties of a node. This patch adds
> this functionality for nodes.
>
> Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
For the whole series:
Acked-by: Grant Likely <grant.likely@secretlab.ca>
^ permalink raw reply
* Re: [patch 4/4] mm, oom: remove statically defined arch functions of same name
From: Michal Hocko @ 2012-11-14 13:47 UTC (permalink / raw)
To: David Rientjes
Cc: Paul Mundt, linux-sh, Greg Kroah-Hartman, x86, linux-kernel,
linux-mm, Ingo Molnar, Paul Mackerras, KOSAKI Motohiro,
H. Peter Anvin, Andrew Morton, linuxppc-dev, Thomas Gleixner,
KAMEZAWA Hiroyuki
In-Reply-To: <alpine.DEB.2.00.1211140113480.32125@chino.kir.corp.google.com>
On Wed 14-11-12 01:15:28, David Rientjes wrote:
> out_of_memory() is a globally defined function to call the oom killer.
> x86, sh, and powerpc all use a function of the same name within file
> scope in their respective fault.c unnecessarily. Inline the functions
> into the pagefault handlers to clean the code up.
Yes I like it. It is really confusing to have a local function with the
same name.
>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Paul Mundt <lethal@linux-sh.org>
> Signed-off-by: David Rientjes <rientjes@google.com>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
> ---
> arch/powerpc/mm/fault.c | 27 ++++++++++++---------------
> arch/sh/mm/fault.c | 19 +++++++------------
> arch/x86/mm/fault.c | 23 ++++++++---------------
> 3 files changed, 27 insertions(+), 42 deletions(-)
>
> diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
> --- a/arch/powerpc/mm/fault.c
> +++ b/arch/powerpc/mm/fault.c
> @@ -113,19 +113,6 @@ static int store_updates_sp(struct pt_regs *regs)
> #define MM_FAULT_CONTINUE -1
> #define MM_FAULT_ERR(sig) (sig)
>
> -static int out_of_memory(struct pt_regs *regs)
> -{
> - /*
> - * We ran out of memory, or some other thing happened to us that made
> - * us unable to handle the page fault gracefully.
> - */
> - up_read(¤t->mm->mmap_sem);
> - if (!user_mode(regs))
> - return MM_FAULT_ERR(SIGKILL);
> - pagefault_out_of_memory();
> - return MM_FAULT_RETURN;
> -}
> -
> static int do_sigbus(struct pt_regs *regs, unsigned long address)
> {
> siginfo_t info;
> @@ -169,8 +156,18 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault)
> return MM_FAULT_CONTINUE;
>
> /* Out of memory */
> - if (fault & VM_FAULT_OOM)
> - return out_of_memory(regs);
> + if (fault & VM_FAULT_OOM) {
> + up_read(¤t->mm->mmap_sem);
> +
> + /*
> + * We ran out of memory, or some other thing happened to us that
> + * made us unable to handle the page fault gracefully.
> + */
> + if (!user_mode(regs))
> + return MM_FAULT_ERR(SIGKILL);
> + pagefault_out_of_memory();
> + return MM_FAULT_RETURN;
> + }
>
> /* Bus error. x86 handles HWPOISON here, we'll add this if/when
> * we support the feature in HW
> diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
> --- a/arch/sh/mm/fault.c
> +++ b/arch/sh/mm/fault.c
> @@ -301,17 +301,6 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
> __bad_area(regs, error_code, address, SEGV_ACCERR);
> }
>
> -static void out_of_memory(void)
> -{
> - /*
> - * We ran out of memory, call the OOM killer, and return the userspace
> - * (which will retry the fault, or kill us if we got oom-killed):
> - */
> - up_read(¤t->mm->mmap_sem);
> -
> - pagefault_out_of_memory();
> -}
> -
> static void
> do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address)
> {
> @@ -353,8 +342,14 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
> no_context(regs, error_code, address);
> return 1;
> }
> + up_read(¤t->mm->mmap_sem);
>
> - out_of_memory();
> + /*
> + * We ran out of memory, call the OOM killer, and return the
> + * userspace (which will retry the fault, or kill us if we got
> + * oom-killed):
> + */
> + pagefault_out_of_memory();
> } else {
> if (fault & VM_FAULT_SIGBUS)
> do_sigbus(regs, error_code, address);
> diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
> --- a/arch/x86/mm/fault.c
> +++ b/arch/x86/mm/fault.c
> @@ -803,20 +803,6 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
> __bad_area(regs, error_code, address, SEGV_ACCERR);
> }
>
> -/* TODO: fixup for "mm-invoke-oom-killer-from-page-fault.patch" */
> -static void
> -out_of_memory(struct pt_regs *regs, unsigned long error_code,
> - unsigned long address)
> -{
> - /*
> - * We ran out of memory, call the OOM killer, and return the userspace
> - * (which will retry the fault, or kill us if we got oom-killed):
> - */
> - up_read(¤t->mm->mmap_sem);
> -
> - pagefault_out_of_memory();
> -}
> -
> static void
> do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
> unsigned int fault)
> @@ -879,7 +865,14 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
> return 1;
> }
>
> - out_of_memory(regs, error_code, address);
> + up_read(¤t->mm->mmap_sem);
> +
> + /*
> + * We ran out of memory, call the OOM killer, and return the
> + * userspace (which will retry the fault, or kill us if we got
> + * oom-killed):
> + */
> + pagefault_out_of_memory();
> } else {
> if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
> VM_FAULT_HWPOISON_LARGE))
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH] TTY: hvc_console, fix port reference count going to zero prematurely
From: Benjamin Herrenschmidt @ 2012-11-14 12:47 UTC (permalink / raw)
To: Jiri Slaby; +Cc: linuxppc-dev, gregkh, Paul Mackerras, anton, alan
In-Reply-To: <50A36844.7080207@suse.cz>
On Wed, 2012-11-14 at 10:45 +0100, Jiri Slaby wrote:
> > This fixes it by removing the extra kref_put() and tty_kref_put() calls.
>
> Oh yeah. Thanks.
>
> Acked-by: Jiri Slaby <jslaby@suse.cz>
So who's merging it ?
Cheers,
Ben.
> > Signed-off-by: Paul Mackerras <paulus@samba.org>
> > Cc: stable@vger.kernel.org
> > ---
> > drivers/tty/hvc/hvc_console.c | 7 -------
> > 1 file changed, 7 deletions(-)
> >
> > diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
> > index a5dec1c..13ee53b 100644
> > --- a/drivers/tty/hvc/hvc_console.c
> > +++ b/drivers/tty/hvc/hvc_console.c
> > @@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty)
> > {
> > struct hvc_struct *hp = tty->driver_data;
> > unsigned long flags;
> > - int temp_open_count;
> >
> > if (!hp)
> > return;
> > @@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty)
> > return;
> > }
> >
> > - temp_open_count = hp->port.count;
> > hp->port.count = 0;
> > spin_unlock_irqrestore(&hp->port.lock, flags);
> > tty_port_tty_set(&hp->port, NULL);
> > @@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty)
> >
> > if (hp->ops->notifier_hangup)
> > hp->ops->notifier_hangup(hp, hp->data);
> > -
> > - while(temp_open_count) {
> > - --temp_open_count;
> > - tty_port_put(&hp->port);
> > - }
> > }
> >
> > /*
> >
>
>
^ permalink raw reply
* Re: [PATCH] Centralise CONFIG_ARCH_NO_VIRT_TO_BUS
From: Arnd Bergmann @ 2012-11-14 12:23 UTC (permalink / raw)
To: Stephen Rothwell
Cc: linux-arch, linux-sh, linux-kernel, David S. Miller, sparclinux,
Paul Mundt, Paul Mackerras, Bjorn Helgaas, Andrew Morton,
linuxppc-dev, H Hartley Sweeten
In-Reply-To: <20121113082615.2f482eb8835daf46e1f27947@canb.auug.org.au>
On Monday 12 November 2012, Stephen Rothwell wrote:
> Show Details
> Make if easier for more architectures to select it and thus disable
> drivers that use virt_to_bus().
>
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Very nice, I was recently looking into enabling this for ARM
as well, at least for the platforms that are known to not
need virt_to_bus.
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: [PATCH] cpuidle: Measure idle state durations with monotonic clock
From: Daniel Lezcano @ 2012-11-14 11:05 UTC (permalink / raw)
To: Julius Werner
Cc: Kevin Hilman, Deepthi Dharwar, Trinabh Gupta, Lists Linaro-dev,
linux-pm, linux-kernel, Rafael J. Wysocki, linux-acpi,
Srivatsa S. Bhat, Andrew Morton, linuxppc-dev, Sameer Nanda,
Len Brown
In-Reply-To: <1352843563-16392-1-git-send-email-jwerner@chromium.org>
On 11/13/2012 10:52 PM, Julius Werner wrote:
> Many cpuidle drivers measure their time spent in an idle state by
> reading the wallclock time before and after idling and calculating the
> difference. This leads to erroneous results when the wallclock time gets
> updated by another processor in the meantime, adding that clock
> adjustment to the idle state's time counter.
>
> If the clock adjustment was negative, the result is even worse due to an
> erroneous cast from int to unsigned long long of the last_residency
> variable. The negative 32 bit integer will zero-extend and result in a
> forward time jump of roughly four billion milliseconds or 1.3 hours on
> the idle state residency counter.
>
> This patch changes all affected cpuidle drivers to use the monotonic
> clock for their measurements instead. It also removes the erroneous
> cast, making sure that negative residency values are applied correctly
> even though they should not appear anymore.
>
> Signed-off-by: Julius Werner <jwerner@chromium.org>
> ---
> arch/powerpc/platforms/pseries/processor_idle.c | 4 ++--
> drivers/acpi/processor_idle.c | 12 ++++++------
> drivers/cpuidle/cpuidle.c | 3 +--
> drivers/idle/intel_idle.c | 13 ++++---------
> 4 files changed, 13 insertions(+), 19 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
> index 45d00e5..4d806b4 100644
> --- a/arch/powerpc/platforms/pseries/processor_idle.c
> +++ b/arch/powerpc/platforms/pseries/processor_idle.c
> @@ -36,7 +36,7 @@ static struct cpuidle_state *cpuidle_state_table;
> static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
> {
>
> - *kt_before = ktime_get_real();
> + *kt_before = ktime_get();
> *in_purr = mfspr(SPRN_PURR);
> /*
> * Indicate to the HV that we are idle. Now would be
> @@ -50,7 +50,7 @@ static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before)
> get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
> get_lppaca()->idle = 0;
>
> - return ktime_to_us(ktime_sub(ktime_get_real(), kt_before));
> + return ktime_to_us(ktime_sub(ktime_get(), kt_before));
> }
>
> static int snooze_loop(struct cpuidle_device *dev,
> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
> index e8086c7..8c98d73 100644
> --- a/drivers/acpi/processor_idle.c
> +++ b/drivers/acpi/processor_idle.c
> @@ -751,9 +751,9 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
>
>
> lapic_timer_state_broadcast(pr, cx, 1);
> - kt1 = ktime_get_real();
> + kt1 = ktime_get();
> acpi_idle_do_entry(cx);
> - kt2 = ktime_get_real();
> + kt2 = ktime_get();
> idle_time = ktime_to_us(ktime_sub(kt2, kt1));
>
> /* Update device last_residency*/
> @@ -843,11 +843,11 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
> if (cx->type == ACPI_STATE_C3)
> ACPI_FLUSH_CPU_CACHE();
>
> - kt1 = ktime_get_real();
> + kt1 = ktime_get();
> /* Tell the scheduler that we are going deep-idle: */
> sched_clock_idle_sleep_event();
> acpi_idle_do_entry(cx);
> - kt2 = ktime_get_real();
> + kt2 = ktime_get();
> idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
> idle_time = idle_time_ns;
> do_div(idle_time, NSEC_PER_USEC);
> @@ -934,7 +934,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> */
> lapic_timer_state_broadcast(pr, cx, 1);
>
> - kt1 = ktime_get_real();
> + kt1 = ktime_get();
> /*
> * disable bus master
> * bm_check implies we need ARB_DIS
> @@ -965,7 +965,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> c3_cpu_count--;
> raw_spin_unlock(&c3_lock);
> }
> - kt2 = ktime_get_real();
> + kt2 = ktime_get();
> idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
> idle_time = idle_time_ns;
> do_div(idle_time, NSEC_PER_USEC);
Maybe you can remove all these computations and set the flag
en_core_tk_irqen for the driver ? That will be handled by the cpuidle
framework, no ?
Same comment for the intel_idle driver.
Thanks
-- Daniel
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply
* Re: [PATCH] cpuidle: Measure idle state durations with monotonic clock
From: Daniel Lezcano @ 2012-11-14 10:57 UTC (permalink / raw)
To: Deepthi Dharwar
Cc: Kevin Hilman, Trinabh Gupta, linux-pm, linux-kernel,
Rafael J. Wysocki, linux-acpi, Srivatsa S. Bhat, Julius Werner,
Andrew Morton, linuxppc-dev, Sameer Nanda, Len Brown
In-Reply-To: <50A35F21.9040003@linux.vnet.ibm.com>
On 11/14/2012 10:06 AM, Deepthi Dharwar wrote:
> On 11/14/2012 03:22 AM, Julius Werner wrote:
>> Many cpuidle drivers measure their time spent in an idle state by
>> reading the wallclock time before and after idling and calculating the
>> difference. This leads to erroneous results when the wallclock time gets
>> updated by another processor in the meantime, adding that clock
>> adjustment to the idle state's time counter.
>>
>> If the clock adjustment was negative, the result is even worse due to an
>> erroneous cast from int to unsigned long long of the last_residency
>> variable. The negative 32 bit integer will zero-extend and result in a
>> forward time jump of roughly four billion milliseconds or 1.3 hours on
>> the idle state residency counter.
>>
>> This patch changes all affected cpuidle drivers to use the monotonic
>> clock for their measurements instead. It also removes the erroneous
>> cast, making sure that negative residency values are applied correctly
>> even though they should not appear anymore.
>
> Currently tegra/cpuidle uses ktime_get(). Good to have it for all
> the other arch idle residency time logging too.
Actually it is used by all arm cpuidle drivers through the wrapper
"cpuidle_wrap_enter" and the en_core_tk_irqen flag.
> Tested patch on pseries.
>
> Reviewed-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
>
> Cheers,
> Deepthi
>
>>
>> Signed-off-by: Julius Werner <jwerner@chromium.org>
>> ---
>> arch/powerpc/platforms/pseries/processor_idle.c | 4 ++--
>> drivers/acpi/processor_idle.c | 12 ++++++------
>> drivers/cpuidle/cpuidle.c | 3 +--
>> drivers/idle/intel_idle.c | 13 ++++---------
>> 4 files changed, 13 insertions(+), 19 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
>> index 45d00e5..4d806b4 100644
>> --- a/arch/powerpc/platforms/pseries/processor_idle.c
>> +++ b/arch/powerpc/platforms/pseries/processor_idle.c
>> @@ -36,7 +36,7 @@ static struct cpuidle_state *cpuidle_state_table;
>> static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
>> {
>>
>> - *kt_before = ktime_get_real();
>> + *kt_before = ktime_get();
>> *in_purr = mfspr(SPRN_PURR);
>> /*
>> * Indicate to the HV that we are idle. Now would be
>> @@ -50,7 +50,7 @@ static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before)
>> get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
>> get_lppaca()->idle = 0;
>>
>> - return ktime_to_us(ktime_sub(ktime_get_real(), kt_before));
>> + return ktime_to_us(ktime_sub(ktime_get(), kt_before));
>> }
>>
>> static int snooze_loop(struct cpuidle_device *dev,
>> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
>> index e8086c7..8c98d73 100644
>> --- a/drivers/acpi/processor_idle.c
>> +++ b/drivers/acpi/processor_idle.c
>> @@ -751,9 +751,9 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
>>
>>
>> lapic_timer_state_broadcast(pr, cx, 1);
>> - kt1 = ktime_get_real();
>> + kt1 = ktime_get();
>> acpi_idle_do_entry(cx);
>> - kt2 = ktime_get_real();
>> + kt2 = ktime_get();
>> idle_time = ktime_to_us(ktime_sub(kt2, kt1));
>>
>> /* Update device last_residency*/
>> @@ -843,11 +843,11 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
>> if (cx->type == ACPI_STATE_C3)
>> ACPI_FLUSH_CPU_CACHE();
>>
>> - kt1 = ktime_get_real();
>> + kt1 = ktime_get();
>> /* Tell the scheduler that we are going deep-idle: */
>> sched_clock_idle_sleep_event();
>> acpi_idle_do_entry(cx);
>> - kt2 = ktime_get_real();
>> + kt2 = ktime_get();
>> idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
>> idle_time = idle_time_ns;
>> do_div(idle_time, NSEC_PER_USEC);
>> @@ -934,7 +934,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
>> */
>> lapic_timer_state_broadcast(pr, cx, 1);
>>
>> - kt1 = ktime_get_real();
>> + kt1 = ktime_get();
>> /*
>> * disable bus master
>> * bm_check implies we need ARB_DIS
>> @@ -965,7 +965,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
>> c3_cpu_count--;
>> raw_spin_unlock(&c3_lock);
>> }
>> - kt2 = ktime_get_real();
>> + kt2 = ktime_get();
>> idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
>> idle_time = idle_time_ns;
>> do_div(idle_time, NSEC_PER_USEC);
>> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
>> index 7f15b85..1536edd 100644
>> --- a/drivers/cpuidle/cpuidle.c
>> +++ b/drivers/cpuidle/cpuidle.c
>> @@ -109,8 +109,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
>> /* This can be moved to within driver enter routine
>> * but that results in multiple copies of same code.
>> */
>> - dev->states_usage[entered_state].time +=
>> - (unsigned long long)dev->last_residency;
>> + dev->states_usage[entered_state].time += dev->last_residency;
>> dev->states_usage[entered_state].usage++;
>> } else {
>> dev->last_residency = 0;
>> diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
>> index b0f6b4c..6329a97 100644
>> --- a/drivers/idle/intel_idle.c
>> +++ b/drivers/idle/intel_idle.c
>> @@ -56,7 +56,7 @@
>> #include <linux/kernel.h>
>> #include <linux/cpuidle.h>
>> #include <linux/clockchips.h>
>> -#include <linux/hrtimer.h> /* ktime_get_real() */
>> +#include <linux/hrtimer.h> /* ktime_get() */
>> #include <trace/events/power.h>
>> #include <linux/sched.h>
>> #include <linux/notifier.h>
>> @@ -281,8 +281,7 @@ static int intel_idle(struct cpuidle_device *dev,
>> struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
>> unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage);
>> unsigned int cstate;
>> - ktime_t kt_before, kt_after;
>> - s64 usec_delta;
>> + ktime_t kt_before;
>> int cpu = smp_processor_id();
>>
>> cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
>> @@ -297,7 +296,7 @@ static int intel_idle(struct cpuidle_device *dev,
>> if (!(lapic_timer_reliable_states & (1 << (cstate))))
>> clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
>>
>> - kt_before = ktime_get_real();
>> + kt_before = ktime_get();
>>
>> stop_critical_timings();
>> if (!need_resched()) {
>> @@ -310,17 +309,13 @@ static int intel_idle(struct cpuidle_device *dev,
>>
>> start_critical_timings();
>>
>> - kt_after = ktime_get_real();
>> - usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before));
>> + dev->last_residency = ktime_to_us(ktime_sub(ktime_get(), kt_before));
>>
>> local_irq_enable();
>>
>> if (!(lapic_timer_reliable_states & (1 << (cstate))))
>> clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
>>
>> - /* Update cpuidle counters */
>> - dev->last_residency = (int)usec_delta;
>> -
>> return index;
>> }
>>
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply
* Re: [PATCH 4/4] perf: Create a sysfs entry for Power event format
From: Jiri Olsa @ 2012-11-14 10:27 UTC (permalink / raw)
To: Sukadev Bhattiprolu
Cc: Peter Zijlstra, robert.richter, Anton Blanchard, linux-kernel,
linuxppc-dev, Ingo Molnar, Paul Mackerras,
Arnaldo Carvalho de Melo
In-Reply-To: <20121107191951.GD16211@us.ibm.com>
On Wed, Nov 07, 2012 at 11:19:52AM -0800, Sukadev Bhattiprolu wrote:
>
> From bafc551c31ce23c1cba0b75d23de6c46aba90f26 Mon Sep 17 00:00:00 2001
> From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Date: Tue, 6 Nov 2012 16:30:28 -0800
> Subject: [PATCH 4/4] perf: Create a sysfs entry for Power event format
>
> Create a sysfs entry, '/sys/bus/event_source/devices/cpu/format/event'
> which describes the format of a POWER cpu.
>
> $ cat /sys/bus/event_source/devices/cpu/format/event
> config:0-20
>
> The format of the event is the same for all POWER cpus, so bulk of this
> change is in the code common to POWER cpus.
>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/perf_event_server.h | 8 ++++++++
> arch/powerpc/perf/core-book3s.c | 19 +++++++++++++++++++
> arch/powerpc/perf/power7-pmu.c | 1 +
> 3 files changed, 28 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
> index ad84f73..20a49bf 100644
> --- a/arch/powerpc/include/asm/perf_event_server.h
> +++ b/arch/powerpc/include/asm/perf_event_server.h
> @@ -130,3 +130,11 @@ extern ssize_t power_events_sysfs_show(struct device *dev,
> .attr = __ATTR(_name, 0444, power_events_sysfs_show, NULL),\
> .id = PM_##_id, \
> };
> +
> +/*
> + * Format of a perf event is the same on all POWER cpus. Declare a
> + * common sysfs attribute group that individual POWER cpus can share.
> + */
> +extern struct attribute_group power_pmu_format_group;
> +
> +
> diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
> index 19b23bd..388e2a1 100644
> --- a/arch/powerpc/perf/core-book3s.c
> +++ b/arch/powerpc/perf/core-book3s.c
> @@ -1315,6 +1315,25 @@ ssize_t power_events_sysfs_show(struct device *dev,
> return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
> }
>
> +static ssize_t power_config_sysfs_show(struct device *dev,
> + struct device_attribute *attr, char *page)
> +{
> + return sprintf(page, "config:0-20\n");
> +}
> +
> +static struct device_attribute config_dev_attr = \
> + __ATTR(event, 0444, power_config_sysfs_show, NULL);
there's PMU_FORMAT_ATTR in include/linux/perf_event.h macro doing this
jirka
^ permalink raw reply
* Re: [PATCH 3/4] perf/POWER7: Make event translations available in sysfs
From: Jiri Olsa @ 2012-11-14 10:25 UTC (permalink / raw)
To: Sukadev Bhattiprolu
Cc: Peter Zijlstra, robert.richter, Anton Blanchard, linux-kernel,
linuxppc-dev, Ingo Molnar, Paul Mackerras,
Arnaldo Carvalho de Melo
In-Reply-To: <20121107191927.GC16211@us.ibm.com>
On Wed, Nov 07, 2012 at 11:19:28AM -0800, Sukadev Bhattiprolu wrote:
SNIP
> +struct perf_pmu_events_attr {
> + struct device_attribute attr;
> + u64 id;
> +};
> +
> +extern ssize_t power_events_sysfs_show(struct device *dev,
> + struct device_attribute *attr, char *page);
> +
> +#define EVENT_VAR(_id) event_attr_##_id
> +#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
> +
> +#define EVENT_ATTR(_name, _id) \
> + static struct perf_pmu_events_attr EVENT_VAR(_id) = { \
> + .attr = __ATTR(_name, 0444, power_events_sysfs_show, NULL),\
> + .id = PM_##_id, \
> + };
this is duplicating the x86 code, perhaps it could be moved
to include/linux/perf_event.h and shared globaly
> diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
> index aa2465e..19b23bd 100644
> --- a/arch/powerpc/perf/core-book3s.c
> +++ b/arch/powerpc/perf/core-book3s.c
> @@ -1305,6 +1305,16 @@ static int power_pmu_event_idx(struct perf_event *event)
> return event->hw.idx;
> }
>
> +ssize_t power_events_sysfs_show(struct device *dev,
> + struct device_attribute *attr, char *page)
> +{
> + struct perf_pmu_events_attr *pmu_attr;
> +
> + pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
> +
> + return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
whitespace issues
jirka
^ permalink raw reply
* Re: [PATCH] TTY: hvc_console, fix port reference count going to zero prematurely
From: Jiri Slaby @ 2012-11-14 9:45 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, alan, anton, gregkh
In-Reply-To: <20121114081547.GA573@bloggs.ozlabs.ibm.com>
On 11/14/2012 09:15 AM, Paul Mackerras wrote:
> Commit bdb498c20040 "TTY: hvc_console, add tty install" took the port
> refcounting out of hvc_open()/hvc_close(), but failed to remove the
> kref_put() and tty_kref_put() calls in hvc_hangup() that were there to
> remove the extra references that hvc_open() had taken.
>
> The result was that doing a vhangup() when the current terminal was
> a hvc_console, then closing the current terminal, would end up calling
> destroy_hvc_struct() and making the port disappear entirely. This
> meant that Fedora 17 systems would boot up but then not display the
> login prompt on the console, and attempts to open /dev/hvc0 would
> give a "No such device" error.
>
> This fixes it by removing the extra kref_put() and tty_kref_put() calls.
Oh yeah. Thanks.
Acked-by: Jiri Slaby <jslaby@suse.cz>
> Signed-off-by: Paul Mackerras <paulus@samba.org>
> Cc: stable@vger.kernel.org
> ---
> drivers/tty/hvc/hvc_console.c | 7 -------
> 1 file changed, 7 deletions(-)
>
> diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
> index a5dec1c..13ee53b 100644
> --- a/drivers/tty/hvc/hvc_console.c
> +++ b/drivers/tty/hvc/hvc_console.c
> @@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty)
> {
> struct hvc_struct *hp = tty->driver_data;
> unsigned long flags;
> - int temp_open_count;
>
> if (!hp)
> return;
> @@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty)
> return;
> }
>
> - temp_open_count = hp->port.count;
> hp->port.count = 0;
> spin_unlock_irqrestore(&hp->port.lock, flags);
> tty_port_tty_set(&hp->port, NULL);
> @@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty)
>
> if (hp->ops->notifier_hangup)
> hp->ops->notifier_hangup(hp, hp->data);
> -
> - while(temp_open_count) {
> - --temp_open_count;
> - tty_port_put(&hp->port);
> - }
> }
>
> /*
>
--
js
suse labs
^ permalink raw reply
* Re: [PATCH 0/1] powerpc/vdso: remove redundant locking in update_vsyscall_tz()
From: Shan Hai @ 2012-11-14 9:39 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, john.stultz
In-Reply-To: <20121109015718.GA6124@debian.corp.ad.wrs.com>
On Fri, Nov 09, 2012 at 09:57:49AM +0800, Shan Hai wrote:
> The locking in update_vsyscall_tz() is not only unnecessary because the vdso
> code copies the data unproteced in __kernel_gettimeofday() but also
> introduces a hard to reproduce race condition between update_vsyscall()
> and update_vsyscall_tz(), which causes user space process to loop
> forever in vdso code.
>
> The following patch removes the locking from update_vsyscall_tz().
>
> ---
> arch/powerpc/kernel/time.c | 5 -----
> 1 file changed, 5 deletions(-)
>
Hi Ben,
Would you please review this one?
>From 167eac293b07e0ee201ffe5043ec442d52495a48 Mon Sep 17 00:00:00 2001
From: Shan Hai <shan.hai@windriver.com>
Date: Mon, 5 Nov 2012 18:24:22 +0800
Subject: [PATCH 1/1] powerpc/vdso: remove redundant locking in
update_vsyscall_tz()
Locking is not only unnecessary because the vdso code copies the data
unprotected in __kernel_gettimeofday() but also erroneous because updating
the tb_update_count is not atomic and introduces a hard to reproduce race
condition between update_vsyscall() and update_vsyscall_tz(), which further
causes user space process to loop forever in vdso code.
The below scenario describes the race condition,
x==0 Boot CPU other CPU
proc_P: x==0
timer interrupt
update_vsyscall
x==1 x++;sync settimeofday
update_vsyscall_tz
x==2 x++;sync
x==3 sync;x++
sync;x++
proc_P: x==3 (loops until x becomes even)
Because the ++ operator would be implemented as three instructions and not
atomic on powerpc.
A similar change was made for x86 in commit 6c260d58634
("x86: vdso: Remove bogus locking in update_vsyscall_tz")
Signed-off-by: Shan Hai <shan.hai@windriver.com>
---
arch/powerpc/kernel/time.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 03b29a6..426141f 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -859,13 +859,8 @@ void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
void update_vsyscall_tz(void)
{
- /* Make userspace gettimeofday spin until we're done. */
- ++vdso_data->tb_update_count;
- smp_mb();
vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
vdso_data->tz_dsttime = sys_tz.tz_dsttime;
- smp_mb();
- ++vdso_data->tb_update_count;
}
static void __init clocksource_init(void)
--
1.7.10.4
Best Regards
Shan Hai
> Thanks
> Shan Hai
> From 167eac293b07e0ee201ffe5043ec442d52495a48 Mon Sep 17 00:00:00 2001
> From: Shan Hai <shan.hai@windriver.com>
> Date: Mon, 5 Nov 2012 18:24:22 +0800
> Subject: [PATCH 1/1] powerpc/vdso: remove redundant locking in
> update_vsyscall_tz()
>
> Locking is not only unnecessary because the vdso code copies the data
> unprotected in __kernel_gettimeofday() but also erroneous because updating
> the tb_update_count is not atomic and introduces a hard to reproduce race
> condition between update_vsyscall() and update_vsyscall_tz(), which further
> causes user space process to loop forever in vdso code.
>
> The below scenario describes the race condition,
> x==0 Boot CPU other CPU
> proc_P: x==0
> timer interrupt
> update_vsyscall
> x==1 x++;sync settimeofday
> update_vsyscall_tz
> x==2 x++;sync
> x==3 sync;x++
> sync;x++
> proc_P: x==3 (loops until x becomes even)
>
> Because the ++ operator would be implemented as three instructions and not
> atomic on powerpc.
>
> A similar change was made for x86 in commit 6c260d58634
> ("x86: vdso: Remove bogus locking in update_vsyscall_tz")
>
> Signed-off-by: Shan Hai <shan.hai@windriver.com>
> ---
> arch/powerpc/kernel/time.c | 5 -----
> 1 file changed, 5 deletions(-)
>
> diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
> index 03b29a6..426141f 100644
> --- a/arch/powerpc/kernel/time.c
> +++ b/arch/powerpc/kernel/time.c
> @@ -859,13 +859,8 @@ void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
>
> void update_vsyscall_tz(void)
> {
> - /* Make userspace gettimeofday spin until we're done. */
> - ++vdso_data->tb_update_count;
> - smp_mb();
> vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
> vdso_data->tz_dsttime = sys_tz.tz_dsttime;
> - smp_mb();
> - ++vdso_data->tb_update_count;
> }
>
> static void __init clocksource_init(void)
> --
> 1.7.10.4
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply related
* [patch 4/4] mm, oom: remove statically defined arch functions of same name
From: David Rientjes @ 2012-11-14 9:15 UTC (permalink / raw)
To: Andrew Morton
Cc: Paul Mundt, linux-sh, Greg Kroah-Hartman, x86, linux-kernel,
Michal Hocko, linux-mm, Ingo Molnar, Paul Mackerras,
KOSAKI Motohiro, H. Peter Anvin, Thomas Gleixner, linuxppc-dev,
KAMEZAWA Hiroyuki
In-Reply-To: <alpine.DEB.2.00.1211140111190.32125@chino.kir.corp.google.com>
out_of_memory() is a globally defined function to call the oom killer.
x86, sh, and powerpc all use a function of the same name within file
scope in their respective fault.c unnecessarily. Inline the functions
into the pagefault handlers to clean the code up.
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: David Rientjes <rientjes@google.com>
---
arch/powerpc/mm/fault.c | 27 ++++++++++++---------------
arch/sh/mm/fault.c | 19 +++++++------------
arch/x86/mm/fault.c | 23 ++++++++---------------
3 files changed, 27 insertions(+), 42 deletions(-)
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -113,19 +113,6 @@ static int store_updates_sp(struct pt_regs *regs)
#define MM_FAULT_CONTINUE -1
#define MM_FAULT_ERR(sig) (sig)
-static int out_of_memory(struct pt_regs *regs)
-{
- /*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
- up_read(¤t->mm->mmap_sem);
- if (!user_mode(regs))
- return MM_FAULT_ERR(SIGKILL);
- pagefault_out_of_memory();
- return MM_FAULT_RETURN;
-}
-
static int do_sigbus(struct pt_regs *regs, unsigned long address)
{
siginfo_t info;
@@ -169,8 +156,18 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault)
return MM_FAULT_CONTINUE;
/* Out of memory */
- if (fault & VM_FAULT_OOM)
- return out_of_memory(regs);
+ if (fault & VM_FAULT_OOM) {
+ up_read(¤t->mm->mmap_sem);
+
+ /*
+ * We ran out of memory, or some other thing happened to us that
+ * made us unable to handle the page fault gracefully.
+ */
+ if (!user_mode(regs))
+ return MM_FAULT_ERR(SIGKILL);
+ pagefault_out_of_memory();
+ return MM_FAULT_RETURN;
+ }
/* Bus error. x86 handles HWPOISON here, we'll add this if/when
* we support the feature in HW
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -301,17 +301,6 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
__bad_area(regs, error_code, address, SEGV_ACCERR);
}
-static void out_of_memory(void)
-{
- /*
- * We ran out of memory, call the OOM killer, and return the userspace
- * (which will retry the fault, or kill us if we got oom-killed):
- */
- up_read(¤t->mm->mmap_sem);
-
- pagefault_out_of_memory();
-}
-
static void
do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address)
{
@@ -353,8 +342,14 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
no_context(regs, error_code, address);
return 1;
}
+ up_read(¤t->mm->mmap_sem);
- out_of_memory();
+ /*
+ * We ran out of memory, call the OOM killer, and return the
+ * userspace (which will retry the fault, or kill us if we got
+ * oom-killed):
+ */
+ pagefault_out_of_memory();
} else {
if (fault & VM_FAULT_SIGBUS)
do_sigbus(regs, error_code, address);
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -803,20 +803,6 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
__bad_area(regs, error_code, address, SEGV_ACCERR);
}
-/* TODO: fixup for "mm-invoke-oom-killer-from-page-fault.patch" */
-static void
-out_of_memory(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
-{
- /*
- * We ran out of memory, call the OOM killer, and return the userspace
- * (which will retry the fault, or kill us if we got oom-killed):
- */
- up_read(¤t->mm->mmap_sem);
-
- pagefault_out_of_memory();
-}
-
static void
do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
unsigned int fault)
@@ -879,7 +865,14 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
return 1;
}
- out_of_memory(regs, error_code, address);
+ up_read(¤t->mm->mmap_sem);
+
+ /*
+ * We ran out of memory, call the OOM killer, and return the
+ * userspace (which will retry the fault, or kill us if we got
+ * oom-killed):
+ */
+ pagefault_out_of_memory();
} else {
if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
VM_FAULT_HWPOISON_LARGE))
^ permalink raw reply
* Re: [PATCH] cpuidle: Measure idle state durations with monotonic clock
From: Deepthi Dharwar @ 2012-11-14 9:06 UTC (permalink / raw)
To: Julius Werner
Cc: Kevin Hilman, Trinabh Gupta, linux-pm, Daniel Lezcano,
linux-kernel, Rafael J. Wysocki, linux-acpi, Srivatsa S. Bhat,
Andrew Morton, linuxppc-dev, Sameer Nanda, Len Brown
In-Reply-To: <1352843563-16392-1-git-send-email-jwerner@chromium.org>
On 11/14/2012 03:22 AM, Julius Werner wrote:
> Many cpuidle drivers measure their time spent in an idle state by
> reading the wallclock time before and after idling and calculating the
> difference. This leads to erroneous results when the wallclock time gets
> updated by another processor in the meantime, adding that clock
> adjustment to the idle state's time counter.
>
> If the clock adjustment was negative, the result is even worse due to an
> erroneous cast from int to unsigned long long of the last_residency
> variable. The negative 32 bit integer will zero-extend and result in a
> forward time jump of roughly four billion milliseconds or 1.3 hours on
> the idle state residency counter.
>
> This patch changes all affected cpuidle drivers to use the monotonic
> clock for their measurements instead. It also removes the erroneous
> cast, making sure that negative residency values are applied correctly
> even though they should not appear anymore.
Currently tegra/cpuidle uses ktime_get(). Good to have it for all
the other arch idle residency time logging too.
Tested patch on pseries.
Reviewed-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Cheers,
Deepthi
>
> Signed-off-by: Julius Werner <jwerner@chromium.org>
> ---
> arch/powerpc/platforms/pseries/processor_idle.c | 4 ++--
> drivers/acpi/processor_idle.c | 12 ++++++------
> drivers/cpuidle/cpuidle.c | 3 +--
> drivers/idle/intel_idle.c | 13 ++++---------
> 4 files changed, 13 insertions(+), 19 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
> index 45d00e5..4d806b4 100644
> --- a/arch/powerpc/platforms/pseries/processor_idle.c
> +++ b/arch/powerpc/platforms/pseries/processor_idle.c
> @@ -36,7 +36,7 @@ static struct cpuidle_state *cpuidle_state_table;
> static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
> {
>
> - *kt_before = ktime_get_real();
> + *kt_before = ktime_get();
> *in_purr = mfspr(SPRN_PURR);
> /*
> * Indicate to the HV that we are idle. Now would be
> @@ -50,7 +50,7 @@ static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before)
> get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
> get_lppaca()->idle = 0;
>
> - return ktime_to_us(ktime_sub(ktime_get_real(), kt_before));
> + return ktime_to_us(ktime_sub(ktime_get(), kt_before));
> }
>
> static int snooze_loop(struct cpuidle_device *dev,
> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
> index e8086c7..8c98d73 100644
> --- a/drivers/acpi/processor_idle.c
> +++ b/drivers/acpi/processor_idle.c
> @@ -751,9 +751,9 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
>
>
> lapic_timer_state_broadcast(pr, cx, 1);
> - kt1 = ktime_get_real();
> + kt1 = ktime_get();
> acpi_idle_do_entry(cx);
> - kt2 = ktime_get_real();
> + kt2 = ktime_get();
> idle_time = ktime_to_us(ktime_sub(kt2, kt1));
>
> /* Update device last_residency*/
> @@ -843,11 +843,11 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
> if (cx->type == ACPI_STATE_C3)
> ACPI_FLUSH_CPU_CACHE();
>
> - kt1 = ktime_get_real();
> + kt1 = ktime_get();
> /* Tell the scheduler that we are going deep-idle: */
> sched_clock_idle_sleep_event();
> acpi_idle_do_entry(cx);
> - kt2 = ktime_get_real();
> + kt2 = ktime_get();
> idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
> idle_time = idle_time_ns;
> do_div(idle_time, NSEC_PER_USEC);
> @@ -934,7 +934,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> */
> lapic_timer_state_broadcast(pr, cx, 1);
>
> - kt1 = ktime_get_real();
> + kt1 = ktime_get();
> /*
> * disable bus master
> * bm_check implies we need ARB_DIS
> @@ -965,7 +965,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> c3_cpu_count--;
> raw_spin_unlock(&c3_lock);
> }
> - kt2 = ktime_get_real();
> + kt2 = ktime_get();
> idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
> idle_time = idle_time_ns;
> do_div(idle_time, NSEC_PER_USEC);
> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
> index 7f15b85..1536edd 100644
> --- a/drivers/cpuidle/cpuidle.c
> +++ b/drivers/cpuidle/cpuidle.c
> @@ -109,8 +109,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
> /* This can be moved to within driver enter routine
> * but that results in multiple copies of same code.
> */
> - dev->states_usage[entered_state].time +=
> - (unsigned long long)dev->last_residency;
> + dev->states_usage[entered_state].time += dev->last_residency;
> dev->states_usage[entered_state].usage++;
> } else {
> dev->last_residency = 0;
> diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
> index b0f6b4c..6329a97 100644
> --- a/drivers/idle/intel_idle.c
> +++ b/drivers/idle/intel_idle.c
> @@ -56,7 +56,7 @@
> #include <linux/kernel.h>
> #include <linux/cpuidle.h>
> #include <linux/clockchips.h>
> -#include <linux/hrtimer.h> /* ktime_get_real() */
> +#include <linux/hrtimer.h> /* ktime_get() */
> #include <trace/events/power.h>
> #include <linux/sched.h>
> #include <linux/notifier.h>
> @@ -281,8 +281,7 @@ static int intel_idle(struct cpuidle_device *dev,
> struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
> unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage);
> unsigned int cstate;
> - ktime_t kt_before, kt_after;
> - s64 usec_delta;
> + ktime_t kt_before;
> int cpu = smp_processor_id();
>
> cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
> @@ -297,7 +296,7 @@ static int intel_idle(struct cpuidle_device *dev,
> if (!(lapic_timer_reliable_states & (1 << (cstate))))
> clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
>
> - kt_before = ktime_get_real();
> + kt_before = ktime_get();
>
> stop_critical_timings();
> if (!need_resched()) {
> @@ -310,17 +309,13 @@ static int intel_idle(struct cpuidle_device *dev,
>
> start_critical_timings();
>
> - kt_after = ktime_get_real();
> - usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before));
> + dev->last_residency = ktime_to_us(ktime_sub(ktime_get(), kt_before));
>
> local_irq_enable();
>
> if (!(lapic_timer_reliable_states & (1 << (cstate))))
> clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
>
> - /* Update cpuidle counters */
> - dev->last_residency = (int)usec_delta;
> -
> return index;
> }
>
^ permalink raw reply
* [PATCH] TTY: hvc_console, fix port reference count going to zero prematurely
From: Paul Mackerras @ 2012-11-14 8:15 UTC (permalink / raw)
To: jslaby, benh, anton, gregkh, alan; +Cc: linuxppc-dev
Commit bdb498c20040 "TTY: hvc_console, add tty install" took the port
refcounting out of hvc_open()/hvc_close(), but failed to remove the
kref_put() and tty_kref_put() calls in hvc_hangup() that were there to
remove the extra references that hvc_open() had taken.
The result was that doing a vhangup() when the current terminal was
a hvc_console, then closing the current terminal, would end up calling
destroy_hvc_struct() and making the port disappear entirely. This
meant that Fedora 17 systems would boot up but then not display the
login prompt on the console, and attempts to open /dev/hvc0 would
give a "No such device" error.
This fixes it by removing the extra kref_put() and tty_kref_put() calls.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Cc: stable@vger.kernel.org
---
drivers/tty/hvc/hvc_console.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index a5dec1c..13ee53b 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty)
{
struct hvc_struct *hp = tty->driver_data;
unsigned long flags;
- int temp_open_count;
if (!hp)
return;
@@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty)
return;
}
- temp_open_count = hp->port.count;
hp->port.count = 0;
spin_unlock_irqrestore(&hp->port.lock, flags);
tty_port_tty_set(&hp->port, NULL);
@@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty)
if (hp->ops->notifier_hangup)
hp->ops->notifier_hangup(hp, hp->data);
-
- while(temp_open_count) {
- --temp_open_count;
- tty_port_put(&hp->port);
- }
}
/*
--
1.7.10.rc3.219.g53414
^ permalink raw reply related
* Re: HVC console breakage
From: Benjamin Herrenschmidt @ 2012-11-14 4:13 UTC (permalink / raw)
To: Anton Blanchard
Cc: linuxppc-dev, paulus, gregkh, Paul Mackerras, jslaby, alan
In-Reply-To: <20121114135702.7b332dd7@kryten>
On Wed, 2012-11-14 at 13:57 +1100, Anton Blanchard wrote:
> Hi,
>
> Commit bdb498c20040 (TTY: hvc_console, add tty install) breaks HVC on
> ppc64. It looks a bit like a refcounting issue and we end up releasing
> the tty. I haven't had a change to look closer yet.
Adding Paulus who is looking into it. So far what we observe is that
something (possibly a close() on a hvc tty by userspace) causes the port
to be destroyed permanently. Typically hits with fedora 17.
Cheers,
Ben.
^ permalink raw reply
* HVC console breakage
From: Anton Blanchard @ 2012-11-14 2:57 UTC (permalink / raw)
To: jslaby, benh, paulus, gregkh, alan; +Cc: linuxppc-dev
Hi,
Commit bdb498c20040 (TTY: hvc_console, add tty install) breaks HVC on
ppc64. It looks a bit like a refcounting issue and we end up releasing
the tty. I haven't had a change to look closer yet.
Anton
^ permalink raw reply
* Re: [PATCH 1/1] arch Kconfig: remove references to IRQ_PER_CPU
From: Richard Kuo @ 2012-11-14 0:53 UTC (permalink / raw)
To: James Hogan
Cc: linux-arch, linux-mips, Tony Luck, linux-ia64, linux-parisc,
linux-sh, linux-hexagon, Helge Deller, linux-kernel, Fenghua Yu,
James E.J. Bottomley, Paul Mundt, Mike Frysinger, Ralf Baechle,
uclinux-dist-devel, Thomas Gleixner, linuxppc-dev, Paul Mackerras
In-Reply-To: <1352807948-26920-1-git-send-email-james.hogan@imgtec.com>
On Tue, Nov 13, 2012 at 11:59:08AM +0000, James Hogan wrote:
> The IRQ_PER_CPU Kconfig symbol was removed in the following commit:
>
> Commit 6a58fb3bad099076f36f0f30f44507bc3275cdb6 ("genirq: Remove
> CONFIG_IRQ_PER_CPU") merged in v2.6.39-rc1.
>
> But IRQ_PER_CPU wasn't removed from any of the architecture Kconfig
> files where it was defined or selected. It's completely unused so remove
> the remaining references.
>
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Mike Frysinger <vapier@gentoo.org>
> Cc: Richard Kuo <rkuo@codeaurora.org>
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: Fenghua Yu <fenghua.yu@intel.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
> Cc: Helge Deller <deller@gmx.de>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Paul Mundt <lethal@linux-sh.org>
> ---
> Based on v3.7-rc5.
>
> Compile tested defconfigs for bfin, ia64, mips, parisc, powerpc, sh, but
> not hexagon.
>
> Grepped entire tree to check no references to CONFIG_IRQ_PER_CPU, and
> grepped arch/ for Kconfig files referencing IRQ_PER_CPU.
>
> arch/blackfin/Kconfig | 1 -
> arch/hexagon/Kconfig | 1 -
> arch/ia64/Kconfig | 1 -
> arch/mips/Kconfig | 1 -
> arch/parisc/Kconfig | 1 -
> arch/powerpc/Kconfig | 1 -
> arch/sh/Kconfig | 3 ---
> 7 files changed, 0 insertions(+), 9 deletions(-)
>
Hexagon's was commented out anyways, but thanks for pointing it out.
Acked-by: Richard Kuo <rkuo@codeaurora.org>
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* Re: [PATCH V2] wanrouter: Remove it and the drivers that depend on it
From: Joe Perches @ 2012-11-13 22:32 UTC (permalink / raw)
To: David Miller
Cc: linux-mips, linux-doc, jcmvbkbc, harryxiyou, paulus, linux,
richard, linux-xtensa, rob, user-mode-linux-devel, jdike,
xiyoulinuxkernelgroup, user-mode-linux-user, linux-arm-kernel,
chris, isdn, netdev, linux-kernel, ralf, linux-kernel,
linuxppc-dev
In-Reply-To: <20121113.171736.561094209116852795.davem@davemloft.net>
On Tue, 2012-11-13 at 17:17 -0500, David Miller wrote:
> From: Joe Perches <joe@perches.com>
> Date: Tue, 13 Nov 2012 12:17:25 -0800
>
> > That seems an odd workflow as it leaves dangling CONFIG_<foo>
> > options set, but I guess it doesn't hurt so here it is.
>
> As you said it's harmless, and more importantly it avoids
> unnecessary conflicts.
>
> > I just removed the modified arch/.../<foo>defconfig files.
>
> Something is not right here:
> [davem@drr net-next]$ git am --signoff V2-wanrouter-Remove-it-and-the-drivers-that-depend-on-it.patch
> Applying: wanrouter: Remove it and the drivers that depend on it
> error: removal patch leaves file contents
> error: net/wanrouter/Kconfig: patch does not apply
> error: removal patch leaves file contents
> error: net/wanrouter/Makefile: patch does not apply
> error: removal patch leaves file contents
> error: net/wanrouter/patchlevel: patch does not apply
> error: removal patch leaves file contents
> error: net/wanrouter/wanmain.c: patch does not apply
> error: removal patch leaves file contents
> error: net/wanrouter/wanproc.c: patch does not apply
> error: removal patch leaves file contents
> error: drivers/net/wan/cycx_drv.c: patch does not apply
> error: removal patch leaves file contents
> error: drivers/net/wan/cycx_main.c: patch does not apply
> error: removal patch leaves file contents
> error: drivers/net/wan/cycx_x25.c: patch does not apply
> error: removal patch leaves file contents
> error: include/linux/cyclomx.h: patch does not apply
> error: removal patch leaves file contents
> error: include/linux/cycx_drv.h: patch does not apply
> error: removal patch leaves file contents
> error: include/linux/wanrouter.h: patch does not apply
> error: removal patch leaves file contents
> error: include/uapi/linux/wanrouter.h: patch does not apply
Right, that is unexpected/odd/interesting.
I was trying to save mailing list bandwidth by reducing
the patch size.
I generated this with
$ git format-patch -M -D
but it doesn't apply here either. :(
Using
$ git format-patch -M
does apply correctly.
It's quite a bit larger though. (120KB vs 14)
I'll send the large patch just to netdev.
Joe
^ permalink raw reply
* Re: [PATCH V2] wanrouter: Remove it and the drivers that depend on it
From: David Miller @ 2012-11-13 22:17 UTC (permalink / raw)
To: joe
Cc: linux-mips, linux-doc, jcmvbkbc, harryxiyou, paulus, linux,
richard, linux-xtensa, rob, user-mode-linux-devel, jdike,
xiyoulinuxkernelgroup, user-mode-linux-user, linux-arm-kernel,
chris, isdn, netdev, linux-kernel, ralf, linux-kernel,
linuxppc-dev
In-Reply-To: <1352837845.12850.3.camel@joe-AO722>
From: Joe Perches <joe@perches.com>
Date: Tue, 13 Nov 2012 12:17:25 -0800
> That seems an odd workflow as it leaves dangling CONFIG_<foo>
> options set, but I guess it doesn't hurt so here it is.
As you said it's harmless, and more importantly it avoids
unnecessary conflicts.
> I just removed the modified arch/.../<foo>defconfig files.
Something is not right here:
[davem@drr net-next]$ git am --signoff V2-wanrouter-Remove-it-and-the-drivers-that-depend-on-it.patch
Applying: wanrouter: Remove it and the drivers that depend on it
error: removal patch leaves file contents
error: net/wanrouter/Kconfig: patch does not apply
error: removal patch leaves file contents
error: net/wanrouter/Makefile: patch does not apply
error: removal patch leaves file contents
error: net/wanrouter/patchlevel: patch does not apply
error: removal patch leaves file contents
error: net/wanrouter/wanmain.c: patch does not apply
error: removal patch leaves file contents
error: net/wanrouter/wanproc.c: patch does not apply
error: removal patch leaves file contents
error: drivers/net/wan/cycx_drv.c: patch does not apply
error: removal patch leaves file contents
error: drivers/net/wan/cycx_main.c: patch does not apply
error: removal patch leaves file contents
error: drivers/net/wan/cycx_x25.c: patch does not apply
error: removal patch leaves file contents
error: include/linux/cyclomx.h: patch does not apply
error: removal patch leaves file contents
error: include/linux/cycx_drv.h: patch does not apply
error: removal patch leaves file contents
error: include/linux/wanrouter.h: patch does not apply
error: removal patch leaves file contents
error: include/uapi/linux/wanrouter.h: patch does not apply
^ permalink raw reply
* [PATCH] cpuidle: Measure idle state durations with monotonic clock
From: Julius Werner @ 2012-11-13 21:52 UTC (permalink / raw)
To: linux-kernel
Cc: Kevin Hilman, Deepthi Dharwar, Trinabh Gupta, linux-pm,
Daniel Lezcano, Rafael J. Wysocki, linux-acpi, Srivatsa S. Bhat,
Julius Werner, Andrew Morton, linuxppc-dev, Sameer Nanda,
Len Brown
Many cpuidle drivers measure their time spent in an idle state by
reading the wallclock time before and after idling and calculating the
difference. This leads to erroneous results when the wallclock time gets
updated by another processor in the meantime, adding that clock
adjustment to the idle state's time counter.
If the clock adjustment was negative, the result is even worse due to an
erroneous cast from int to unsigned long long of the last_residency
variable. The negative 32 bit integer will zero-extend and result in a
forward time jump of roughly four billion milliseconds or 1.3 hours on
the idle state residency counter.
This patch changes all affected cpuidle drivers to use the monotonic
clock for their measurements instead. It also removes the erroneous
cast, making sure that negative residency values are applied correctly
even though they should not appear anymore.
Signed-off-by: Julius Werner <jwerner@chromium.org>
---
arch/powerpc/platforms/pseries/processor_idle.c | 4 ++--
drivers/acpi/processor_idle.c | 12 ++++++------
drivers/cpuidle/cpuidle.c | 3 +--
drivers/idle/intel_idle.c | 13 ++++---------
4 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index 45d00e5..4d806b4 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -36,7 +36,7 @@ static struct cpuidle_state *cpuidle_state_table;
static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
{
- *kt_before = ktime_get_real();
+ *kt_before = ktime_get();
*in_purr = mfspr(SPRN_PURR);
/*
* Indicate to the HV that we are idle. Now would be
@@ -50,7 +50,7 @@ static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before)
get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
get_lppaca()->idle = 0;
- return ktime_to_us(ktime_sub(ktime_get_real(), kt_before));
+ return ktime_to_us(ktime_sub(ktime_get(), kt_before));
}
static int snooze_loop(struct cpuidle_device *dev,
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index e8086c7..8c98d73 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -751,9 +751,9 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
lapic_timer_state_broadcast(pr, cx, 1);
- kt1 = ktime_get_real();
+ kt1 = ktime_get();
acpi_idle_do_entry(cx);
- kt2 = ktime_get_real();
+ kt2 = ktime_get();
idle_time = ktime_to_us(ktime_sub(kt2, kt1));
/* Update device last_residency*/
@@ -843,11 +843,11 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
if (cx->type == ACPI_STATE_C3)
ACPI_FLUSH_CPU_CACHE();
- kt1 = ktime_get_real();
+ kt1 = ktime_get();
/* Tell the scheduler that we are going deep-idle: */
sched_clock_idle_sleep_event();
acpi_idle_do_entry(cx);
- kt2 = ktime_get_real();
+ kt2 = ktime_get();
idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
idle_time = idle_time_ns;
do_div(idle_time, NSEC_PER_USEC);
@@ -934,7 +934,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
*/
lapic_timer_state_broadcast(pr, cx, 1);
- kt1 = ktime_get_real();
+ kt1 = ktime_get();
/*
* disable bus master
* bm_check implies we need ARB_DIS
@@ -965,7 +965,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
c3_cpu_count--;
raw_spin_unlock(&c3_lock);
}
- kt2 = ktime_get_real();
+ kt2 = ktime_get();
idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
idle_time = idle_time_ns;
do_div(idle_time, NSEC_PER_USEC);
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 7f15b85..1536edd 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -109,8 +109,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
/* This can be moved to within driver enter routine
* but that results in multiple copies of same code.
*/
- dev->states_usage[entered_state].time +=
- (unsigned long long)dev->last_residency;
+ dev->states_usage[entered_state].time += dev->last_residency;
dev->states_usage[entered_state].usage++;
} else {
dev->last_residency = 0;
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index b0f6b4c..6329a97 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -56,7 +56,7 @@
#include <linux/kernel.h>
#include <linux/cpuidle.h>
#include <linux/clockchips.h>
-#include <linux/hrtimer.h> /* ktime_get_real() */
+#include <linux/hrtimer.h> /* ktime_get() */
#include <trace/events/power.h>
#include <linux/sched.h>
#include <linux/notifier.h>
@@ -281,8 +281,7 @@ static int intel_idle(struct cpuidle_device *dev,
struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage);
unsigned int cstate;
- ktime_t kt_before, kt_after;
- s64 usec_delta;
+ ktime_t kt_before;
int cpu = smp_processor_id();
cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
@@ -297,7 +296,7 @@ static int intel_idle(struct cpuidle_device *dev,
if (!(lapic_timer_reliable_states & (1 << (cstate))))
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
- kt_before = ktime_get_real();
+ kt_before = ktime_get();
stop_critical_timings();
if (!need_resched()) {
@@ -310,17 +309,13 @@ static int intel_idle(struct cpuidle_device *dev,
start_critical_timings();
- kt_after = ktime_get_real();
- usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before));
+ dev->last_residency = ktime_to_us(ktime_sub(ktime_get(), kt_before));
local_irq_enable();
if (!(lapic_timer_reliable_states & (1 << (cstate))))
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
- /* Update cpuidle counters */
- dev->last_residency = (int)usec_delta;
-
return index;
}
--
1.7.8.6
^ permalink raw reply related
* RE: [PATCH 1/1] arch Kconfig: remove references to IRQ_PER_CPU
From: Luck, Tony @ 2012-11-13 21:28 UTC (permalink / raw)
To: James Hogan, linux-kernel@vger.kernel.org
Cc: linux-arch@vger.kernel.org, linux-mips@linux-mips.org,
linux-ia64@vger.kernel.org, linux-parisc@vger.kernel.org,
linux-sh@vger.kernel.org, linux-hexagon@vger.kernel.org,
Helge Deller, James E.J. Bottomley, Yu, Fenghua, Richard Kuo,
Paul Mundt, Mike Frysinger, Ralf Baechle,
uclinux-dist-devel@blackfin.uclinux.org, Thomas Gleixner,
linuxppc-dev@lists.ozlabs.org, Paul Mackerras
In-Reply-To: <1352807948-26920-1-git-send-email-james.hogan@imgtec.com>
> But IRQ_PER_CPU wasn't removed from any of the architecture Kconfig
> files where it was defined or selected. It's completely unused so remove
> the remaining references.
Acked-by: Tony Luck <tony.luck@intel.com>
[Hope someone picks up this whole patch ... otherwise I can take the ia64 h=
unk]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox