* [PATCH 16/16] powerpc/perf/hv-gpci: add the remaining gpci requests
From: Cody P Schafer @ 2014-05-28 0:22 UTC (permalink / raw)
To: LKML, Linux PPC, Cody P Schafer; +Cc: Sukadev Bhattiprolu, Paul Mackerras
In-Reply-To: <1401236684-10579-1-git-send-email-dev@codyps.com>
Add the remaining gpci requests that contain counters suitable for use
by perf. Omit those that don't contain any counters (but note their
ommision).
CC: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: Cody P Schafer <dev@codyps.com>
---
arch/powerpc/perf/hv-gpci-requests.h | 179 +++++++++++++++++++++++++++++++++++
1 file changed, 179 insertions(+)
diff --git a/arch/powerpc/perf/hv-gpci-requests.h b/arch/powerpc/perf/hv-gpci-requests.h
index 0dfc4d9..af3b73c 100644
--- a/arch/powerpc/perf/hv-gpci-requests.h
+++ b/arch/powerpc/perf/hv-gpci-requests.h
@@ -65,6 +65,33 @@ REQUEST(__count(0, 8, processor_time_in_timebase_cycles)
)
#include I(REQUEST_END)
+#define REQUEST_NAME entitled_capped_uncapped_donated_idle_timebase_by_partition
+#define REQUEST_NUM 0x20
+#define REQUEST_IDX_KIND sibling_part_id
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 8, partition_id)
+ __count(0x8, 8, entitled_cycles)
+ __count(0x10, 8, consumed_capped_cycles)
+ __count(0x18, 8, consumed_uncapped_cycles)
+ __count(0x20, 8, cycles_donated)
+ __count(0x28, 8, purr_idle_cycles)
+)
+#include I(REQUEST_END)
+
+/*
+ * Not avaliable for counter_info_version >= 0x8, use
+ * run_instruction_cycles_by_partition(0x100) instead.
+ */
+#define REQUEST_NAME run_instructions_run_cycles_by_partition
+#define REQUEST_NUM 0x30
+#define REQUEST_IDX_KIND sibling_part_id
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 8, partition_id)
+ __count(0x8, 8, instructions_completed)
+ __count(0x10, 8, cycles)
+)
+#include I(REQUEST_END)
+
#define REQUEST_NAME system_performance_capabilities
#define REQUEST_NUM 0x40
#define REQUEST_IDX_KIND M1
@@ -75,5 +102,157 @@ REQUEST(__field(0, 1, perf_collect_privileged)
)
#include I(REQUEST_END)
+#define REQUEST_NAME processor_bus_utilization_abc_links
+#define REQUEST_NUM 0x50
+#define REQUEST_IDX_KIND hw_chip_id
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 4, hw_chip_id)
+ __array(0x4, 0xC, reserved1)
+ __count(0x10, 8, total_link_cycles)
+ __count(0x18, 8, idle_cycles_for_a_link)
+ __count(0x20, 8, idle_cycles_for_b_link)
+ __count(0x28, 8, idle_cycles_for_c_link)
+ __array(0x30, 0x20, reserved2)
+)
+#include I(REQUEST_END)
+
+#define REQUEST_NAME processor_bus_utilization_wxyz_links
+#define REQUEST_NUM 0x60
+#define REQUEST_IDX_KIND hw_chip_id
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 4, hw_chip_id)
+ __array(0x4, 0xC, reserved1)
+ __count(0x10, 8, total_link_cycles)
+ __count(0x18, 8, idle_cycles_for_w_link)
+ __count(0x20, 8, idle_cycles_for_x_link)
+ __count(0x28, 8, idle_cycles_for_y_link)
+ __count(0x30, 8, idle_cycles_for_z_link)
+ __array(0x38, 0x28, reserved2)
+)
+#include I(REQUEST_END)
+
+#define REQUEST_NAME processor_bus_utilization_gx_links
+#define REQUEST_NUM 0x70
+#define REQUEST_IDX_KIND hw_chip_id
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 4, hw_chip_id)
+ __array(0x4, 0xC, reserved1)
+ __count(0x10, 8, gx0_in_address_cycles)
+ __count(0x18, 8, gx0_in_data_cycles)
+ __count(0x20, 8, gx0_in_retries)
+ __count(0x28, 8, gx0_in_bus_cycles)
+ __count(0x30, 8, gx0_in_cycles_total)
+ __count(0x38, 8, gx0_out_address_cycles)
+ __count(0x40, 8, gx0_out_data_cycles)
+ __count(0x48, 8, gx0_out_retries)
+ __count(0x50, 8, gx0_out_bus_cycles)
+ __count(0x58, 8, gx0_out_cycles_total)
+ __count(0x60, 8, gx1_in_address_cycles)
+ __count(0x68, 8, gx1_in_data_cycles)
+ __count(0x70, 8, gx1_in_retries)
+ __count(0x78, 8, gx1_in_bus_cycles)
+ __count(0x80, 8, gx1_in_cycles_total)
+ __count(0x88, 8, gx1_out_address_cycles)
+ __count(0x90, 8, gx1_out_data_cycles)
+ __count(0x98, 8, gx1_out_retries)
+ __count(0xA0, 8, gx1_out_bus_cycles)
+ __count(0xA8, 8, gx1_out_cycles_total)
+)
+#include I(REQUEST_END)
+
+#define REQUEST_NAME processor_bus_utilization_mc_links
+#define REQUEST_NUM 0x80
+#define REQUEST_IDX_KIND hw_chip_id
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 4, hw_chip_id)
+ __array(0x4, 0xC, reserved1)
+ __count(0x10, 8, mc0_frames)
+ __count(0x18, 8, mc0_reads)
+ __count(0x20, 8, mc0_write)
+ __count(0x28, 8, mc0_total_cycles)
+ __count(0x30, 8, mc1_frames)
+ __count(0x38, 8, mc1_reads)
+ __count(0x40, 8, mc1_writes)
+ __count(0x48, 8, mc1_total_cycles)
+)
+#include I(REQUEST_END)
+
+/* Processor_config (0x90) skipped, no counters */
+/* Current_processor_frequency (0x91) skipped, no counters */
+
+#define REQUEST_NAME processor_core_utilization
+#define REQUEST_NUM 0x94
+#define REQUEST_IDX_KIND phys_processor_idx
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 4, phys_processor_idx)
+ __field(0x4, 4, hw_processor_id)
+ __count(0x8, 8, cycles_across_any_thread)
+ __count(0x10, 8, timebase_at_collection)
+ __count(0x18, 8, purr_cycles)
+ __count(0x20, 8, sum_of_cycles_across_all_threads)
+ __count(0x28, 8, instructions_completed)
+)
+#include I(REQUEST_END)
+
+/* Processor_core_power_mode (0x95) skipped, no counters */
+/* Affinity_domain_information_by_virtual_processor (0xA0) skipped, no counters */
+/* Affinity_domain_information_by_domain (0xB0) skipped, no counters */
+/* Affinity_domain_information_by_partition (0xB1) skipped, no counters */
+/* Physical_memory_info (0xC0) skipped, no counters */
+/* Processor_bus_topology (0xD0) skipped, no counters */
+
+#define REQUEST_NAME partition_hypervisor_queuing_times
+#define REQUEST_NUM 0xE0
+#define REQUEST_IDX_KIND partition_id
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 2, partition_id)
+ __array(0x2, 0x6, reserved1)
+ __count(0x8, 8, time_waiting_for_entitlement)
+ __count(0x10, 8, times_waited_for_entitlement)
+ __count(0x18, 8, time_waiting_for_phys_processor)
+ __count(0x20, 8, times_waited_for_phys_processor)
+ __count(0x28, 8, dispatches_on_home_core)
+ __count(0x30, 8, dispatches_on_home_primary_affinity_domain)
+ __count(0x38, 8, dispatches_on_home_secondary_affinity_domain)
+ __count(0x40, 8, dispatches_off_home_secondary_affinity_domain)
+ __count(0x48, 8, dispatches_on_dedicated_processor_donating_cycles)
+)
+#include I(REQUEST_END)
+
+#define REQUEST_NAME system_hypervisor_times
+#define REQUEST_NUM 0xF0
+#define REQUEST_IDX_KIND M1
+#include I(REQUEST_BEGIN)
+REQUEST(__count(0, 8, time_spent_to_dispatch_virtual_processors)
+ __count(0x8, 8, time_spent_processing_virtual_processor_timers)
+ __count(0x10, 8, time_spent_managing_partitions_over_entitlement)
+ __count(0x18, 8, time_spent_on_system_managment)
+)
+#include I(REQUEST_END)
+
+#define REQUEST_NAME system_tlbie_count_and_time
+#define REQUEST_NUM 0xF4
+#define REQUEST_IDX_KIND M1
+#include I(REQUEST_BEGIN)
+REQUEST(__count(0, 8, tlbie_instructions_issued)
+ /* FIXME: The spec says the offset here is 0x10, which I suspect is wrong. */
+ __count(0x8, 8, time_spent_issuing_tlbies)
+)
+#include I(REQUEST_END)
+
+#define REQUEST_NAME partition_instruction_count_and_time
+#define REQUEST_NUM 0x100
+#define REQUEST_IDX_KIND partition_id
+#include I(REQUEST_BEGIN)
+REQUEST(__field(0, 2, partition_id)
+ __array(0x2, 0x6, reserved1)
+ __count(0x8, 8, instructions_performed)
+ __count(0x10, 8, time_collected)
+)
+#include I(REQUEST_END)
+
+/* set_mmcrh (0x80001000) skipped, no counters */
+/* retrieve_hpmcx (0x80002000) skipped, no counters */
+
#undef M1
#include "req-gen/_end.h"
--
1.9.3
^ permalink raw reply related
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Alex Williamson @ 2014-05-28 0:39 UTC (permalink / raw)
To: Alexander Graf; +Cc: aik, Gavin Shan, kvm-ppc, qiudayu, linuxppc-dev
In-Reply-To: <5385166A.5060404@suse.de>
On Wed, 2014-05-28 at 00:49 +0200, Alexander Graf wrote:
> On 27.05.14 20:15, Alex Williamson wrote:
> > On Tue, 2014-05-27 at 18:40 +1000, Gavin Shan wrote:
> >> The patch adds new IOCTL commands for sPAPR VFIO container device
> >> to support EEH functionality for PCI devices, which have been passed
> >> through from host to somebody else via VFIO.
> >>
> >> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
> >> ---
> >> Documentation/vfio.txt | 92 ++++++++++++++++++++++++++++++++++++-
> >> drivers/vfio/pci/Makefile | 1 +
> >> drivers/vfio/pci/vfio_pci.c | 20 +++++---
> >> drivers/vfio/pci/vfio_pci_eeh.c | 46 +++++++++++++++++++
> >> drivers/vfio/pci/vfio_pci_private.h | 5 ++
> >> drivers/vfio/vfio_iommu_spapr_tce.c | 85 ++++++++++++++++++++++++++++++++++
> >> include/uapi/linux/vfio.h | 66 ++++++++++++++++++++++++++
> >> 7 files changed, 308 insertions(+), 7 deletions(-)
> >> create mode 100644 drivers/vfio/pci/vfio_pci_eeh.c
>
> [...]
>
> >> +
> >> + return ret;
> >> +}
> >> +
> >> static long tce_iommu_ioctl(void *iommu_data,
> >> unsigned int cmd, unsigned long arg)
> >> {
> >> @@ -283,6 +363,11 @@ static long tce_iommu_ioctl(void *iommu_data,
> >> tce_iommu_disable(container);
> >> mutex_unlock(&container->lock);
> >> return 0;
> >> + case VFIO_EEH_PE_SET_OPTION:
> >> + case VFIO_EEH_PE_GET_STATE:
> >> + case VFIO_EEH_PE_RESET:
> >> + case VFIO_EEH_PE_CONFIGURE:
> >> + return tce_iommu_eeh_ioctl(iommu_data, cmd, arg);
> > This is where it would have really made sense to have a single
> > VFIO_EEH_OP ioctl with a data structure passed to indicate the sub-op.
> > AlexG, are you really attached to splitting these out into separate
> > ioctls?
>
> I don't see the problem. We need to forward 4 ioctls to a separate piece
> of code, so we forward 4 ioctls to a separate piece of code :). Putting
> them into one ioctl just moves the switch() into another function.
And uses an extra 3 ioctl numbers and gives us extra things to update if
we ever need to add more ioctls, etc. ioctl numbers are an address
space, how much address space do we really want to give to EEH? It's
not a big difference, but I don't think it's completely even either.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Alexander Graf @ 2014-05-28 0:44 UTC (permalink / raw)
To: Alex Williamson; +Cc: aik, Gavin Shan, kvm-ppc, qiudayu, linuxppc-dev
In-Reply-To: <1401237575.3289.676.camel@ul30vt.home>
On 28.05.14 02:39, Alex Williamson wrote:
> On Wed, 2014-05-28 at 00:49 +0200, Alexander Graf wrote:
>> On 27.05.14 20:15, Alex Williamson wrote:
>>> On Tue, 2014-05-27 at 18:40 +1000, Gavin Shan wrote:
>>>> The patch adds new IOCTL commands for sPAPR VFIO container device
>>>> to support EEH functionality for PCI devices, which have been passed
>>>> through from host to somebody else via VFIO.
>>>>
>>>> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>>>> ---
>>>> Documentation/vfio.txt | 92 ++++++++++++++++++++++++++++++++++++-
>>>> drivers/vfio/pci/Makefile | 1 +
>>>> drivers/vfio/pci/vfio_pci.c | 20 +++++---
>>>> drivers/vfio/pci/vfio_pci_eeh.c | 46 +++++++++++++++++++
>>>> drivers/vfio/pci/vfio_pci_private.h | 5 ++
>>>> drivers/vfio/vfio_iommu_spapr_tce.c | 85 ++++++++++++++++++++++++++++++++++
>>>> include/uapi/linux/vfio.h | 66 ++++++++++++++++++++++++++
>>>> 7 files changed, 308 insertions(+), 7 deletions(-)
>>>> create mode 100644 drivers/vfio/pci/vfio_pci_eeh.c
>> [...]
>>
>>>> +
>>>> + return ret;
>>>> +}
>>>> +
>>>> static long tce_iommu_ioctl(void *iommu_data,
>>>> unsigned int cmd, unsigned long arg)
>>>> {
>>>> @@ -283,6 +363,11 @@ static long tce_iommu_ioctl(void *iommu_data,
>>>> tce_iommu_disable(container);
>>>> mutex_unlock(&container->lock);
>>>> return 0;
>>>> + case VFIO_EEH_PE_SET_OPTION:
>>>> + case VFIO_EEH_PE_GET_STATE:
>>>> + case VFIO_EEH_PE_RESET:
>>>> + case VFIO_EEH_PE_CONFIGURE:
>>>> + return tce_iommu_eeh_ioctl(iommu_data, cmd, arg);
>>> This is where it would have really made sense to have a single
>>> VFIO_EEH_OP ioctl with a data structure passed to indicate the sub-op.
>>> AlexG, are you really attached to splitting these out into separate
>>> ioctls?
>> I don't see the problem. We need to forward 4 ioctls to a separate piece
>> of code, so we forward 4 ioctls to a separate piece of code :). Putting
>> them into one ioctl just moves the switch() into another function.
> And uses an extra 3 ioctl numbers and gives us extra things to update if
> we ever need to add more ioctls, etc. ioctl numbers are an address
> space, how much address space do we really want to give to EEH? It's
> not a big difference, but I don't think it's completely even either.
> Thanks,
Yes, that's the point. I by far prefer to have you push back on anyone
who introduces useless ioctls rather than have a separate EEH number
space that people can just throw anything in they like ;).
Alex
^ permalink raw reply
* Re: [PATCH 11/16] byteorder: provide a linux/byteorder.h with {be,le}_to_cpu() and cpu_to_{be,le}() macros
From: Joe Perches @ 2014-05-28 0:44 UTC (permalink / raw)
To: Cody P Schafer; +Cc: Sukadev Bhattiprolu, Linux PPC, LKML
In-Reply-To: <1401236684-10579-12-git-send-email-dev@codyps.com>
On Tue, 2014-05-27 at 17:22 -0700, Cody P Schafer wrote:
> Rather manually specifying the size of the integer to be converted, key
> off of the type size. Reduces duplicate size info and the occurance of
> certain types of bugs (using the wrong sized conversion).
[]
> diff --git a/include/linux/byteorder.h b/include/linux/byteorder.h
[]
> @@ -0,0 +1,34 @@
> +#ifndef LINUX_BYTEORDER_H_
> +#define LINUX_BYTEORDER_H_
> +
> +#include <asm/byteorder.h>
> +
> +#define be_to_cpu(v) \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint8_t) , v, \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint16_t), be16_to_cpu(v), \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint32_t), be32_to_cpu(v), \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint64_t), be64_to_cpu(v), \
> + (void)0))))
probably better to use BUILD_BUG instead of these 0 returns
> +
> +#define le_to_cpu(v) \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint8_t) , v, \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint16_t), le16_to_cpu(v), \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint32_t), le32_to_cpu(v), \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint64_t), le64_to_cpu(v), \
> + (void)0))))
> +
> +#define cpu_to_le(v) \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint8_t) , v, \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint16_t), cpu_to_le16(v), \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint32_t), cpu_to_le32(v), \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint64_t), cpu_to_le64(v), \
> + (void)0))))
> +
> +#define cpu_to_be(v) \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint8_t) , v, \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint16_t), cpu_to_be16(v), \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint32_t), cpu_to_be32(v), \
> + __builtin_choose_expr(sizeof(v) == sizeof(uint64_t), cpu_to_be64(v), \
> + (void)0))))
> +
> +#endif
^ permalink raw reply
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Gavin Shan @ 2014-05-28 0:55 UTC (permalink / raw)
To: Alex Williamson; +Cc: aik, Gavin Shan, kvm-ppc, agraf, qiudayu, linuxppc-dev
In-Reply-To: <1401214527.3289.611.camel@ul30vt.home>
On Tue, May 27, 2014 at 12:15:27PM -0600, Alex Williamson wrote:
>On Tue, 2014-05-27 at 18:40 +1000, Gavin Shan wrote:
>> The patch adds new IOCTL commands for sPAPR VFIO container device
>> to support EEH functionality for PCI devices, which have been passed
>> through from host to somebody else via VFIO.
>>
>> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>> ---
>> Documentation/vfio.txt | 92 ++++++++++++++++++++++++++++++++++++-
>> drivers/vfio/pci/Makefile | 1 +
>> drivers/vfio/pci/vfio_pci.c | 20 +++++---
>> drivers/vfio/pci/vfio_pci_eeh.c | 46 +++++++++++++++++++
>> drivers/vfio/pci/vfio_pci_private.h | 5 ++
>> drivers/vfio/vfio_iommu_spapr_tce.c | 85 ++++++++++++++++++++++++++++++++++
>> include/uapi/linux/vfio.h | 66 ++++++++++++++++++++++++++
>> 7 files changed, 308 insertions(+), 7 deletions(-)
>> create mode 100644 drivers/vfio/pci/vfio_pci_eeh.c
>>
>> diff --git a/Documentation/vfio.txt b/Documentation/vfio.txt
>> index b9ca023..d890fed 100644
>> --- a/Documentation/vfio.txt
>> +++ b/Documentation/vfio.txt
>> @@ -305,7 +305,15 @@ faster, the map/unmap handling has been implemented in real mode which provides
>> an excellent performance which has limitations such as inability to do
>> locked pages accounting in real time.
>>
>> -So 3 additional ioctls have been added:
>> +4) According to sPAPR specification, A Partitionable Endpoint (PE) is an I/O
>> +subtree that can be treated as a unit for the purposes of partitioning and
>> +error recovery. A PE may be a single or multi-function IOA (IO Adapter), a
>> +function of a multi-function IOA, or multiple IOAs (possibly including switch
>> +and bridge structures above the multiple IOAs). PPC64 guests detect PCI errors
>> +and recover from them via EEH RTAS services, which works on the basis of
>> +additional ioctl commands.
>> +
>> +So 7 additional ioctls have been added:
>>
>> VFIO_IOMMU_SPAPR_TCE_GET_INFO - returns the size and the start
>> of the DMA window on the PCI bus.
>> @@ -316,6 +324,17 @@ So 3 additional ioctls have been added:
>>
>> VFIO_IOMMU_DISABLE - disables the container.
>>
>> + VFIO_EEH_PE_SET_OPTION - enables or disables EEH functionality on the
>> + specified device. Also, it can be used to remove IO or DMA
>> + stopped state on the frozen PE.
>> +
>> + VFIO_EEH_PE_GET_STATE - retrieve PE's state: frozen or normal state.
>> +
>> + VFIO_EEH_PE_RESET - do PE reset, which is one of the major steps for
>> + error recovering.
>> +
>> + VFIO_EEH_PE_CONFIGURE - configure the PCI bridges after PE reset. It's
>> + one of the major steps for error recoverying.
>>
>> The code flow from the example above should be slightly changed:
>>
>> @@ -346,6 +365,77 @@ The code flow from the example above should be slightly changed:
>> ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
>> .....
>>
>> +Based on the initial example we have, the following piece of code could be
>> +reference for EEH setup and error handling:
>> +
>> + struct vfio_eeh_pe_set_option option = { .argsz = sizeof(option) };
>> + struct vfio_eeh_pe_get_state state = { .argsz = sizeof(state) };
>> + struct vfio_eeh_pe_reset reset = { .argsz = sizeof(reset) };
>> + struct vfio_eeh_pe_configure configure = { .argsz = sizeof(configure) };
>> +
>> + ....
>> +
>> + /* Get a file descriptor for the device */
>> + device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:06:0d.0");
>> +
>> + /* Enable the EEH functionality on the device */
>> + option.option = VFIO_EEH_PE_SET_OPT_ENABLE;
>> + ioctl(container, VFIO_EEH_PE_SET_OPTION, &option);
>> +
>> + /* You're suggested to create additional data struct to represent
>> + * PE, and put child devices belonging to same IOMMU group to the
>> + * PE instance for later reference.
>> + */
>> +
>> + /* Check the PE's state and make sure it's in functional state */
>> + ioctl(container, VFIO_EEH_PE_GET_STATE, &state);
>> +
>> + /* Save device's state. pci_save_state() would be good enough
>> + * as an example.
>> + */
>> +
>> + /* Test and setup the device */
>> + ioctl(device, VFIO_DEVICE_GET_INFO, &device_info);
>> +
>> + ....
>> +
>> + /* When 0xFF's returned from reading PCI config space or IO BARs
>> + * of the PCI device. Check the PE state to see if that has been
>> + * frozen.
>> + */
>> + ioctl(container, VFIO_EEH_PE_GET_STATE, &state);
>> +
>> + /* Waiting for pending PCI transactions to be completed and don't
>> + * produce any more PCI traffic from/to the affected PE until
>> + * recovery is finished.
>> + */
>> +
>> + /* Enable IO for the affected PE and collect logs. Usually, the
>> + * standard part of PCI config space, AER registers are dumped
>> + * as logs for further analysis.
>> + */
>> + option.option = VFIO_EEH_PE_SET_OPT_IO;
>> + ioctl(container, VFIO_EEH_PE_SET_OPTION, &option);
>> +
>> + /* Issue PE reset */
>> + reset.option = VFIO_EEH_PE_RESET_HOT;
>> + ioctl(container, VFIO_EEH_PE_RESET, &reset);
>> + reset.option = VFIO_EEH_PE_RESET_DEACTIVATE;
>> + ioctl(container, VFIO_EEH_PE_RESET, &reset);
>> +
>> + /* Configure the PCI bridges for the affected PE */
>> + ioctl(container, VFIO_EEH_PE_CONFIGURE, &configure);
>> +
>> + /* Restored state we saved at initialization time. pci_restore_state()
>> + * is good enough as an example.
>> + */
>> +
>> + /* Hopefully, error is recovered successfully. Now, you can resume to
>> + * start PCI traffic to/from the affected PE.
>> + */
>> +
>> + ....
>> +
>> -------------------------------------------------------------------------------
>>
>> [1] VFIO was originally an acronym for "Virtual Function I/O" in its
>> diff --git a/drivers/vfio/pci/Makefile b/drivers/vfio/pci/Makefile
>> index 1310792..faad885 100644
>> --- a/drivers/vfio/pci/Makefile
>> +++ b/drivers/vfio/pci/Makefile
>> @@ -1,4 +1,5 @@
>>
>> vfio-pci-y := vfio_pci.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o
>> +vfio-pci-y += vfio_pci_eeh.o
>
>Why do we build this w/o CONFIG_EEH? Can't we define the functions as
>static inline in the header in that case?
>
Ok. Will do in next revision.
>> obj-$(CONFIG_VFIO_PCI) += vfio-pci.o
>> diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
>> index 7ba0424..7c8d26a 100644
>> --- a/drivers/vfio/pci/vfio_pci.c
>> +++ b/drivers/vfio/pci/vfio_pci.c
>> @@ -156,8 +156,10 @@ static void vfio_pci_release(void *device_data)
>> {
>> struct vfio_pci_device *vdev = device_data;
>>
>> - if (atomic_dec_and_test(&vdev->refcnt))
>> + if (atomic_dec_and_test(&vdev->refcnt)) {
>> + vfio_pci_eeh_release(vdev->pdev);
>> vfio_pci_disable(vdev);
>> + }
>>
>> module_put(THIS_MODULE);
>> }
>> @@ -165,19 +167,25 @@ static void vfio_pci_release(void *device_data)
>> static int vfio_pci_open(void *device_data)
>> {
>> struct vfio_pci_device *vdev = device_data;
>> + int ret;
>>
>> if (!try_module_get(THIS_MODULE))
>> return -ENODEV;
>>
>> if (atomic_inc_return(&vdev->refcnt) == 1) {
>> - int ret = vfio_pci_enable(vdev);
>> - if (ret) {
>> - module_put(THIS_MODULE);
>> - return ret;
>> - }
>> + ret = vfio_pci_enable(vdev);
>> + if (ret)
>> + goto error;
>> +
>> + ret = vfio_pci_eeh_open(vdev->pdev);
>> + if (ret)
>> + goto error;
>> }
>>
>> return 0;
>> +error:
>> + module_put(THIS_MODULE);
>> + return ret;
>> }
>>
>> static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type)
>> diff --git a/drivers/vfio/pci/vfio_pci_eeh.c b/drivers/vfio/pci/vfio_pci_eeh.c
>> new file mode 100644
>> index 0000000..9c25207
>> --- /dev/null
>> +++ b/drivers/vfio/pci/vfio_pci_eeh.c
>> @@ -0,0 +1,46 @@
>> +/*
>> + * EEH functionality support for VFIO PCI devices.
>> + *
>> + * Copyright Gavin Shan, IBM Corporation 2014.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/device.h>
>> +#include <linux/eventfd.h>
>> +#include <linux/file.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/iommu.h>
>> +#include <linux/module.h>
>> +#include <linux/mutex.h>
>> +#include <linux/notifier.h>
>> +#include <linux/pci.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/slab.h>
>> +#include <linux/types.h>
>> +#include <linux/uaccess.h>
>> +#include <linux/vfio.h>
>
>Cleanup the includes
>
Ok. Will do in next revision.
>> +#ifdef CONFIG_EEH
>> +#include <asm/eeh.h>
>> +#endif
>
>This shouldn't even be compiles w/o CONFIG_EEH
>
Yeah. Will fix in next revision as you suggested.
>> +
>> +#include "vfio_pci_private.h"
>> +
>> +int vfio_pci_eeh_open(struct pci_dev *pdev)
>> +{
>> + int ret = 0;
>> +
>> +#ifdef CONFIG_EEH
>> + ret = eeh_dev_open(pdev);
>> +#endif
>> + return ret;
>> +}
>> +
>> +void vfio_pci_eeh_release(struct pci_dev *pdev)
>> +{
>> +#ifdef CONFIG_EEH
>> + eeh_dev_release(pdev);
>> +#endif
>> +}
>> diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h
>> index 9c6d5d0..c3cbe40 100644
>> --- a/drivers/vfio/pci/vfio_pci_private.h
>> +++ b/drivers/vfio/pci/vfio_pci_private.h
>> @@ -90,4 +90,9 @@ extern void vfio_pci_virqfd_exit(void);
>>
>> extern int vfio_config_init(struct vfio_pci_device *vdev);
>> extern void vfio_config_free(struct vfio_pci_device *vdev);
>> +
>> +/* EEH stub */
>> +extern int vfio_pci_eeh_open(struct pci_dev *pdev);
>> +extern void vfio_pci_eeh_release(struct pci_dev *pdev);
>
>The #ifdef with static inlines should be here.
>
thanks for the detailed comments.
>> +
>> #endif /* VFIO_PCI_PRIVATE_H */
>> diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
>> index a84788b..666691b 100644
>> --- a/drivers/vfio/vfio_iommu_spapr_tce.c
>> +++ b/drivers/vfio/vfio_iommu_spapr_tce.c
>> @@ -21,6 +21,9 @@
>> #include <linux/vfio.h>
>> #include <asm/iommu.h>
>> #include <asm/tce.h>
>> +#ifdef CONFIG_EEH
>> +#include <asm/eeh.h>
>> +#endif
>
>Now we're infecting another file with EEH, can't we put it in a central
>location for vfio?
How about something like this:
- Create drivers/vfio/vfio_eeh.c and it will be built when having CONFIG_EEH
- Declare all EEH functions in include/linux/vfio.h (it's the only central
header file I can find except you have a better one).
#ifdef CONFIG_EEH
extern int vfio_pci_eeh_open(struct pci_dev *pdev);
extern void vfio_pci_eeh_release(struct pci_dev *pdev);
extern long vfio_iommu_spapr_eeh_ioctl(struct iommu_table *tbl,
unsigned int cmd, unsigned long arg);
#else
static int vfio_pci_eeh_open(struct pci_dev *pdev)
{
return 0;
}
static void vfio_pci_eeh_release(struct pci_dev *pdev)
{
}
static inline vfio_iommu_spapr_eeh_ioctl(struct iommu_table *tbl,
unsigned int cmd, unsigned long arg);
{
return -ENOTTY;
}
#endif
>>
>> #define DRIVER_VERSION "0.1"
>> #define DRIVER_AUTHOR "aik@ozlabs.ru"
>> @@ -147,6 +150,83 @@ static void tce_iommu_release(void *iommu_data)
>> kfree(container);
>> }
>>
>> +static long tce_iommu_eeh_ioctl(void *iommu_data,
>> + unsigned int cmd, unsigned long arg)
>> +{
>> + struct tce_container *container = iommu_data;
>> + unsigned long minsz;
>> + int ret = 0;
>> +
>> +#ifdef CONFIG_EEH
>> + switch (cmd) {
>> + case VFIO_EEH_PE_SET_OPTION: {
>> + struct vfio_eeh_pe_set_option option;
>> +
>> + minsz = offsetofend(struct vfio_eeh_pe_set_option, option);
>> + if (copy_from_user(&option, (void __user *)arg, minsz))
>> + return -EFAULT;
>> + if (option.argsz < minsz)
>> + return -EINVAL;
>> +
>> + ret = eeh_pe_set_option(eeh_iommu_table_to_pe(container->tbl),
>> + option.option);
>> + break;
>> + }
>> + case VFIO_EEH_PE_GET_STATE: {
>> + struct vfio_eeh_pe_get_state state;
>> +
>> + minsz = offsetofend(struct vfio_eeh_pe_get_state, state);
>> + if (copy_from_user(&state, (void __user *)arg, minsz))
>> + return -EFAULT;
>> + if (state.argsz < minsz)
>> + return -EINVAL;
>> +
>> + ret = eeh_pe_get_state(eeh_iommu_table_to_pe(container->tbl));
>> + if (ret >= 0) {
>> + state.state = ret;
>> + if (copy_to_user((void __user *)arg, &state, minsz))
>> + return -EFAULT;
>> + ret = 0;
>> + }
>
>This looks like one of those cases where you should just use the ioctl
>return value.
>
Ok. I'll use ioctl return value to carry output information. Note it might
have "0" as the output information.
>> + break;
>> + }
>> + case VFIO_EEH_PE_RESET: {
>> + struct vfio_eeh_pe_reset reset;
>> +
>> + minsz = offsetofend(struct vfio_eeh_pe_reset, option);
>> + if (copy_from_user(&reset, (void __user *)arg, minsz))
>> + return -EFAULT;
>> + if (reset.argsz < minsz)
>> + return -EINVAL;
>> +
>> + ret = eeh_pe_reset(eeh_iommu_table_to_pe(container->tbl),
>> + reset.option);
>> + break;
>> + }
>> + case VFIO_EEH_PE_CONFIGURE: {
>> + struct vfio_eeh_pe_configure configure;
>> +
>> + minsz = offsetofend(struct vfio_eeh_pe_configure, flags);
>> + if (copy_from_user(&configure, (void __user *)arg, minsz))
>> + return -EFAULT;
>> + if (configure.argsz < minsz)
>> + return -EINVAL;
>> +
>> + ret = eeh_pe_configure(eeh_iommu_table_to_pe(container->tbl));
>> + break;
>> + }
>> + default:
>> + ret = -EINVAL;
>> + pr_debug("%s: Cannot handle command %d\n",
>> + __func__, cmd);
>> + }
>> +#else
>> + ret = -ENOENT;
>> +#endif
>
>Hmm, more like a BUG in the default case the way it's coded here (not
>even sure it's worth the default entry). The #else case should probably
>be -ENOTTY like other unimplemented ioctls.
>
Yeah, we don't need default case here and I'll remove it in next revision.
Also, "-ENOTTY" will be used in future for unimplemented functions.
>> +
>> + return ret;
>> +}
>> +
>> static long tce_iommu_ioctl(void *iommu_data,
>> unsigned int cmd, unsigned long arg)
>> {
>> @@ -283,6 +363,11 @@ static long tce_iommu_ioctl(void *iommu_data,
>> tce_iommu_disable(container);
>> mutex_unlock(&container->lock);
>> return 0;
>> + case VFIO_EEH_PE_SET_OPTION:
>> + case VFIO_EEH_PE_GET_STATE:
>> + case VFIO_EEH_PE_RESET:
>> + case VFIO_EEH_PE_CONFIGURE:
>> + return tce_iommu_eeh_ioctl(iommu_data, cmd, arg);
>
>This is where it would have really made sense to have a single
>VFIO_EEH_OP ioctl with a data structure passed to indicate the sub-op.
>AlexG, are you really attached to splitting these out into separate
>ioctls?
>
I really don't know. Alex.G want separate ioctl commands, but you
suggested to combine them. Could you guys please just tell me which
one (separate vs combined) I need to have in next revision? :-)
>> }
>>
>> return -ENOTTY;
>> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
>> index cb9023d..c5fac36 100644
>> --- a/include/uapi/linux/vfio.h
>> +++ b/include/uapi/linux/vfio.h
>> @@ -455,6 +455,72 @@ struct vfio_iommu_spapr_tce_info {
>>
>> #define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
>>
>> +/*
>> + * EEH functionality can be enabled or disabled on one specific device.
>> + * Also, the DMA or IO frozen state can be removed from the frozen PE
>> + * if required.
>> + */
>> +struct vfio_eeh_pe_set_option {
>> + __u32 argsz;
>> + __u32 flags;
>> + __u32 option;
>> +#define VFIO_EEH_PE_SET_OPT_DISABLE 0 /* Disable EEH */
>> +#define VFIO_EEH_PE_SET_OPT_ENABLE 1 /* Enable EEH */
>> +#define VFIO_EEH_PE_SET_OPT_IO 2 /* Enable IO */
>> +#define VFIO_EEH_PE_SET_OPT_DMA 3 /* Enable DMA */
>
>This is more of a "command" than an "option" isn't it? Each of these
>probably needs a more significant description.
>
Yeah, it would be regarded as "opcode" and I'll add more description about
them in next revision.
>> +};
>> +
>> +#define VFIO_EEH_PE_SET_OPTION _IO(VFIO_TYPE, VFIO_BASE + 21)
>> +
>> +/*
>> + * Each EEH PE should have unique address to be identified. PE's
>> + * sharing mode is also useful information as well.
>> + */
>> +#define VFIO_EEH_PE_GET_ADDRESS 0 /* Get address */
>> +#define VFIO_EEH_PE_GET_MODE 1 /* Query mode */
>> +#define VFIO_EEH_PE_MODE_NONE 0 /* Not a PE */
>> +#define VFIO_EEH_PE_MODE_NOT_SHARED 1 /* Exclusive */
>> +#define VFIO_EEH_PE_MODE_SHARED 2 /* Shared mode */
>> +
>> +/*
>> + * EEH PE might have been frozen because of PCI errors. Also, it might
>> + * be experiencing reset for error revoery. The following command helps
>> + * to get the state.
>> + */
>> +struct vfio_eeh_pe_get_state {
>> + __u32 argsz;
>> + __u32 flags;
>> + __u32 state;
>> +};
>
>Should state be a union to better describe the value returned? What
>exactly is the address and why does the user need to know it? Does this
>need user input or could we just return the address and mode regardless?
>
Ok. I think you want enum (not union) for state. I'll have macros for the
state in next revision as I did that for other cases.
Those macros defined for "address" just for ABI stuff as Alex.G mentioned.
There isn't corresponding ioctl command for host to get address any more
because QEMU (user) will have to figure it out by himself. The "address"
here means PE address and user has to figure it out according to PE
segmentation.
>> +
>> +#define VFIO_EEH_PE_GET_STATE _IO(VFIO_TYPE, VFIO_BASE + 22)
>> +
>> +/*
>> + * Reset is the major step to recover problematic PE. The following
>> + * command helps on that.
>> + */
>> +struct vfio_eeh_pe_reset {
>> + __u32 argsz;
>> + __u32 flags;
>> + __u32 option;
>> +#define VFIO_EEH_PE_RESET_DEACTIVATE 0 /* Deactivate reset */
>> +#define VFIO_EEH_PE_RESET_HOT 1 /* Hot reset */
>> +#define VFIO_EEH_PE_RESET_FUNDAMENTAL 3 /* Fundamental reset */
>
>How does a user know which of these to use?
>
I think Ben already helped explaining it for a lot in the subsequent
replies. Thanks to Ben :-)
>> +};
>> +
>> +#define VFIO_EEH_PE_RESET _IO(VFIO_TYPE, VFIO_BASE + 23)
>> +
>> +/*
>> + * One of the steps for recovery after PE reset is to configure the
>> + * PCI bridges affected by the PE reset.
>> + */
>> +struct vfio_eeh_pe_configure {
>> + __u32 argsz;
>> + __u32 flags;
>> +};
>
>Parameters are probably not necessary here.
>
Yep. I'll remove it in next revision. Thanks for your comments, Alex.
>> +
>> +#define VFIO_EEH_PE_CONFIGURE _IO(VFIO_TYPE, VFIO_BASE + 24)
>> +
>> /* ***************************************************************** */
>>
>> #endif /* _UAPIVFIO_H */
>
>How does a user learn that a device supports EEH? Do they just start
>making ioctl calls and getting a failure? Shouldn't we make use of one
>of the flag bits on the device or add a capability on the container for
>the user to query?
>
User needs to make some ioctl calls to make sure EEH can be supported on
one specific device:
struct vfio_eeh_pe_set_option set_option;
/* User have to make sure the device isn't a bridge and there
* has one PE for it, which means that case of VFIO_EEH_PE_MODE_NONE.
*/
set_option.argsz = sizeof(set_option);
set_option.option = VFIO_EEH_PE_SET_OPT_ENABLE;
ret = ioctl(container, VFIO_EEH_PE_SET_OPTION, &set_option);
if (ret < 0) {
/* EEH can't supported */
}
Thanks,
Gavin
^ permalink raw reply
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Alex Williamson @ 2014-05-28 0:57 UTC (permalink / raw)
To: Alexander Graf; +Cc: aik, Gavin Shan, kvm-ppc, qiudayu, linuxppc-dev
In-Reply-To: <53853155.60809@suse.de>
On Wed, 2014-05-28 at 02:44 +0200, Alexander Graf wrote:
> On 28.05.14 02:39, Alex Williamson wrote:
> > On Wed, 2014-05-28 at 00:49 +0200, Alexander Graf wrote:
> >> On 27.05.14 20:15, Alex Williamson wrote:
> >>> On Tue, 2014-05-27 at 18:40 +1000, Gavin Shan wrote:
> >>>> The patch adds new IOCTL commands for sPAPR VFIO container device
> >>>> to support EEH functionality for PCI devices, which have been passed
> >>>> through from host to somebody else via VFIO.
> >>>>
> >>>> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
> >>>> ---
> >>>> Documentation/vfio.txt | 92 ++++++++++++++++++++++++++++++++++++-
> >>>> drivers/vfio/pci/Makefile | 1 +
> >>>> drivers/vfio/pci/vfio_pci.c | 20 +++++---
> >>>> drivers/vfio/pci/vfio_pci_eeh.c | 46 +++++++++++++++++++
> >>>> drivers/vfio/pci/vfio_pci_private.h | 5 ++
> >>>> drivers/vfio/vfio_iommu_spapr_tce.c | 85 ++++++++++++++++++++++++++++++++++
> >>>> include/uapi/linux/vfio.h | 66 ++++++++++++++++++++++++++
> >>>> 7 files changed, 308 insertions(+), 7 deletions(-)
> >>>> create mode 100644 drivers/vfio/pci/vfio_pci_eeh.c
> >> [...]
> >>
> >>>> +
> >>>> + return ret;
> >>>> +}
> >>>> +
> >>>> static long tce_iommu_ioctl(void *iommu_data,
> >>>> unsigned int cmd, unsigned long arg)
> >>>> {
> >>>> @@ -283,6 +363,11 @@ static long tce_iommu_ioctl(void *iommu_data,
> >>>> tce_iommu_disable(container);
> >>>> mutex_unlock(&container->lock);
> >>>> return 0;
> >>>> + case VFIO_EEH_PE_SET_OPTION:
> >>>> + case VFIO_EEH_PE_GET_STATE:
> >>>> + case VFIO_EEH_PE_RESET:
> >>>> + case VFIO_EEH_PE_CONFIGURE:
> >>>> + return tce_iommu_eeh_ioctl(iommu_data, cmd, arg);
> >>> This is where it would have really made sense to have a single
> >>> VFIO_EEH_OP ioctl with a data structure passed to indicate the sub-op.
> >>> AlexG, are you really attached to splitting these out into separate
> >>> ioctls?
> >> I don't see the problem. We need to forward 4 ioctls to a separate piece
> >> of code, so we forward 4 ioctls to a separate piece of code :). Putting
> >> them into one ioctl just moves the switch() into another function.
> > And uses an extra 3 ioctl numbers and gives us extra things to update if
> > we ever need to add more ioctls, etc. ioctl numbers are an address
> > space, how much address space do we really want to give to EEH? It's
> > not a big difference, but I don't think it's completely even either.
> > Thanks,
>
> Yes, that's the point. I by far prefer to have you push back on anyone
> who introduces useless ioctls rather than have a separate EEH number
> space that people can just throw anything in they like ;).
Well, I appreciate that, but having them as separate ioctls doesn't
really prevent that either. Any one of these 4 could be set to take a
sub-option to extend and contort the EEH interface. The only way to
prevent that would be to avoid the argsz+flags hack that make the ioctl
extendable. Thanks,
Alex
^ permalink raw reply
* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2014-05-28 3:29 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list
Hi Linus !
Here's a pair of powerpc fixes for 3.15 which are also going to stable.
One's a fix for building with newer binutils (the problem currently only
affects the BookE kernels but the affected macro might come back into
use on BookS platforms at any time). Unfortunately, the binutils maintainer
did a backward incompatible change to a construct that we use so we have
to add Makefile check.
The other one is a fix for CPUs getting stuck in kexec when running single
threaded. Since we routinely use kexec on power (including in our newer
bootloaders), I deemed that important enough.
Cheers,
Ben.
The following changes since commit 8050936caf125fbe54111ba5e696b68a360556ba:
powerpc: irq work racing with timer interrupt can result in timer interrupt hang (2014-05-12 14:29:28 +1000)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge
for you to fetch changes up to 011e4b02f1da156ac7fea28a9da878f3c23af739:
powerpc, kexec: Fix "Processor X is stuck" issue during kexec from ST mode (2014-05-28 13:24:26 +1000)
----------------------------------------------------------------
Guenter Roeck (1):
powerpc: Fix 64 bit builds with binutils 2.24
Srivatsa S. Bhat (1):
powerpc, kexec: Fix "Processor X is stuck" issue during kexec from ST mode
arch/powerpc/Makefile | 4 +++-
arch/powerpc/include/asm/ppc_asm.h | 7 ++++++-
arch/powerpc/kernel/machine_kexec_64.c | 2 +-
kernel/kexec.c | 8 ++++++++
4 files changed, 18 insertions(+), 3 deletions(-)
^ permalink raw reply
* Re: Kernel 3.15: Boot problems with a PA6T board
From: Michael Ellerman @ 2014-05-28 4:23 UTC (permalink / raw)
To: Christian Zigotzky; +Cc: linuxppc-dev
In-Reply-To: <53851AFA.5040504@xenosoft.de>
On Wed, 2014-05-28 at 01:08 +0200, Christian Zigotzky wrote:
> Hi Michael,
>
> Thanks a lot for your answer.
>
> ...
>
> 18a1a7a1d862ae0794a0179473d08a414dd49234 <- It doesn't boot. Error messages: Oops: Machine check, sig: 7 [#1] CPU: 1 PID: 1 Comm: swapper/0 not tainted
> d8ff9cdf68fd119d491f3de90e1a612afc2f3b2b <- It boots. :-)
> 0f5a869600141a0d5575e3190af01a050c081b07 <- It boots. :-)
> c7e64b9ce04aa2e3fad7396d92b5cb92056d16ac <- It boots. :-)
> d3e144532703fe2454b56eddb56f30d2d620187b <- It boots. :-)
>
> I think the machine check is the problem.
Yes I think it is. Do you get any more info, or just that one line?
So I think the latest working commit we have is d8ff9cdf68fd119d491f3de90e1a612afc2f3b2b.
I'm going to guess that cd427485357c0c4b99f69719251baacf25946e11 is BAD. Can
you please confirm or deny that?
Assuming cd42748 is bad, you should do a git bisect between it and 18a1a7a.
That should be a fairly quick bisect. That would be:
$ git bisect start
$ git bisect good d8ff9cdf68fd119d491f3de90e1a612afc2f3b2b
$ git bisect bad cd427485357c0c4b99f69719251baacf25946e11
If cd42748 is *good*, then you'll need to do a bigger bisect from d8ff9cd to
18a1a7a.
cheers
^ permalink raw reply
* [PATCH 0/6] ppc, kvm, cpuidle: Allow offline and kvm standby threads to enter fastsleep
From: Preeti U Murthy @ 2014-05-28 4:38 UTC (permalink / raw)
To: benh, linux-kernel, svaidyan, paulus, srivatsa.bhat, linuxppc-dev
Fast sleep is a deep idle state on Power8. The support for the state was
added in commit 0d94873011. Today the idle threads in the host can
potentially be put to fast sleep. But when we launch guests using kvm,
the secondary threads are required to be offline and the offline threads
are put to nap. Besides this case, when secondary threads are woken up
to run guests and eventually go idle or when the guest is killed, they
enter nap. So when the entire core goes idle in both the above scenarios,
the maximum power savings that we can obtain is as much as we can get from
napping the cpus. This patchset adds support in the above two cases
for the threads to enter fast sleep.
---
Srivatsa S. Bhat (6):
powernv, cpuidle: Move the flags used for idle state discovery to powernv core
powerpc, powernv, CPU hotplug: Put offline CPUs in Fast-Sleep instead of Nap
KVM: PPC: Book3S HV: Enable CPUs to run guest after waking up from fast-sleep
KVM: PPC: Book3S HV: Consolidate the idle-state enter sequence in KVM
KVM: PPC: Book3S HV: Put KVM standby hwthreads to fast-sleep instead of nap
ppc,book3s: Go back to same idle state after handling machine check interrupt
arch/powerpc/include/asm/processor.h | 12 ++++
arch/powerpc/kernel/exceptions-64s.S | 51 +++++++++------
arch/powerpc/kernel/idle.c | 52 ++++++++++++++++
arch/powerpc/kernel/idle_power7.S | 2 -
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 103 ++++++++++++++++++++++++-------
arch/powerpc/platforms/powernv/smp.c | 12 +++-
drivers/cpuidle/cpuidle-powernv.c | 7 +-
7 files changed, 190 insertions(+), 49 deletions(-)
^ permalink raw reply
* [PATCH 1/6] powernv, cpuidle: Move the flags used for idle state discovery to powernv core
From: Preeti U Murthy @ 2014-05-28 4:38 UTC (permalink / raw)
To: benh, linux-kernel, svaidyan, paulus, srivatsa.bhat, linuxppc-dev
In-Reply-To: <20140528043703.15676.58580.stgit@preeti.in.ibm.com>
From: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
These flags will be used by the cpuidle driver as well as in the cpu
offline path. The offline cpus should be put to fastsleep if the idle state
is discovered so as to gain maximum power savings in the offline state.
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
[ Changelog added by <preeti@linux.vnet.ibm.com> ]
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/processor.h | 4 ++++
drivers/cpuidle/cpuidle-powernv.c | 7 +++----
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index d660dc3..d922e5c 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -445,6 +445,10 @@ static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
}
#endif
+/* Support for 'nap' and 'sleep' instructions, as discovered from the DT */
+#define IDLE_INST_NAP 0x00010000 /* nap instruction can be used */
+#define IDLE_INST_SLEEP 0x00020000 /* sleep instruction can be used */
+
extern unsigned long cpuidle_disable;
enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
index 719f6fb..5d4f9e8 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -17,12 +17,11 @@
#include <asm/machdep.h>
#include <asm/firmware.h>
#include <asm/runlatch.h>
+#include <asm/processor.h>
/* Flags and constants used in PowerNV platform */
#define MAX_POWERNV_IDLE_STATES 8
-#define IDLE_USE_INST_NAP 0x00010000 /* Use nap instruction */
-#define IDLE_USE_INST_SLEEP 0x00020000 /* Use sleep instruction */
struct cpuidle_driver powernv_idle_driver = {
.name = "powernv_idle",
@@ -187,7 +186,7 @@ static int powernv_add_idle_states(void)
for (i = 0; i < dt_idle_states; i++) {
- if (flags[i] & IDLE_USE_INST_NAP) {
+ if (flags[i] & IDLE_INST_NAP) {
/* Add NAP state */
strcpy(powernv_states[nr_idle_states].name, "Nap");
strcpy(powernv_states[nr_idle_states].desc, "Nap");
@@ -198,7 +197,7 @@ static int powernv_add_idle_states(void)
nr_idle_states++;
}
- if (flags[i] & IDLE_USE_INST_SLEEP) {
+ if (flags[i] & IDLE_INST_SLEEP) {
/* Add FASTSLEEP state */
strcpy(powernv_states[nr_idle_states].name, "FastSleep");
strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
^ permalink raw reply related
* [PATCH 2/6] powerpc, powernv, CPU hotplug: Put offline CPUs in Fast-Sleep instead of Nap
From: Preeti U Murthy @ 2014-05-28 4:38 UTC (permalink / raw)
To: benh, linux-kernel, svaidyan, paulus, srivatsa.bhat, linuxppc-dev
In-Reply-To: <20140528043703.15676.58580.stgit@preeti.in.ibm.com>
From: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
The offline cpus are put to fast sleep if the idle state is discovered in the
device tree. This is to gain maximum powersavings in the offline state.
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
[ Changelog added by <preeti@linux.vnet.ibm.com> ]
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/processor.h | 8 +++++
arch/powerpc/kernel/idle.c | 52 ++++++++++++++++++++++++++++++++++
arch/powerpc/platforms/powernv/smp.c | 12 +++++++-
3 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index d922e5c..c5256db 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -449,6 +449,14 @@ static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
#define IDLE_INST_NAP 0x00010000 /* nap instruction can be used */
#define IDLE_INST_SLEEP 0x00020000 /* sleep instruction can be used */
+/* Flags to indicate which of the CPU idle states are available for use */
+
+#define IDLE_USE_NAP (1UL << 0)
+#define IDLE_USE_SLEEP (1UL << 1)
+
+extern unsigned int supported_cpuidle_states;
+extern unsigned int pnv_get_supported_cpuidle_states(void);
+
extern unsigned long cpuidle_disable;
enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index d7216c9..e51d574 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -25,6 +25,7 @@
#include <linux/cpu.h>
#include <linux/sysctl.h>
#include <linux/tick.h>
+#include <linux/of.h>
#include <asm/processor.h>
#include <asm/cputable.h>
@@ -32,6 +33,7 @@
#include <asm/machdep.h>
#include <asm/runlatch.h>
#include <asm/smp.h>
+#include <asm/firmware.h>
unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
@@ -79,6 +81,56 @@ void arch_cpu_idle(void)
ppc64_runlatch_on();
}
+#ifdef CONFIG_PPC_POWERNV
+
+unsigned int supported_cpuidle_states = 0;
+
+unsigned int pnv_get_supported_cpuidle_states(void)
+{
+ return supported_cpuidle_states;
+}
+
+static int __init pnv_probe_idle_states(void)
+{
+ struct device_node *power_mgt;
+ struct property *prop;
+ int dt_idle_states;
+ u32 *flags;
+ int i;
+
+ if (!firmware_has_feature(FW_FEATURE_OPALv3))
+ return 0;
+
+ power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
+ if (!power_mgt) {
+ pr_warn("opal: PowerMgmt Node not found\n");
+ return 0;
+ }
+
+ prop = of_find_property(power_mgt, "ibm,cpu-idle-state-flags", NULL);
+ if (!prop) {
+ pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n");
+ return 0;
+ }
+
+ dt_idle_states = prop->length / sizeof(u32);
+ flags = (u32 *) prop->value;
+
+ for (i = 0; i < dt_idle_states; i++) {
+ if (flags[i] & IDLE_INST_NAP)
+ supported_cpuidle_states |= IDLE_USE_NAP;
+
+ if (flags[i] & IDLE_INST_SLEEP)
+ supported_cpuidle_states |= IDLE_USE_SLEEP;
+ }
+
+ return 0;
+}
+
+__initcall(pnv_probe_idle_states);
+#endif
+
+
int powersave_nap;
#ifdef CONFIG_SYSCTL
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index bf5fcd4..fc83006 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -31,6 +31,7 @@
#include <asm/xics.h>
#include <asm/opal.h>
#include <asm/runlatch.h>
+#include <asm/processor.h>
#include "powernv.h"
@@ -142,6 +143,7 @@ static int pnv_smp_cpu_disable(void)
static void pnv_smp_cpu_kill_self(void)
{
unsigned int cpu;
+ unsigned long idle_states;
/* Standard hot unplug procedure */
local_irq_disable();
@@ -152,13 +154,21 @@ static void pnv_smp_cpu_kill_self(void)
generic_set_cpu_dead(cpu);
smp_wmb();
+ idle_states = pnv_get_supported_cpuidle_states();
+
/* We don't want to take decrementer interrupts while we are offline,
* so clear LPCR:PECE1. We keep PECE2 enabled.
*/
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
while (!generic_check_cpu_restart(cpu)) {
ppc64_runlatch_off();
- power7_nap();
+
+ /* If sleep is supported, go to sleep, instead of nap */
+ if (idle_states & IDLE_USE_SLEEP)
+ power7_sleep();
+ else
+ power7_nap();
+
ppc64_runlatch_on();
if (!generic_check_cpu_restart(cpu)) {
DBG("CPU%d Unexpected exit while offline !\n", cpu);
^ permalink raw reply related
* [PATCH 3/6] KVM: PPC: Book3S HV: Enable CPUs to run guest after waking up from fast-sleep
From: Preeti U Murthy @ 2014-05-28 4:39 UTC (permalink / raw)
To: benh, linux-kernel, svaidyan, paulus, srivatsa.bhat, linuxppc-dev
In-Reply-To: <20140528043703.15676.58580.stgit@preeti.in.ibm.com>
From: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
When guests have to be launched, the secondary threads which are offline
are woken up to run the guests. Today these threads wake up from nap
and check if they have to run guests. Now that the offline secondary threads
can go to fastsleep, add this check in the fastsleep wakeup path as well.
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
[ Changelog added by <preeti@linux.vnet.ibm.com> ]
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
arch/powerpc/kernel/exceptions-64s.S | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 3afd391..b4bf464 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -100,6 +100,19 @@ system_reset_pSeries:
SET_SCRATCH0(r13)
#ifdef CONFIG_PPC_P7_NAP
BEGIN_FTR_SECTION
+
+ GET_PACA(r13)
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+ li r0,KVM_HWTHREAD_IN_KERNEL
+ stb r0,HSTATE_HWTHREAD_STATE(r13)
+ /* Order setting hwthread_state vs. testing hwthread_req */
+ sync
+ lbz r0,HSTATE_HWTHREAD_REQ(r13)
+ cmpwi r0,0
+ beq 1f
+ b kvm_start_guest
+1:
+#endif
/* Running native on arch 2.06 or later, check if we are
* waking up from nap. We only handle no state loss and
* supervisor state loss. We do -not- handle hypervisor
@@ -116,28 +129,15 @@ BEGIN_FTR_SECTION
* OPAL v3 based powernv platforms have new idle states
* which fall in this catagory.
*/
- bgt cr1,8f
GET_PACA(r13)
-
-#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
- li r0,KVM_HWTHREAD_IN_KERNEL
- stb r0,HSTATE_HWTHREAD_STATE(r13)
- /* Order setting hwthread_state vs. testing hwthread_req */
- sync
- lbz r0,HSTATE_HWTHREAD_REQ(r13)
- cmpwi r0,0
- beq 1f
- b kvm_start_guest
-1:
-#endif
+ bgt cr1,8f
beq cr1,2f
b .power7_wakeup_noloss
2: b .power7_wakeup_loss
/* Fast Sleep wakeup on PowerNV */
-8: GET_PACA(r13)
- b .power7_wakeup_tb_loss
+8: b .power7_wakeup_tb_loss
9:
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
^ permalink raw reply related
* [PATCH 4/6] KVM: PPC: Book3S HV: Consolidate the idle-state enter sequence in KVM
From: Preeti U Murthy @ 2014-05-28 4:39 UTC (permalink / raw)
To: benh, linux-kernel, svaidyan, paulus, srivatsa.bhat, linuxppc-dev
In-Reply-To: <20140528043703.15676.58580.stgit@preeti.in.ibm.com>
From: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Now that the support for fast sleep idle state is present, the KVM
standby threads can be put to fast sleep when they are either idle
or do not have a guest to run. Today they enter nap in these scenarios.
The purpose is to gain maximum power savings in a KVM scenario as well
when an entire cpu core is idle.
As a precursor, consolidate the code common across all idle states.
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
[ Changelog added by <preeti@linux.vnet.ibm.com> ]
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index b031f93..43aa806 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -40,6 +40,17 @@
#define NAPPING_CEDE 1
#define NAPPING_NOVCPU 2
+#define IDLE_STATE_ENTER_SEQ_HV(IDLE_INST) \
+ /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \
+ std r0, HSTATE_SCRATCH0(r13); \
+ ptesync; \
+ ld r0, HSTATE_SCRATCH0(r13); \
+1: cmpd r0, r0; \
+ bne 1b; \
+ IDLE_INST; \
+ b .
+
+
/*
* Call kvmppc_hv_entry in real mode.
* Must be called with interrupts hard-disabled.
@@ -325,13 +336,9 @@ kvm_do_nap:
rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1
mtspr SPRN_LPCR, r4
isync
- std r0, HSTATE_SCRATCH0(r13)
- ptesync
- ld r0, HSTATE_SCRATCH0(r13)
-1: cmpd r0, r0
- bne 1b
- nap
- b .
+ IDLE_STATE_ENTER_SEQ_HV(PPC_NAP)
+ /* No return */
+
/******************************************************************************
* *
@@ -2027,13 +2034,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
mtspr SPRN_LPCR,r5
isync
li r0, 0
- std r0, HSTATE_SCRATCH0(r13)
- ptesync
- ld r0, HSTATE_SCRATCH0(r13)
-1: cmpd r0, r0
- bne 1b
- nap
- b .
+ IDLE_STATE_ENTER_SEQ_HV(PPC_NAP)
+ /* No return */
33: mr r4, r3
li r3, 0
^ permalink raw reply related
* [PATCH 5/6] KVM: PPC: Book3S HV: Put KVM standby hwthreads to fast-sleep instead of nap
From: Preeti U Murthy @ 2014-05-28 4:39 UTC (permalink / raw)
To: benh, linux-kernel, svaidyan, paulus, srivatsa.bhat, linuxppc-dev
In-Reply-To: <20140528043703.15676.58580.stgit@preeti.in.ibm.com>
From: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Now that the support for fast sleep idle state is present, allow
the KVM standby threads to go to fast sleep if the platform supports
it.This will fetch us maximum power savings if an entire core is idle.
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
[ Changelog added by <preeti@linux.vnet.ibm.com> ]
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 73 ++++++++++++++++++++++++++++---
1 file changed, 65 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 43aa806..69244cc 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -207,7 +207,7 @@ kvmppc_primary_no_guest:
li r3, 1
stb r3, HSTATE_HWTHREAD_REQ(r13)
- b kvm_do_nap
+ b kvm_do_idle
kvm_novcpu_wakeup:
ld r1, HSTATE_HOST_R1(r13)
@@ -247,7 +247,7 @@ kvm_novcpu_exit:
b hdec_soon
/*
- * We come in here when wakened from nap mode.
+ * We come in here when wakened from nap or fast-sleep mode.
* Relocation is off and most register values are lost.
* r13 points to the PACA.
*/
@@ -303,7 +303,7 @@ kvm_start_guest:
bl kvmppc_hv_entry
- /* Back from the guest, go back to nap */
+ /* Back from the guest, go back to nap or fastsleep */
/* Clear our vcpu pointer so we don't come back in early */
li r0, 0
std r0, HSTATE_KVM_VCPU(r13)
@@ -314,7 +314,7 @@ kvm_start_guest:
*/
lwsync
- /* increment the nap count and then go to nap mode */
+ /* increment the nap count and then go to nap or fast-sleep mode */
ld r4, HSTATE_KVM_VCORE(r13)
addi r4, r4, VCORE_NAP_COUNT
51: lwarx r3, 0, r4
@@ -325,6 +325,24 @@ kvm_start_guest:
kvm_no_guest:
li r0, KVM_HWTHREAD_IN_NAP
stb r0, HSTATE_HWTHREAD_STATE(r13)
+
+kvm_do_idle:
+ /*
+ * if (supported_cpuidle_states & IDLE_USE_SLEEP)
+ * kvm_do_fastsleep();
+ * else
+ * kvm_do_nap();
+ */
+ LOAD_REG_ADDRBASE(r3,supported_cpuidle_states)
+ lwz r4,ADDROFF(supported_cpuidle_states)(r3)
+ /*
+ * andi. r4,r4,IDLE_USE_SLEEP. Replacing IDLE_USE_SLEEP
+ * with the immediate value since it is a 32 bit instruction
+ * and the operand needs to fit into this.
+ */
+ andi. r4,r4,2
+ bne kvm_do_fastsleep
+
kvm_do_nap:
/* Clear the runlatch bit before napping */
mfspr r2, SPRN_CTRLF
@@ -339,6 +357,18 @@ kvm_do_nap:
IDLE_STATE_ENTER_SEQ_HV(PPC_NAP)
/* No return */
+kvm_do_fastsleep:
+ li r3, LPCR_PECE0
+ mfspr r4, SPRN_LPCR
+ /* Don't set LPCR_PECE1 since we want to wakeup only on an external
+ * interrupt, and not on a decrementer interrupt.
+ */
+ rlwimi r4, r3, 0, LPCR_PECE0
+ mtspr SPRN_LPCR, r4
+ isync
+ IDLE_STATE_ENTER_SEQ_HV(PPC_SLEEP)
+ /* No return */
+
/******************************************************************************
* *
@@ -2016,8 +2046,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
bl kvmppc_save_fp
/*
- * Take a nap until a decrementer or external or doobell interrupt
- * occurs, with PECE1, PECE0 and PECEDP set in LPCR. Also clear the
+ * Go to fastsleep until an external or doobell interrupt
+ * occurs, with PECE0 and PECEDP set in LPCR. Also clear the
* runlatch bit before napping.
*/
mfspr r2, SPRN_CTRLF
@@ -2026,6 +2056,22 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
li r0,1
stb r0,HSTATE_HWTHREAD_REQ(r13)
+ /*
+ * if (supported_cpuidle_states & IDLE_USE_SLEEP)
+ * PPC_SLEEP;
+ * else
+ * PPC_NAP;
+ */
+ LOAD_REG_ADDRBASE(r3,supported_cpuidle_states)
+ lwz r4,ADDROFF(supported_cpuidle_states)(r3)
+ /*
+ * andi. r4,r4,IDLE_USE_SLEEP. Replacing IDLE_USE_SLEEP
+ * with the immediate value since it is a 32 bit instruction
+ * and the operand needs to fit into this.
+ */
+ andi. r4,r4,2
+ bne 35f
+
mfspr r5,SPRN_LPCR
ori r5,r5,LPCR_PECE0 | LPCR_PECE1
BEGIN_FTR_SECTION
@@ -2037,6 +2083,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
IDLE_STATE_ENTER_SEQ_HV(PPC_NAP)
/* No return */
+35: mfspr r5,SPRN_LPCR
+ ori r5,r5,LPCR_PECE0
+BEGIN_FTR_SECTION
+ oris r5,r5,LPCR_PECEDP@h
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+ mtspr SPRN_LPCR,r5
+ isync
+ li r0, 0
+ IDLE_STATE_ENTER_SEQ_HV(PPC_SLEEP)
+ /* No return */
+
33: mr r4, r3
li r3, 0
li r12, 0
@@ -2046,7 +2103,7 @@ kvm_end_cede:
/* get vcpu pointer */
ld r4, HSTATE_KVM_VCPU(r13)
- /* Woken by external or decrementer interrupt */
+ /* Woken by external */
ld r1, HSTATE_HOST_R1(r13)
/* load up FP state */
@@ -2129,7 +2186,7 @@ machine_check_realmode:
b fast_interrupt_c_return
/*
- * Check the reason we woke from nap, and take appropriate action.
+ * Check the reason we woke from nap or fastsleep, and take appropriate action.
* Returns:
* 0 if nothing needs to be done
* 1 if something happened that needs to be handled by the host
^ permalink raw reply related
* [PATCH 6/6] ppc, book3s: Go back to same idle state after handling machine check interrupt
From: Preeti U Murthy @ 2014-05-28 4:39 UTC (permalink / raw)
To: benh, linux-kernel, svaidyan, paulus, srivatsa.bhat, linuxppc-dev
In-Reply-To: <20140528043703.15676.58580.stgit@preeti.in.ibm.com>
From: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Now that the support for fast sleep is present, threads could have woken up
from fast sleep on getting a machine check interrupt. Hence add code to allow
threads to go back to the idle state they woke up from after handling the
interrupt. Today they go back to nap by default.
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
[ Changelog added by <preeti@linux.vnet.ibm.com> ]
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
arch/powerpc/kernel/exceptions-64s.S | 21 +++++++++++++++------
arch/powerpc/kernel/idle_power7.S | 2 +-
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index b4bf464..94cee3c 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1396,15 +1396,16 @@ machine_check_handle_early:
* of the following is true:
* a. thread wasn't in power saving mode
* b. thread was in power saving mode with no state loss or
- * supervisor state loss
+ * supervisor state loss or hypervisor state loss (fastsleep)
*
- * Go back to nap again if (b) is true.
+ * Go back to nap or fastsleep again if (b) is true.
*/
rlwinm. r11,r12,47-31,30,31 /* Was it in power saving mode? */
beq 4f /* No, it wasn;t */
- /* Thread was in power saving mode. Go back to nap again. */
- cmpwi r11,2
- bne 3f
+ /* Thread was in power saving mode. Go back to the same state again. */
+ cmpwi cr1,r11,2
+ blt cr1,3f
+7:
/* Supervisor state loss */
li r0,1
stb r0,PACA_NAPSTATELOST(r13)
@@ -1412,7 +1413,15 @@ machine_check_handle_early:
MACHINE_CHECK_HANDLER_WINDUP
GET_PACA(r13)
ld r1,PACAR1(r13)
- b .power7_enter_nap_mode
+ /* We need to pass the idle state in r3: 0 -> nap, 1 -> sleep */
+ bgt cr1,8f
+ li r3,0
+ b .power7_enter_idle
+ /* No return */
+
+8: li r3,1 /* Pass 1 in r3 to request sleep in power7_enter_idle */
+ b .power7_enter_idle
+ /* No return */
4:
#endif
/*
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index c3ab869..e13e21b 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -95,7 +95,7 @@ _GLOBAL(power7_powersave_common)
std r9,_MSR(r1)
std r1,PACAR1(r13)
-_GLOBAL(power7_enter_nap_mode)
+_GLOBAL(power7_enter_idle)
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
/* Tell KVM we're napping */
li r4,KVM_HWTHREAD_IN_NAP
^ permalink raw reply related
* [PATCH v2] powerpc/defconfig: update RTC support
From: Shengzhou Liu @ 2014-05-28 5:55 UTC (permalink / raw)
To: linuxppc-dev, scottwood; +Cc: Shengzhou Liu
- remove CONFIG_RTC_DRV_CMOS in corenet32_smp_defconfig(it's unused),
reserve CONFIG_RTC_DRV_CMOS in mpc85xx_defconfig(needed on some CDS boards)
- enable CONFIG_RTC_DRV_DS1307, CONFIG_RTC_DRV_DS1374,
CONFIG_RTC_DRV_DS3232 in mpc85xx_defconfig, mpc85xx_smp_defconfig
- enable RTC support in corenet64_smp_defconfig
Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
---
v2: updated with comments.
arch/powerpc/configs/corenet32_smp_defconfig | 3 ++-
arch/powerpc/configs/corenet64_smp_defconfig | 4 ++++
arch/powerpc/configs/mpc85xx_defconfig | 3 +++
arch/powerpc/configs/mpc85xx_smp_defconfig | 3 +++
4 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig
index bbd794d..9866898 100644
--- a/arch/powerpc/configs/corenet32_smp_defconfig
+++ b/arch/powerpc/configs/corenet32_smp_defconfig
@@ -138,8 +138,9 @@ CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_MPC85XX=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
CONFIG_RTC_DRV_DS3232=y
-CONFIG_RTC_DRV_CMOS=y
CONFIG_UIO=y
CONFIG_STAGING=y
CONFIG_VIRT_DRIVERS=y
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 63508dd..bdae4d0 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -125,6 +125,10 @@ CONFIG_USB_EHCI_FSL=y
CONFIG_USB_STORAGE=y
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
+CONFIG_RTC_DRV_DS3232=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_DMADEVICES=y
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index d2e0fab..541a5b6 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -210,6 +210,9 @@ CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
+CONFIG_RTC_DRV_DS3232=y
CONFIG_RTC_DRV_CMOS=y
CONFIG_DMADEVICES=y
CONFIG_FSL_DMA=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index 4cb7b59..105991a 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -211,6 +211,9 @@ CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
+CONFIG_RTC_DRV_DS3232=y
CONFIG_RTC_DRV_CMOS=y
CONFIG_DMADEVICES=y
CONFIG_FSL_DMA=y
--
1.8.0
^ permalink raw reply related
* RE: [2/2] powerpc/corenet64_smp_defconfig: enable RTC support
From: Shengzhou.Liu @ 2014-05-28 6:50 UTC (permalink / raw)
To: Scott Wood, Kumar Gala; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1401207688.6603.9.camel@snotra.buserror.net>
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogV29vZCBTY290dC1CMDc0
MjENCj4gU2VudDogV2VkbmVzZGF5LCBNYXkgMjgsIDIwMTQgMTI6MjEgQU0NCj4gVG86IEt1bWFy
IEdhbGENCj4gQ2M6IExpdSBTaGVuZ3pob3UtQjM2Njg1OyBsaW51eHBwYy1kZXZAbGlzdHMub3ps
YWJzLm9yZw0KPiBTdWJqZWN0OiBSZTogWzIvMl0gcG93ZXJwYy9jb3JlbmV0NjRfc21wX2RlZmNv
bmZpZzogZW5hYmxlIFJUQyBzdXBwb3J0DQo+IA0KPiBPbiBUdWUsIDIwMTQtMDUtMjcgYXQgMTA6
MzMgLTA1MDAsIEt1bWFyIEdhbGEgd3JvdGU6DQo+ID4gT24gTWF5IDI1LCAyMDE0LCBhdCAxMDow
OCBQTSwgU2hlbmd6aG91LkxpdUBmcmVlc2NhbGUuY29tIHdyb3RlOg0KPiA+DQo+ID4gPg0KPiA+
ID4+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+ID4gPj4gRnJvbTogV29vZCBTY290dC1C
MDc0MjENCj4gPiA+PiBTZW50OiBTYXR1cmRheSwgTWF5IDI0LCAyMDE0IDE6MDYgQU0NCj4gPiA+
PiBUbzogTGl1IFNoZW5nemhvdS1CMzY2ODUNCj4gPiA+PiBDYzogbGludXhwcGMtZGV2QGxpc3Rz
Lm96bGFicy5vcmcNCj4gPiA+PiBTdWJqZWN0OiBSZTogWzIvMl0gcG93ZXJwYy9jb3JlbmV0NjRf
c21wX2RlZmNvbmZpZzogZW5hYmxlIFJUQw0KPiA+ID4+IHN1cHBvcnQNCj4gPiA+Pg0KPiA+ID4+
IE9uIEZyaSwgMjAxNC0wNS0yMyBhdCAwMzowMyAtMDUwMCwgTGl1IFNoZW5nemhvdS1CMzY2ODUg
d3JvdGU6DQo+ID4gPj4+PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+ID4+Pj4gRnJv
bTogV29vZCBTY290dC1CMDc0MjENCj4gPiA+Pj4+IFNlbnQ6IEZyaWRheSwgTWF5IDIzLCAyMDE0
IDY6NTIgQU0NCj4gPiA+Pj4+IFRvOiBMaXUgU2hlbmd6aG91LUIzNjY4NQ0KPiA+ID4+Pj4gQ2M6
IGxpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnDQo+ID4gPj4+PiBTdWJqZWN0OiBSZTogWzIv
Ml0gcG93ZXJwYy9jb3JlbmV0NjRfc21wX2RlZmNvbmZpZzogZW5hYmxlIFJUQw0KPiA+ID4+Pj4g
c3VwcG9ydA0KPiA+ID4+Pj4NCj4gPiA+Pj4+PiArKysgYi9hcmNoL3Bvd2VycGMvY29uZmlncy9j
b3JlbmV0NjRfc21wX2RlZmNvbmZpZw0KPiA+ID4+Pj4+IEBAIC0xMjUsNiArMTI1LDExIEBAIENP
TkZJR19VU0JfRUhDSV9GU0w9eSAgQ09ORklHX1VTQl9TVE9SQUdFPXkNCj4gPiA+Pj4+PiBDT05G
SUdfTU1DPXkgIENPTkZJR19NTUNfU0RIQ0k9eQ0KPiA+ID4+Pj4+ICtDT05GSUdfUlRDX0NMQVNT
PXkNCj4gPiA+Pj4+PiArQ09ORklHX1JUQ19EUlZfQ01PUz15DQo+ID4gPj4+Pj4gK0NPTkZJR19S
VENfRFJWX0RTMTMwNz15DQo+ID4gPj4+Pj4gK0NPTkZJR19SVENfRFJWX0RTMTM3ND15DQo+ID4g
Pj4+Pj4gK0NPTkZJR19SVENfRFJWX0RTMzIzMj15DQo+ID4gPj4+Pj4gQ09ORklHX0VEQUM9eQ0K
PiA+ID4+Pj4+IENPTkZJR19FREFDX01NX0VEQUM9eQ0KPiA+ID4+Pj4+IENPTkZJR19ETUFERVZJ
Q0VTPXkNCj4gPiA+Pj4+DQo+ID4gPj4+PiBXaHkgb25seSBjb3JlbmV0NjQgYW5kIG5vdCBjb3Jl
bmV0MzI/DQo+ID4gPj4+Pg0KPiA+ID4+Pj4gLVNjb3R0DQo+ID4gPj4+IFtTaGVuZ3pob3VdIFRo
ZXJlIGlzIGFscmVhZHkgUlRDIHN1cHBvcnQgaW4gY29yZW5ldDMyLCBvbmx5DQo+ID4gPj4+IG1p
c3NpbmcgaW4NCj4gPiA+PiBjb3JlbmV0NjQuDQo+ID4gPj4NCj4gPiA+PiBPbmx5IERTMzIzMiwg
bm90IERTMTMwNyBvciBEUzEzNzQuICBXaGljaCBib2FyZHMgdXNlIHRoZSBsYXR0ZXIgdHdvPw0K
PiA+ID4+DQo+ID4gPj4gV2h5IGRvIHdlIG5lZWQgQ09ORklHX1JUQ19EUlZfQ01PUz8NCj4gPiA+
Pg0KPiA+ID4+IC1TY290dA0KPiA+ID4+DQo+ID4gPiBbU2hlbmd6aG91XSBzbyBmYXIgRFMxMzA3
IGFuZCBEUzEzNzQgb2NjdXIgb25seSBvbiB0aG9zZSBib2FyZHMgd2l0aA0KPiBjb3JlbmV0NjQu
DQo+IA0KPiBXaGljaCBib2FyZHM/ICBJIGRvbid0IHNlZSB0aGVtIGluIGFueSBjb3JlbmV0IGR0
cyBmaWxlcy4gIA0KDQpbU2hlbmd6aG91XSBDT05GSUdfUlRDX0RSVl9EUzEzMDcgaXMgbmVlZGVk
IGZvciBkczEzMzkgb24gdDIwODByZGIuDQoNCj4gSSBkbyBzZWUgc29tZSBpbnN0YW5jZXMgb2Yg
ZHMxMzc0IGluIHRoZSBkdHMgZmlsZXMgb2YgYm9hcmRzIG5vbi1jb3JlbmV0IG1wYzg1eHggYm9h
cmRzDQo+IChtcGM4NTY4bWRzLCBtcGM4NTY5bWRzLCBhbmQgcDEwMjFtZHMpLCB5ZXQgaXQncyBu
b3QgaW4gdGhlDQo+IG1wYzg1eHhfZGVmY29uZmlnIG9yIG1wYzg1eHhfc21wX2RlZmNvbmZpZy4N
Cj4gDQo+ID4gPiBDT05GSUdfUlRDX0RSVl9DTU9TIGlzIGVuYWJsZWQgaW4gbXBjODV4eF9kZWZj
b25maWcsDQo+IG1wYzg1eHhfc21wX2RlZmNvbmZpZywgY29yZW5ldDMyX3NtcF9kZWZjb25maWcs
IGV0YywgaGVyZSBrZWVwcw0KPiBjb25zaXN0ZW50IGluIGNvcmVuZXQ2NC4NCj4gPiA+IEl0IHNl
ZW1zIENPTkZJR19SVENfRFJWX0NNT1MgaXMgbm90IG5lZWRlZCBvbiA4NXh4IHBsYXRmb3JtLCBk
byB3ZQ0KPiBuZWVkIHRvIHJlbW92ZSBDT05GSUdfUlRDX0RSVl9DTU9TIGZyb20gYWxsIDg1eHgv
Y29yZW5ldCBkZWZjb25maWc/IElmIHNvLA0KPiBJIHdpbGwgcG9zdCBhIG5ldyBwYXRjaCB0byBk
byBpdC4NCj4gPg0KPiA+IFRoZSBDRFMgYm9hcmQgdXNlcyBhbiBSVEMgb3ZlciBJU0EgaWYgSSBy
ZW1lbWJlciBjb3JyZWN0bHksIG5vdCBzdXJlDQo+IHdoYXQgZHJpdmVyIGRlYWxzIHdpdGggdGhh
dCAoaWYgaXRzIENPTkZJR19SVENfRFJWX0NNT1MpIG9yIHNvbWV0aGluZw0KPiBlbHNlLg0KPiAN
Cj4gSWYgaXQncyBqdXN0IENEUyB0aGVuIHdlIGRvbid0IG5lZWQgaXQgaW4gZWl0aGVyIGNvcmVu
ZXQgY29uZmlnLg0KPiANCj4gLVNjb3R0DQo+IA0KW1NoZW5nemhvdV0geWVzLCBtcGM4NTQ4Y2Rz
IGJvYXJkIHVzZXMgQ09ORklHX1JUQ19EUlZfQ01PUyB0byBkZWFsIHdpdGggcnRjLiANCkkgdXBk
YXRlZCB0aGVzZSBjaGFuZ2VzIHdpdGggbmV3IHBhdGNoIHYyOiBodHRwOi8vcGF0Y2h3b3JrLm96
bGFicy5vcmcvcGF0Y2gvMzUzMjQzLw0KDQoNCg==
^ permalink raw reply
* Re: [PATCH v2] powerpc/powernv: hwmon driver for power values, fan rpm and temperature
From: Guenter Roeck @ 2014-05-28 7:23 UTC (permalink / raw)
To: Neelesh Gupta, linuxppc-dev, jdelvare, lm-sensors; +Cc: sbhat
In-Reply-To: <20140519141931.9248.11356.stgit@neelegup-tp-t420.in.ibm.com>
On 05/19/2014 07:26 AM, Neelesh Gupta wrote:
> This patch adds basic kernel enablement for reading power values, fan
> speed rpm and temperature values on powernv platforms which will
> be exported to user space through sysfs interface.
>
> Test results:
> -------------
> [root@tul163p1 ~]# sensors
> ibmpowernv-isa-0000
> Adapter: ISA adapter
> fan1: 5487 RPM (min = 0 RPM)
> fan2: 5152 RPM (min = 0 RPM)
> fan3: 5590 RPM (min = 0 RPM)
> fan4: 4963 RPM (min = 0 RPM)
> fan5: 0 RPM (min = 0 RPM)
> fan6: 0 RPM (min = 0 RPM)
> fan7: 7488 RPM (min = 0 RPM)
> fan8: 7944 RPM (min = 0 RPM)
> temp1: +39.0°C (high = +0.0°C)
> power1: 192.00 W
>
> [root@tul163p1 ~]# ls /sys/devices/platform/
> alarmtimer ibmpowernv.0 rtc-generic serial8250 uevent
> [root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/
> driver/ hwmon/ modalias subsystem/ uevent
> [root@tul163p1 ~]# ls /sys/devices/platform/ibmpowernv.0/hwmon/hwmon0/
> device fan2_min fan4_min fan6_min fan8_min power1_input
> fan1_fault fan3_fault fan5_fault fan7_fault in1_fault subsystem
> fan1_input fan3_input fan5_input fan7_input in2_fault temp1_input
> fan1_min fan3_min fan5_min fan7_min in3_fault temp1_max
> fan2_fault fan4_fault fan6_fault fan8_fault in4_fault uevent
> fan2_input fan4_input fan6_input fan8_input name
> [root@tul163p1 ~]#
> [root@tul163p1 ~]# ls /sys/class/hwmon/hwmon0/
> device fan2_min fan4_min fan6_min fan8_min power1_input
> fan1_fault fan3_fault fan5_fault fan7_fault in1_fault subsystem
> fan1_input fan3_input fan5_input fan7_input in2_fault temp1_input
> fan1_min fan3_min fan5_min fan7_min in3_fault temp1_max
> fan2_fault fan4_fault fan6_fault fan8_fault in4_fault uevent
> fan2_input fan4_input fan6_input fan8_input name
> [root@tul163p1 ~]#
>
The inX_fault attributes don't really make much sense. _fault attributes without
_input attributes don't have any value and are, as you noticed, not displayed
with the sensors command. Is this a problem in teh devicetree data or do you
really have voltage faults without voltages ?
> Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
> ---
>
Checkpatch says:
total: 8 errors, 11 warnings, 389 lines checked
NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or
scripts/cleanfile
which should really not happen at this point.
Please make sure you follow CodingStyle. checkpatch --strict points to a number
of additional violations.
More comments inline.
> Changes in v2
> =============
> - Generic use of devm_* functions in hwmon like using devm_kzalloc() for dynamic
> memory request, avoiding the need to explicit free of memory.
> Adding 'struct attribute_group' as member of platform data structure to be
> populated and then passed to devm_hwmon_device_register_with_groups().
>
> Note: Having an array of pointers of 'attribute_group' and each group
> corresponds to 'enum sensors' type. Not completely sure, if it's ideal or
> could have just one group populated with attributes of sensor types?
>
Your call, really; whatever is easier for you. I won't dictate one or the other.
Question though is what happens if one group is not populated. If I understand
the code correctly this will result in the remaining groups to be 'dropped',
ie not displayed at all.
> - 'ibmpowernv' is not hot-pluggable device so moving 'platform_driver' callback
> function (probe) as part of __init code.
> - Fixed issues related to coding style.
> - Other general comments in v1.
>
> drivers/hwmon/Kconfig | 8 +
> drivers/hwmon/Makefile | 1
> drivers/hwmon/ibmpowernv.c | 368 ++++++++++++++++++++++++++++++++++++++++++++
You'll also need Documentation/hwmon/ibmpowernv and
Documentation/devicetree/bindings/hwmon/ibmpowernv.
The latter will need to get an Ack from the devicetree maintainers.
> 3 files changed, 377 insertions(+)
> create mode 100644 drivers/hwmon/ibmpowernv.c
>
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index bc196f4..3e308fa 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -554,6 +554,14 @@ config SENSORS_IBMPEX
> This driver can also be built as a module. If so, the module
> will be called ibmpex.
>
> +config SENSORS_IBMPOWERNV
> + tristate "IBM POWERNV platform sensors"
> + depends on PPC_POWERNV
> + default y
> + help
> + If you say yes here you get support for the temperature/fan/power
> + sensors on your platform.
> +
> config SENSORS_IIO_HWMON
> tristate "Hwmon driver that uses channels specified via iio maps"
> depends on IIO
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index c48f987..199c401 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
> obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
> obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
> obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
> +obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o
> obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
> obj-$(CONFIG_SENSORS_INA209) += ina209.o
> obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
> diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
> new file mode 100644
> index 0000000..afce620
> --- /dev/null
> +++ b/drivers/hwmon/ibmpowernv.c
> @@ -0,0 +1,368 @@
> +/*
> + * IBM PowerNV platform sensors for temperature/fan/power
> + * Copyright (C) 2014 IBM
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +
> +#include <linux/platform_device.h>
> +#include <asm/opal.h>
> +#include <linux/err.h>
> +
> +#define DRVNAME "ibmpowernv"
> +#define MAX_ATTR_LEN 32
> +
> +/* Sensor suffix name from DT */
> +#define DT_FAULT_ATTR_SUFFIX "faulted"
> +#define DT_DATA_ATTR_SUFFIX "data"
> +#define DT_THRESHOLD_ATTR_SUFFIX "thrs"
> +
> +/*
> + * Enumerates all the types of sensors in the POWERNV platform and does index
> + * into 'struct sensor_group'
> + */
> +enum sensors {
> + FAN,
> + AMBIENT_TEMP,
> + POWER_SUPPLY,
> + POWER_INPUT,
> + MAX_SENSOR_TYPE,
> +};
> +
> +static struct sensor_group {
> + const char *name;
> + const char *compatible;
> + struct attribute_group group;
> + u32 attr_count;
> +} sensor_groups[] = {
> + {"fan", "ibm,opal-sensor-cooling-fan", {0}, 0},
> + {"temp", "ibm,opal-sensor-amb-temp", {0}, 0},
> + {"in", "ibm,opal-sensor-power-supply", {0}, 0},
> + {"power", "ibm,opal-sensor-power", {0}, 0}
> +};
> +
The '0' initializations should not be necessary.
> +struct sensor_data {
> + u32 id; /* An opaque id of the firmware for each sensor */
> + enum sensors type;
> + char name[MAX_ATTR_LEN];
> + struct device_attribute dev_attr;
> +};
> +
> +struct platform_data {
> + const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];
> + u32 sensors_count; /* Total count of sensors from each group */
> +};
> +
> +/* Platform device representing all the ibmpowernv sensors */
> +static struct platform_device *pdevice;
> +
> +static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
> + char *buf)
> +{
> + struct sensor_data *sdata = container_of(devattr, struct sensor_data,
> + dev_attr);
> + ssize_t ret;
> + u32 x;
> +
> + ret = opal_get_sensor_data(sdata->id, &x);
> + if (ret) {
> + pr_err("%s: Failed to get opal sensor data\n", __func__);
> + return ret;
> + }
> +
> + /* Convert temperature to milli-degrees */
> + if (sdata->type == AMBIENT_TEMP)
> + x *= 1000;
> + /* Convert power to micro-watts */
> + else if (sdata->type == POWER_INPUT)
> + x *= 1000000;
> +
> + return sprintf(buf, "%d\n", x);
x is unsigned, so %u.
> +}
> +
> +static void __init get_sensor_index_attr(const char *name, u32 *index, char *attr)
> +{
> + char *hash_pos = strchr(name, '#');
> + char *dash_pos;
> + u32 copy_len;
> + char buf[8];
> +
> + memset(buf, 0, sizeof(buf));
> + *index = 0;
> + *attr = '\0';
> +
> + if (hash_pos) {
> + dash_pos = strchr(hash_pos, '-');
> + if (dash_pos) {
> + copy_len = dash_pos - hash_pos - 1;
> + if (copy_len < sizeof(buf)) {
> + strncpy(buf, hash_pos + 1, copy_len);
> + sscanf(buf, "%d", index);
What if sscanf fails ? Might be an interesting exercise to try and create
multiple sensors with index 0 (or, for that matter, with the same index value).
Do you have any protection against bad input data ? Guess not; did you test
what happens if you pass bad data to the driver (such as duplicate sensor
entries) ?
> + }
> +
> + strncpy(attr, dash_pos + 1, MAX_ATTR_LEN);
> + }
> + }
> +}
> +
> +/*
> + * This function translates the DT node name into the 'hwmon' attribute name.
> + * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc.
> + * which need to be mapped as fan2_input, temp1_max respectively before
> + * populating them inside hwmon device class..
> + */
> +static int __init create_hwmon_attr_name(enum sensors type, const char *node_name,
> + char *hwmon_attr_name)
> +{
> + char attr_suffix[MAX_ATTR_LEN];
> + char *attr_name;
> + u32 index;
> +
> + get_sensor_index_attr(node_name, &index, attr_suffix);
> + if (!index || !strlen(attr_suffix)) {
> + pr_info("%s: Sensor device node name is invalid, name: %s\n",
> + __func__, node_name);
> + return -EINVAL;
> + }
> +
> + if (!strcmp(attr_suffix, DT_FAULT_ATTR_SUFFIX))
> + attr_name = "fault";
> + else if(!strcmp(attr_suffix, DT_DATA_ATTR_SUFFIX))
> + attr_name = "input";
> + else if (!strcmp(attr_suffix, DT_THRESHOLD_ATTR_SUFFIX)) {
> + if (type == AMBIENT_TEMP)
> + attr_name = "max";
> + else if (type == FAN)
> + attr_name = "min";
> + else
> + return -ENOENT;
> + } else
> + return -ENOENT;
> +
> + snprintf(hwmon_attr_name, MAX_ATTR_LEN, "%s%d_%s",
> + sensor_groups[type].name, index, attr_name);
> + return 0;
> +}
> +
> +static int __init populate_attr_groups(struct platform_device *pdev)
> +{
> + struct platform_data *pdata = platform_get_drvdata(pdev);
> + const struct attribute_group **pgroups = pdata->attr_groups;
> + struct device_node *opal, *np;
> + enum sensors type;
> + int err = 0;
> +
> + opal = of_find_node_by_path("/ibm,opal/sensors");
> + if (!opal) {
An obvious whitespace error here.
> + pr_err("%s: Opal 'sensors' node not found\n", __func__);
> + return -ENODEV;
> + }
> +
> + for_each_child_of_node(opal, np) {
> + if (np->name == NULL)
> + continue;
> +
> + for (type = 0; type < MAX_SENSOR_TYPE; type++)
> + if (of_device_is_compatible(np,
> + sensor_groups[type].compatible)) {
> + sensor_groups[type].attr_count++;
> + break;
> + }
> + }
You should be able to do
of_node_put(opal);
here. Then you can return immediately on error below.
> +
> + for (type = 0; type < MAX_SENSOR_TYPE; type++) {
> + if (!sensor_groups[type].attr_count)
> + continue;
> +
> + sensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev,
> + sizeof(struct attribute*) *
> + (sensor_groups[type].attr_count + 1),
> + GFP_KERNEL);
> + if (!sensor_groups[type].group.attrs) {
> + pr_err("%s: Failed to allocate memory for attribute"
> + "array\n", __func__);
devm_kzalloc() already dumps an error message. Same for all other memory error messages.
> + err = -ENOMEM;
> + goto exit_put_node;
> + }
> +
> + pgroups[type] = &sensor_groups[type].group;
> + pdata->sensors_count += sensor_groups[type].attr_count;
> + sensor_groups[type].attr_count = 0;
> + }
> +
> +exit_put_node:
> + of_node_put(opal);
> + return err;
> +}
> +
> +/*
> + * Iterate through the device tree for each child of sensor node, create
> + * a sysfs attribute file, the file is named by translating the DT node name
> + * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max
> + * etc..
> + */
> +static int __init create_device_attrs(struct platform_device *pdev)
> +{
> + struct platform_data *pdata = platform_get_drvdata(pdev);
> + const struct attribute_group **pgroups = pdata->attr_groups;
> + struct device_node *opal, *np;
> + struct sensor_data *sdata;
> + const u32 *sensor_id;
> + enum sensors type;
> + u32 count = 0;
> + int err = 0;
> +
> + opal = of_find_node_by_path("/ibm,opal/sensors");
> + if (!opal) {
> + pr_err("%s: Opal 'sensors' node not found\n", __func__);
> + return -ENODEV;
> + }
> +
> + sdata = devm_kzalloc(&pdev->dev, (pdata->sensors_count) *
> + sizeof(*sdata), GFP_KERNEL);
> + if (!sdata) {
> + pr_err("%s: Failed to allocate memory for the sensor_data",
> + __func__);
> + err = -ENOMEM;
> + goto exit_put_node;
> + }
> +
> + for_each_child_of_node(opal, np) {
> + if (np->name == NULL)
> + continue;
> +
> + for (type = 0; type < MAX_SENSOR_TYPE; type++)
> + if (of_device_is_compatible(np,
> + sensor_groups[type].compatible))
> + break;
> +
> + if (type == MAX_SENSOR_TYPE)
> + continue;
> +
> + sensor_id = of_get_property(np, "sensor-id", NULL);
> + if (!sensor_id) {
> + pr_info("%s: %s doesn't have sensor-id\n", __func__,
> + np->name);
> + continue;
> + }
> +
Consider using of_property_read_u32().
> + sdata[count].id = *sensor_id;
> + sdata[count].type = type;
> + err = create_hwmon_attr_name(type, np->name, sdata[count].name);
> + if (err)
> + goto exit_put_node;
> +
> + sysfs_attr_init(&sdata[count].dev_attr.attr);
> + sdata[count].dev_attr.attr.name = sdata[count].name;
> + sdata[count].dev_attr.attr.mode = S_IRUGO;
> + sdata[count].dev_attr.show = show_sensor;
> +
> + pgroups[type]->attrs[sensor_groups[type].attr_count++] =
> + &sdata[count++].dev_attr.attr;
> + }
> +
> +exit_put_node:
> + of_node_put(opal);
> + return err;
> +}
> +
> +static int __init ibmpowernv_probe(struct platform_device *pdev)
> +{
> + struct platform_data *pdata;
> + struct device *hwmon_dev;
> + int err;
> +
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> + if (!pdata)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, pdata);
> + pdata->sensors_count = 0;
> + err = populate_attr_groups(pdev);
> + if (err)
> + return err;
> +
> + /* Create sysfs attribute file for each sensor found in the DT */
Attribute data, not file
> + err = create_device_attrs(pdev);
> + if (err)
> + return err;
> +
> + /* Finally, register with hwmon */
> + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
> + pdata,
> + pdata->attr_groups);
> +
> + return PTR_ERR_OR_ZERO(hwmon_dev);
> +}
> +
> +static struct platform_driver ibmpowernv_driver = {
> + .driver = {
> + .owner = THIS_MODULE,
> + .name = DRVNAME,
> + },
> +};
> +
> +static int __init ibmpowernv_init(void)
> +{
> + int err;
> +
> + pdevice = platform_device_alloc(DRVNAME, 0);
> + if (!pdevice) {
> + pr_err("%s: Device allocation failed\n", __func__);
> + err = -ENOMEM;
> + goto exit;
> + }
> +
> + err = platform_device_add(pdevice);
> + if (err) {
> + pr_err("%s: Device addition failed (%d)\n", __func__, err);
> + goto exit_device_put;
> + }
> +
> + err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);
> + if (err) {
> + pr_err("%s: Platfrom driver probe failed\n", __func__);
> + goto exit_device_del;
> + }
> +
> + return 0;
> +
> +exit_device_del:
> + platform_device_del(pdevice);
> +exit_device_put:
> + platform_device_put(pdevice);
> +exit:
> + return err;
> +}
> +
> +static void __exit ibmpowernv_exit(void)
> +{
> + platform_driver_unregister(&ibmpowernv_driver);
> + platform_device_unregister(pdevice);
> +}
> +
> +MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>");
> +MODULE_DESCRIPTION("IBM POWERNV platform sensors");
> +MODULE_LICENSE("GPL");
> +
> +module_init(ibmpowernv_init);
> +module_exit(ibmpowernv_exit);
>
>
>
^ permalink raw reply
* Re: [PATCH v2] powerpc/powernv: hwmon driver for power values, fan rpm and temperature
From: Benjamin Herrenschmidt @ 2014-05-28 7:41 UTC (permalink / raw)
To: Guenter Roeck; +Cc: lm-sensors, sbhat, Neelesh Gupta, linuxppc-dev, jdelvare
In-Reply-To: <53858F02.2020808@roeck-us.net>
On Wed, 2014-05-28 at 00:23 -0700, Guenter Roeck wrote:
> Consider using of_property_read_u32().
>
> > + sdata[count].id = *sensor_id;
> > + sdata[count].type = type;
Especially since this is broken for Little Endian !
Neelesh, please make sure you test your patch on LE.
Cheers,
Ben.
^ permalink raw reply
* Re: [V6 00/11] perf: New conditional branch filter
From: Anshuman Khandual @ 2014-05-28 8:04 UTC (permalink / raw)
To: Stephane Eranian
Cc: Michael Neuling, ak@linux.intel.com, Peter Zijlstra, LKML,
Michael Ellerman, Linux PPC dev, Arnaldo Carvalho de Melo,
Sukadev Bhattiprolu, Ingo Molnar
In-Reply-To: <CABPqkBS+3N6PW0wJr3xnvpF4zinZM7+iwFWzwS7BDm-LTkam5Q@mail.gmail.com>
On 05/27/2014 05:39 PM, Stephane Eranian wrote:
> I have been looking at those patches and ran some tests.
> And I found a few issues so far.
>
> I am running:
> $ perf record -j any_ret -e cycles:u test_program
> $ perf report -D
>
> Most entries are okay and match the filter, however some do not make sense:
>
> 3642586996762 0x15d0 [0x108]: PERF_RECORD_SAMPLE(IP, 2): 17921/17921:
> 0x10001170 period: 613678 addr: 0
> .... branch stack: nr:9
> ..... 0: 00000000100011cc -> 0000000010000e38
> ..... 1: 0000000010001150 -> 00000000100011bc
> ..... 2: 0000000010001208 -> 0000000010000e38
> ..... 3: 0000000010001160 -> 00000000100011f8
> ..... 4: 00000000100011cc -> 0000000010000e38
> ..... 5: 0000000010001150 -> 00000000100011bc
> ..... 6: 0000000010001208 -> 0000000010000e38
> ..... 7: 0000000010001160 -> 00000000100011f8
> ..... 8: 0000000000000000 -> 0000000010001160
> ^^^^^^
> Entry 8 does not make sense, unless 0x0 is a valid return branch
> instruction address.
> If an address is invalid, the whole entry needs to be eliminated. It
> is okay to have
> less than the max number of entries supported by HW.
Hey Stephane,
Okay. The same behaviour is also reflected in the test results what I have
shared in the patchset. Here is that section.
(3) perf record -j any_ret -e branch-misses:u ./cprog
# Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
# ........ ....... .................... ..................... .................... .....................
#
15.61% cprog [unknown] [.] 00000000 cprog [.] sw_3_1
6.28% cprog cprog [.] symbol2 cprog [.] hw_1_2
6.28% cprog cprog [.] ctr_addr cprog [.] sw_4_1
6.26% cprog cprog [.] success_3_1_3 cprog [.] sw_3_1
6.24% cprog cprog [.] symbol1 cprog [.] hw_1_1
6.24% cprog cprog [.] sw_4_2 cprog [.] callme
6.21% cprog [unknown] [.] 00000000 cprog [.] callme
6.19% cprog cprog [.] lr_addr cprog [.] sw_4_2
3.16% cprog cprog [.] hw_1_2 cprog [.] callme
3.15% cprog cprog [.] success_3_1_1 cprog [.] sw_3_1
3.15% cprog cprog [.] sw_4_1 cprog [.] callme
3.14% cprog cprog [.] callme cprog [.] main
3.13% cprog cprog [.] hw_1_1 cprog [.] callme
So a lot of samples above have 0x0 as the "from" address. This originates from the code
section here inside the function "power_pmu_bhrb_read", where we hit two back to back
target addresses. So we zero out the from address for the first target address and re-read
the second address over again. So thats how we get zero as the from address. This is how the
HW capture the samples. I was reluctant to drop these samples but I agree that these kind of
samples can be dropped if we need to.
if (val & BHRB_TARGET) {
/* Shouldn't have two targets in a
row.. Reset index and try again */
r_index--;
addr = 0;
}
> I also had cases where monitoring only at the user level, got me
> branch addresses in the
> 0xc0000000...... range. My test program is linked statically.
>
Thats weird. I would need more information and details on this. BTW
what is the system you are running on ? Could you please share the
/proc/cpuinfo details of the same ?
> when eliminating the bogus entries, my tests yielded only return
> branch instruction addresses
> which is good. Will run more tests.
Sure. Thanks for the tests and comments.
^ permalink raw reply
* [PATCH 1/2] powerpc/mm: Check paca psize is up to date for huge mappings
From: Michael Ellerman @ 2014-05-28 8:21 UTC (permalink / raw)
To: linuxppc-dev; +Cc: aneesh.kumar, Paul Mackerras
We have a bug in our hugepage handling which exhibits as an infinite
loop of hash faults. If the fault is being taken in the kernel it will
typically trigger the softlockup detector, or the RCU stall detector.
The bug is as follows:
1. mmap(0xa0000000, ..., MAP_FIXED | MAP_HUGE_TLB | MAP_ANONYMOUS ..)
2. Slice code converts the slice psize to 16M.
3. The code on lines 539-540 of slice.c in slice_get_unmapped_area()
synchronises the mm->context with the paca->context. So the paca slice
mask is updated to include the 16M slice.
3. Either:
* mmap() fails because there are no huge pages available.
* mmap() succeeds and the mapping is then munmapped.
In both cases the slice psize remains at 16M in both the paca & mm.
4. mmap(0xa0000000, ..., MAP_FIXED | MAP_ANONYMOUS ..)
5. The slice psize is converted back to 64K. Because of the check on line 539
of slice.c we DO NOT update the paca->context. The paca slice mask is now
out of sync with the mm slice mask.
6. User/kernel accesses 0xa0000000.
7. The SLB miss handler slb_allocate_realmode() **uses the paca slice mask**
to create an SLB entry and inserts it in the SLB.
18. With the 16M SLB entry in place the hardware does a hash lookup, no entry
is found so a data access exception is generated.
19. The data access handler calls do_page_fault() -> handle_mm_fault().
10. __handle_mm_fault() creates a THP mapping with do_huge_pmd_anonymous_page().
11. The hardware retries the access, there is still nothing in the hash table
so once again a data access exception is generated.
12. hash_page() calls into __hash_page_thp() and inserts a mapping in the
hash. Although the THP mapping maps 16M the hashing is done using 64K
as the segment page size.
13. hash_page() returns immediately after calling __hash_page_thp(), skipping
over the code at line 1125. Resulting in the mismatch between the
paca->context and mm->context not being detected.
14. The hardware retries the access, the hash it generates using the 16M
SLB entry does NOT match the hash we inserted.
15. We take another data access and go into __hash_page_thp().
16. We see a valid entry in the hpte_slot_array and so we call updatepp()
which succeeds.
17. Goto 14.
We could fix this in two ways. The first would be to remove or modify
the check on line 539 of slice.c.
The second option is to cause the check of paca psize in hash_page() on
line 1125 to also be done for THP pages.
We prefer the latter, because the check & update of the paca psize is
not done until we know it's necessary. It's also done only on the
current cpu, so we don't need to IPI all other cpus.
Without further rearranging the code, the simplest fix is to pull out
the code that checks paca psize and call it in two places. Firstly for
THP/hugetlb, and secondly for other mappings as before.
Thanks to Dave Jones for trinity, which originally found this bug.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/mm/hash_utils_64.c | 31 ++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index d766d6e..6650699 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -960,6 +960,22 @@ void hash_failure_debug(unsigned long ea, unsigned long access,
trap, vsid, ssize, psize, lpsize, pte);
}
+static void check_paca_psize(unsigned long ea, struct mm_struct *mm,
+ int psize, bool user_region)
+{
+ if (user_region) {
+ if (psize != get_paca_psize(ea)) {
+ get_paca()->context = mm->context;
+ slb_flush_and_rebolt();
+ }
+ } else if (get_paca()->vmalloc_sllp !=
+ mmu_psize_defs[mmu_vmalloc_psize].sllp) {
+ get_paca()->vmalloc_sllp =
+ mmu_psize_defs[mmu_vmalloc_psize].sllp;
+ slb_vmalloc_update();
+ }
+}
+
/* Result code is:
* 0 - handled
* 1 - normal page fault
@@ -1081,6 +1097,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
WARN_ON(1);
}
#endif
+ check_paca_psize(ea, mm, psize, user_region);
+
goto bail;
}
@@ -1121,17 +1139,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
#endif
}
}
- if (user_region) {
- if (psize != get_paca_psize(ea)) {
- get_paca()->context = mm->context;
- slb_flush_and_rebolt();
- }
- } else if (get_paca()->vmalloc_sllp !=
- mmu_psize_defs[mmu_vmalloc_psize].sllp) {
- get_paca()->vmalloc_sllp =
- mmu_psize_defs[mmu_vmalloc_psize].sllp;
- slb_vmalloc_update();
- }
+
+ check_paca_psize(ea, mm, psize, user_region);
#endif /* CONFIG_PPC_64K_PAGES */
#ifdef CONFIG_PPC_HAS_HASH_64K
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] selftests/powerpc: Test the THP bug we fixed in the previous commit
From: Michael Ellerman @ 2014-05-28 8:21 UTC (permalink / raw)
To: linuxppc-dev; +Cc: aneesh.kumar, Paul Mackerras
In-Reply-To: <1401265278-29307-1-git-send-email-mpe@ellerman.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
tools/testing/selftests/powerpc/Makefile | 2 +-
tools/testing/selftests/powerpc/mm/Makefile | 18 ++++++
.../selftests/powerpc/mm/hugetlb_vs_thp_test.c | 72 ++++++++++++++++++++++
3 files changed, 91 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/mm/Makefile
create mode 100644 tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 316194f..b3dbe9e 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
export CC CFLAGS
-TARGETS = pmu copyloops
+TARGETS = pmu copyloops mm
endif
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile
new file mode 100644
index 0000000..357ccbd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/Makefile
@@ -0,0 +1,18 @@
+noarg:
+ $(MAKE) -C ../
+
+PROGS := hugetlb_vs_thp_test
+
+all: $(PROGS)
+
+$(PROGS): ../harness.c
+
+run_tests: all
+ @-for PROG in $(PROGS); do \
+ ./$$PROG; \
+ done;
+
+clean:
+ rm -f $(PROGS)
+
+.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c b/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c
new file mode 100644
index 0000000..3d8e5b0
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "utils.h"
+
+/* This must match the huge page & THP size */
+#define SIZE (16 * 1024 * 1024)
+
+static int test_body(void)
+{
+ void *addr;
+ char *p;
+
+ addr = (void *)0xa0000000;
+
+ p = mmap(addr, SIZE, PROT_READ | PROT_WRITE,
+ MAP_HUGETLB | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (p != MAP_FAILED) {
+ /*
+ * Typically the mmap will fail because no huge pages are
+ * allocated on the system. But if there are huge pages
+ * allocated the mmap will succeed. That's fine too, we just
+ * munmap here before continuing.
+ */
+ munmap(addr, SIZE);
+ }
+
+ p = mmap(addr, SIZE, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (p == MAP_FAILED) {
+ printf("Mapping failed @ %p\n", addr);
+ perror("mmap");
+ return 1;
+ }
+
+ /*
+ * Either a user or kernel access is sufficient to trigger the bug.
+ * A kernel access is easier to spot & debug, as it will trigger the
+ * softlockup or RCU stall detectors, and when the system is kicked
+ * into xmon we get a backtrace in the kernel.
+ *
+ * A good option is:
+ * getcwd(p, SIZE);
+ *
+ * For the purposes of this testcase it's preferable to spin in
+ * userspace, so the harness can kill us if we get stuck. That way we
+ * see a test failure rather than a dead system.
+ */
+ *p = 0xf;
+
+ munmap(addr, SIZE);
+
+ return 0;
+}
+
+static int test_main(void)
+{
+ int i;
+
+ /* 10,000 because it's a "bunch", and completes reasonably quickly */
+ for (i = 0; i < 10000; i++)
+ if (test_body())
+ return 1;
+
+ return 0;
+}
+
+int main(void)
+{
+ return test_harness(test_main, "hugetlb_vs_thp");
+}
--
1.9.1
^ permalink raw reply related
* [PATCH] powerpc/85xx: Add T4240RDB board support
From: Chunhe Lan @ 2014-05-28 8:11 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Scott Wood, Chunhe Lan
T4240RDB board Specification
----------------------------
Memory subsystem:
6GB DDR3
128MB NOR flash
2GB NAND flash
Ethernet:
Eight 1G SGMII ports
Four 10Gbps SFP+ ports
PCIe:
Two PCIe slots
USB:
Two USB2.0 Type A ports
SDHC:
One SD-card port
SATA:
One SATA port
UART:
Dual RJ45 ports
Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/boot/dts/t4240rdb.dts | 186 +++++++++++++++++++++++++
arch/powerpc/configs/corenet64_smp_defconfig | 5 +
arch/powerpc/platforms/85xx/Kconfig | 2 +-
arch/powerpc/platforms/85xx/corenet_generic.c | 1 +
4 files changed, 193 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/boot/dts/t4240rdb.dts
diff --git a/arch/powerpc/boot/dts/t4240rdb.dts b/arch/powerpc/boot/dts/t4240rdb.dts
new file mode 100644
index 0000000..53761d4
--- /dev/null
+++ b/arch/powerpc/boot/dts/t4240rdb.dts
@@ -0,0 +1,186 @@
+/*
+ * T4240RDB Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/t4240si-pre.dtsi"
+
+/ {
+ model = "fsl,T4240RDB";
+ compatible = "fsl,T4240RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25wf040";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ };
+ };
+
+ i2c@118000 {
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ eeprom@54 {
+ compatible = "at24,24c256";
+ reg = <0x54>;
+ };
+ eeprom@56 {
+ compatible = "at24,24c256";
+ reg = <0x56>;
+ };
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+
+ sdhc@114000 {
+ voltage-ranges = <1800 1800 3300 3300>;
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe270000 {
+ reg = <0xf 0xfe270000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+};
+
+/include/ "fsl/t4240si-post.dtsi"
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 5c7fa19..fe0ab57 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -96,6 +96,8 @@ CONFIG_SATA_SIL24=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_E1000E=y
+CONFIG_PHYLIB=y
+CONFIG_VITESSE_PHY=y
CONFIG_INPUT_FF_MEMLESS=m
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_KEYBOARD is not set
@@ -125,6 +127,9 @@ CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1374=y
+CONFIG_RTC_DRV_CMOS=y
CONFIG_DMADEVICES=y
CONFIG_FSL_DMA=y
CONFIG_EXT2_FS=y
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index c17aae8..6f279ce 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -265,7 +265,7 @@ config CORENET_GENERIC
For 32bit kernel, the following boards are supported:
P2041 RDB, P3041 DS and P4080 DS
For 64bit kernel, the following boards are supported:
- T4240 QDS and B4 QDS
+ T4240 QDS, T4240 RDB and B4 QDS
The following boards are supported for both 32bit and 64bit kernel:
P5020 DS and P5040 DS
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index 8e4b1e1..2f50526 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -119,6 +119,7 @@ static const char * const boards[] __initconst = {
"fsl,P5020DS",
"fsl,P5040DS",
"fsl,T4240QDS",
+ "fsl,T4240RDB",
"fsl,B4860QDS",
"fsl,B4420QDS",
"fsl,B4220QDS",
--
1.7.6.5
^ permalink raw reply related
* [PATCH] t4240/dts: Enable third elo3 DMA engine support
From: Chunhe Lan @ 2014-05-28 8:47 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Scott Wood, Chunhe Lan
T4240QDS and T4240RDB have the third DMA engine
controller. So add corresponding DMA node into
dts file.
Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 1 +
arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
index f99d74f..001183c 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
@@ -475,6 +475,7 @@
/include/ "elo3-dma-0.dtsi"
/include/ "elo3-dma-1.dtsi"
+/include/ "elo3-dma-2.dtsi"
/include/ "qoriq-espi-0.dtsi"
spi@110000 {
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
index 0b8ccc5..05fb23b 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
@@ -57,6 +57,7 @@
pci3 = &pci3;
dma0 = &dma0;
dma1 = &dma1;
+ dma2 = &dma2;
sdhc = &sdhc;
};
--
1.7.6.5
^ permalink raw reply related
* RE: [PATCH 11/16] byteorder: provide a linux/byteorder.h with {be, le}_to_cpu() and cpu_to_{be, le}() macros
From: David Laight @ 2014-05-28 8:45 UTC (permalink / raw)
To: 'Cody P Schafer', LKML, Linux PPC; +Cc: Sukadev Bhattiprolu
In-Reply-To: <1401236684-10579-12-git-send-email-dev@codyps.com>
RnJvbTogQ29keSBQIFNjaGFmZXINCj4gUmF0aGVyIG1hbnVhbGx5IHNwZWNpZnlpbmcgdGhlIHNp
emUgb2YgdGhlIGludGVnZXIgdG8gYmUgY29udmVydGVkLCBrZXkNCj4gb2ZmIG9mIHRoZSB0eXBl
IHNpemUuIFJlZHVjZXMgZHVwbGljYXRlIHNpemUgaW5mbyBhbmQgdGhlIG9jY3VyYW5jZSBvZg0K
PiBjZXJ0YWluIHR5cGVzIG9mIGJ1Z3MgKHVzaW5nIHRoZSB3cm9uZyBzaXplZCBjb252ZXJzaW9u
KS4NCi4uLg0KPiArI2RlZmluZSBiZV90b19jcHUodikgXA0KPiArCV9fYnVpbHRpbl9jaG9vc2Vf
ZXhwcihzaXplb2YodikgPT0gc2l6ZW9mKHVpbnQ4X3QpICwgdiwJXA0KPiArCV9fYnVpbHRpbl9j
aG9vc2VfZXhwcihzaXplb2YodikgPT0gc2l6ZW9mKHVpbnQxNl90KSwgYmUxNl90b19jcHUodiks
IFwNCj4gKwlfX2J1aWx0aW5fY2hvb3NlX2V4cHIoc2l6ZW9mKHYpID09IHNpemVvZih1aW50MzJf
dCksIGJlMzJfdG9fY3B1KHYpLCBcDQo+ICsJX19idWlsdGluX2Nob29zZV9leHByKHNpemVvZih2
KSA9PSBzaXplb2YodWludDY0X3QpLCBiZTY0X3RvX2NwdSh2KSwgXA0KPiArCQkodm9pZCkwKSkp
KQ0KLi4uDQoNCkknbSBub3QgYXQgYWxsIHN1cmUgdGhhdCB1c2luZyB0aGUgJ3NpemUnIG9mIHRo
ZSBjb25zdGFudCB3aWxsIHJlZHVjZQ0KdGhlIG51bWJlciBvZiBidWdzIC0gaXQganVzdCBpbnRy
b2R1Y2VzIGEgd2hvbGUgbmV3IGNhdGVnb3J5IG9mIGJ1Z3MuDQoNClVzaW5nIHRoZSBzaXplIG9m
IHRoZSBkZXN0aW5hdGlvbiBtaWdodCBoZWxwLCBidXQgdGhhdCBtYWtlcyB0aGUgY29kZQ0KdWds
eS4NCg0KR2V0dGluZyBvbmUgb2YgdGhlIHN0YXRpYyBhbmFseXNlcnMgdG8gZmluZCB0aGUgb2J2
aW91cyBlcnJvcnMgaXMNCnByb2JhYmx5IG1vcmUgYXBwcm9wcmlhdGUuDQoNCglEYXZpZA0KDQo=
^ 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