* [PATCH v7 2/3] powerpc/eeh: EEH support for VFIO PCI device
From: Gavin Shan @ 2014-05-27 8:40 UTC (permalink / raw)
To: kvm-ppc; +Cc: aik, agraf, Gavin Shan, alex.williamson, qiudayu, linuxppc-dev
In-Reply-To: <1401180052-6060-1-git-send-email-gwshan@linux.vnet.ibm.com>
The patch exports functions to be used by new ioctl commands, which
will be introduced in subsequent patch, to support EEH functinality
for VFIO PCI device.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/eeh.h | 15 +++
arch/powerpc/kernel/eeh.c | 286 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 301 insertions(+)
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 34a2d83..ffc95e7 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -26,6 +26,7 @@
#include <linux/string.h>
#include <linux/time.h>
+struct iommu_table;
struct pci_dev;
struct pci_bus;
struct device_node;
@@ -191,6 +192,8 @@ enum {
#define EEH_OPT_ENABLE 1 /* EEH enable */
#define EEH_OPT_THAW_MMIO 2 /* MMIO enable */
#define EEH_OPT_THAW_DMA 3 /* DMA enable */
+#define EEH_OPT_GET_PE_ADDR 0 /* Get PE addr */
+#define EEH_OPT_GET_PE_MODE 1 /* Get PE mode */
#define EEH_STATE_UNAVAILABLE (1 << 0) /* State unavailable */
#define EEH_STATE_NOT_SUPPORT (1 << 1) /* EEH not supported */
#define EEH_STATE_RESET_ACTIVE (1 << 2) /* Active reset */
@@ -198,6 +201,11 @@ enum {
#define EEH_STATE_DMA_ACTIVE (1 << 4) /* Active DMA */
#define EEH_STATE_MMIO_ENABLED (1 << 5) /* MMIO enabled */
#define EEH_STATE_DMA_ENABLED (1 << 6) /* DMA enabled */
+#define EEH_PE_STATE_NORMAL 0 /* Normal state */
+#define EEH_PE_STATE_RESET 1 /* PE reset */
+#define EEH_PE_STATE_STOPPED_IO_DMA 2 /* Stopped */
+#define EEH_PE_STATE_STOPPED_DMA 4 /* Stopped DMA */
+#define EEH_PE_STATE_UNAVAIL 5 /* Unavailable */
#define EEH_RESET_DEACTIVATE 0 /* Deactivate the PE reset */
#define EEH_RESET_HOT 1 /* Hot reset */
#define EEH_RESET_FUNDAMENTAL 3 /* Fundamental reset */
@@ -305,6 +313,13 @@ void eeh_add_device_late(struct pci_dev *);
void eeh_add_device_tree_late(struct pci_bus *);
void eeh_add_sysfs_files(struct pci_bus *);
void eeh_remove_device(struct pci_dev *);
+int eeh_dev_open(struct pci_dev *pdev);
+void eeh_dev_release(struct pci_dev *pdev);
+struct eeh_pe *eeh_iommu_table_to_pe(struct iommu_table *tbl);
+int eeh_pe_set_option(struct eeh_pe *pe, int option);
+int eeh_pe_get_state(struct eeh_pe *pe);
+int eeh_pe_reset(struct eeh_pe *pe, int option);
+int eeh_pe_configure(struct eeh_pe *pe);
/**
* EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 3bc8b12..30693c1 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -40,6 +40,7 @@
#include <asm/eeh.h>
#include <asm/eeh_event.h>
#include <asm/io.h>
+#include <asm/iommu.h>
#include <asm/machdep.h>
#include <asm/ppc-pci.h>
#include <asm/rtas.h>
@@ -108,6 +109,9 @@ struct eeh_ops *eeh_ops = NULL;
/* Lock to avoid races due to multiple reports of an error */
DEFINE_RAW_SPINLOCK(confirm_error_lock);
+/* Lock to protect passed flags */
+static DEFINE_MUTEX(eeh_dev_mutex);
+
/* Buffer for reporting pci register dumps. Its here in BSS, and
* not dynamically alloced, so that it ends up in RMO where RTAS
* can access it.
@@ -1106,6 +1110,288 @@ void eeh_remove_device(struct pci_dev *dev)
edev->mode &= ~EEH_DEV_SYSFS;
}
+/**
+ * eeh_dev_open - Mark EEH device and PE as passed through
+ * @pdev: PCI device
+ *
+ * Mark the indicated EEH device and PE as passed through.
+ * In the result, the EEH errors detected on the PE won't be
+ * reported. The owner of the device will be responsible for
+ * detection and recovery.
+ */
+int eeh_dev_open(struct pci_dev *pdev)
+{
+ struct eeh_dev *edev;
+
+ mutex_lock(&eeh_dev_mutex);
+
+ /* No PCI device ? */
+ if (!pdev) {
+ mutex_unlock(&eeh_dev_mutex);
+ return -ENODEV;
+ }
+
+ /* No EEH device ? */
+ edev = pci_dev_to_eeh_dev(pdev);
+ if (!edev || !edev->pe) {
+ mutex_unlock(&eeh_dev_mutex);
+ return -ENODEV;
+ }
+
+ eeh_dev_set_passed(edev, true);
+ eeh_pe_set_passed(edev->pe, true);
+ mutex_unlock(&eeh_dev_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(eeh_dev_open);
+
+/**
+ * eeh_dev_release - Reclaim the ownership of EEH device
+ * @pdev: PCI device
+ *
+ * Reclaim ownership of EEH device, potentially the corresponding
+ * PE. In the result, the EEH errors detected on the PE will be
+ * reported and handled as usual.
+ */
+void eeh_dev_release(struct pci_dev *pdev)
+{
+ bool release_pe = true;
+ struct eeh_pe *pe = NULL;
+ struct eeh_dev *tmp, *edev;
+
+ mutex_lock(&eeh_dev_mutex);
+
+ /* No PCI device ? */
+ if (!pdev) {
+ mutex_unlock(&eeh_dev_mutex);
+ return;
+ }
+
+ /* No EEH device ? */
+ edev = pci_dev_to_eeh_dev(pdev);
+ if (!edev || !eeh_dev_passed(edev) ||
+ !edev->pe || !eeh_pe_passed(pe)) {
+ mutex_unlock(&eeh_dev_mutex);
+ return;
+ }
+
+ /* Release device */
+ pe = edev->pe;
+ eeh_dev_set_passed(edev, false);
+
+ /* Release PE */
+ eeh_pe_for_each_dev(pe, edev, tmp) {
+ if (eeh_dev_passed(edev)) {
+ release_pe = false;
+ break;
+ }
+ }
+
+ if (release_pe)
+ eeh_pe_set_passed(pe, false);
+
+ mutex_unlock(&eeh_dev_mutex);
+}
+EXPORT_SYMBOL(eeh_dev_release);
+
+/**
+ * eeh_iommu_table_to_pe - Convert IOMMU table to EEH PE
+ * @tbl: IOMMU table
+ *
+ * The routine is called to convert IOMMU table to EEH PE.
+ */
+struct eeh_pe *eeh_iommu_table_to_pe(struct iommu_table *tbl)
+{
+ struct pci_dev *pdev = NULL;
+ struct eeh_dev *edev;
+ bool found = false;
+
+ /* No IOMMU table ? */
+ if (!tbl)
+ return NULL;
+
+ /* No PCI device ? */
+ for_each_pci_dev(pdev) {
+ if (get_iommu_table_base(&pdev->dev) == tbl) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return NULL;
+
+ /* No EEH device or PE ? */
+ edev = pci_dev_to_eeh_dev(pdev);
+ if (!edev || !edev->pe)
+ return NULL;
+
+ return edev->pe;
+}
+
+/**
+ * eeh_pe_set_option - Set options for the indicated PE
+ * @pe: EEH PE
+ * @option: requested option
+ *
+ * The routine is called to enable or disable EEH functionality
+ * on the indicated PE, to enable IO or DMA for the frozen PE.
+ */
+int eeh_pe_set_option(struct eeh_pe *pe, int option)
+{
+ int ret = 0;
+
+ /* Invalid PE ? */
+ if (!pe)
+ return -ENODEV;
+
+ /*
+ * EEH functionality could possibly be disabled, just
+ * return error for the case. And the EEH functinality
+ * isn't expected to be disabled on one specific PE.
+ */
+ switch (option) {
+ case EEH_OPT_ENABLE:
+ if (eeh_enabled())
+ break;
+ ret = -EIO;
+ break;
+ case EEH_OPT_DISABLE:
+ break;
+ case EEH_OPT_THAW_MMIO:
+ case EEH_OPT_THAW_DMA:
+ if (!eeh_ops || !eeh_ops->set_option) {
+ ret = -ENOENT;
+ break;
+ }
+
+ ret = eeh_ops->set_option(pe, option);
+ break;
+ default:
+ pr_debug("%s: Option %d out of range (%d, %d)\n",
+ __func__, option, EEH_OPT_DISABLE, EEH_OPT_THAW_DMA);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(eeh_pe_set_option);
+
+/**
+ * eeh_pe_get_state - Retrieve PE's state
+ * @pe: EEH PE
+ *
+ * Retrieve the PE's state, which includes 3 aspects: enabled
+ * DMA, enabled IO and asserted reset.
+ */
+int eeh_pe_get_state(struct eeh_pe *pe)
+{
+ int result, ret = 0;
+
+ /* Existing PE ? */
+ if (!pe)
+ return -ENODEV;
+
+ if (!eeh_ops || !eeh_ops->get_state)
+ return -ENOENT;
+
+ result = eeh_ops->get_state(pe, NULL);
+ if (!(result & EEH_STATE_RESET_ACTIVE) &&
+ (result & EEH_STATE_DMA_ENABLED) &&
+ (result & EEH_STATE_MMIO_ENABLED))
+ ret = EEH_PE_STATE_NORMAL;
+ else if (result & EEH_STATE_RESET_ACTIVE)
+ ret = EEH_PE_STATE_RESET;
+ else if (!(result & EEH_STATE_RESET_ACTIVE) &&
+ !(result & EEH_STATE_DMA_ENABLED) &&
+ !(result & EEH_STATE_MMIO_ENABLED))
+ ret = EEH_PE_STATE_STOPPED_IO_DMA;
+ else if (!(result & EEH_STATE_RESET_ACTIVE) &&
+ (result & EEH_STATE_DMA_ENABLED) &&
+ !(result & EEH_STATE_MMIO_ENABLED))
+ ret = EEH_PE_STATE_STOPPED_DMA;
+ else
+ ret = EEH_PE_STATE_UNAVAIL;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(eeh_pe_get_state);
+
+/**
+ * eeh_pe_reset - Issue PE reset according to specified type
+ * @pe: EEH PE
+ * @option: reset type
+ *
+ * The routine is called to reset the specified PE with the
+ * indicated type, either fundamental reset or hot reset.
+ * PE reset is the most important part for error recovery.
+ */
+int eeh_pe_reset(struct eeh_pe *pe, int option)
+{
+ int ret = 0;
+
+ /* Invalid PE ? */
+ if (!pe)
+ return -ENODEV;
+
+ if (!eeh_ops || !eeh_ops->set_option || !eeh_ops->reset)
+ return -ENOENT;
+
+ switch (option) {
+ case EEH_RESET_DEACTIVATE:
+ ret = eeh_ops->reset(pe, option);
+ if (ret)
+ break;
+
+ /*
+ * The PE is still in frozen state and we need to clear
+ * that. It's good to clear frozen state after deassert
+ * to avoid messy IO access during reset, which might
+ * cause recursive frozen PE.
+ */
+ ret = eeh_ops->set_option(pe, EEH_OPT_THAW_MMIO);
+ if (!ret)
+ ret = eeh_ops->set_option(pe, EEH_OPT_THAW_DMA);
+ if (!ret)
+ eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
+ break;
+ case EEH_RESET_HOT:
+ case EEH_RESET_FUNDAMENTAL:
+ ret = eeh_ops->reset(pe, option);
+ break;
+ default:
+ pr_debug("%s: Unsupported option %d\n",
+ __func__, option);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(eeh_pe_reset);
+
+/**
+ * eeh_pe_configure - Configure PCI bridges after PE reset
+ * @pe: EEH PE
+ *
+ * The routine is called to restore the PCI config space for
+ * those PCI devices, especially PCI bridges affected by PE
+ * reset issued previously.
+ */
+int eeh_pe_configure(struct eeh_pe *pe)
+{
+ int ret = 0;
+
+ /* Invalid PE ? */
+ if (!pe)
+ return -ENODEV;
+
+ /* Restore config space for the affected devices */
+ eeh_pe_restore_bars(pe);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(eeh_pe_configure);
+
static int proc_eeh_show(struct seq_file *m, void *v)
{
if (!eeh_enabled()) {
--
1.8.3.2
^ permalink raw reply related
* [PATCH v7 1/3] powerpc/eeh: Avoid event on passed PE
From: Gavin Shan @ 2014-05-27 8:40 UTC (permalink / raw)
To: kvm-ppc; +Cc: aik, agraf, Gavin Shan, alex.williamson, qiudayu, linuxppc-dev
In-Reply-To: <1401180052-6060-1-git-send-email-gwshan@linux.vnet.ibm.com>
If we detects frozen state on PE that has been passed through to somebody
else. we needn't handle it. Instead, we rely on the device's owner to
detect and recover it. The patch avoid EEH event on the frozen passed PE
so that the device's owner can have chance to handle that.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/eeh.h | 32 +++++++++++++++++++++++++++++++
arch/powerpc/kernel/eeh.c | 8 ++++++++
arch/powerpc/platforms/powernv/eeh-ioda.c | 3 ++-
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 7782056..34a2d83 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -72,6 +72,7 @@ struct device_node;
#define EEH_PE_RESET (1 << 2) /* PE reset in progress */
#define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */
+#define EEH_PE_PASSTHROUGH (1 << 9) /* PE owned by guest */
struct eeh_pe {
int type; /* PE type: PHB/Bus/Device */
@@ -93,6 +94,21 @@ struct eeh_pe {
#define eeh_pe_for_each_dev(pe, edev, tmp) \
list_for_each_entry_safe(edev, tmp, &pe->edevs, list)
+static inline bool eeh_pe_passed(struct eeh_pe *pe)
+{
+ return pe ? !!(pe->state & EEH_PE_PASSTHROUGH) : false;
+}
+
+static inline void eeh_pe_set_passed(struct eeh_pe *pe, bool passed)
+{
+ if (pe) {
+ if (passed)
+ pe->state |= EEH_PE_PASSTHROUGH;
+ else
+ pe->state &= ~EEH_PE_PASSTHROUGH;
+ }
+}
+
/*
* The struct is used to trace EEH state for the associated
* PCI device node or PCI device. In future, it might
@@ -110,6 +126,7 @@ struct eeh_pe {
#define EEH_DEV_SYSFS (1 << 9) /* Sysfs created */
#define EEH_DEV_REMOVED (1 << 10) /* Removed permanently */
#define EEH_DEV_FRESET (1 << 11) /* Fundamental reset */
+#define EEH_DEV_PASSTHROUGH (1 << 12) /* Owned by guest */
struct eeh_dev {
int mode; /* EEH mode */
@@ -138,6 +155,21 @@ static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev)
return edev ? edev->pdev : NULL;
}
+static inline bool eeh_dev_passed(struct eeh_dev *dev)
+{
+ return dev ? !!(dev->mode & EEH_DEV_PASSTHROUGH) : false;
+}
+
+static inline void eeh_dev_set_passed(struct eeh_dev *dev, bool passed)
+{
+ if (dev) {
+ if (passed)
+ dev->mode |= EEH_DEV_PASSTHROUGH;
+ else
+ dev->mode &= ~EEH_DEV_PASSTHROUGH;
+ }
+}
+
/* Return values from eeh_ops::next_error */
enum {
EEH_NEXT_ERR_NONE = 0,
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 9c6b899..3bc8b12 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -400,6 +400,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
if (ret > 0)
return ret;
+ /*
+ * If the PE isn't owned by us, we shouldn't check the
+ * state. Instead, let the owner handle it if the PE has
+ * been frozen.
+ */
+ if (eeh_pe_passed(pe))
+ return 0;
+
/* If we already have a pending isolation event for this
* slot, we know it's bad already, we don't need to check.
* Do this checking under a lock; as multiple PCI devices
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index cab3e62..79193eb 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -892,7 +892,8 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
opal_pci_eeh_freeze_clear(phb->opal_id, frozen_pe_no,
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
ret = EEH_NEXT_ERR_NONE;
- } else if ((*pe)->state & EEH_PE_ISOLATED) {
+ } else if ((*pe)->state & EEH_PE_ISOLATED ||
+ eeh_pe_passed(*pe)) {
ret = EEH_NEXT_ERR_NONE;
} else {
pr_err("EEH: Frozen PHB#%x-PE#%x (%s) detected\n",
--
1.8.3.2
^ permalink raw reply related
* [PATCH v7 0/3] EEH Support for VFIO PCI Device
From: Gavin Shan @ 2014-05-27 8:40 UTC (permalink / raw)
To: kvm-ppc; +Cc: aik, agraf, Gavin Shan, alex.williamson, qiudayu, linuxppc-dev
The series of patches intends to support EEH for PCI devices, which are
passed through to PowerKVM based guest via VFIO. The implementation is
straightforward based on the issues or problems we have to resolve to
support EEH for PowerKVM based guest.
- Emulation for EEH RTAS requests. All EEH RTAS requests goes to QEMU firstly.
If QEMU can't handle it, the request will be sent to host via newly introduced
VFIO container IOCTL command (VFIO_EEH_OP) and gets handled in host kernel.
The series of patches requires corresponding QEMU changes.
Change log
==========
v1 -> v2:
* EEH RTAS requests are routed to QEMU, and then possiblly to host kerenl.
The mechanism KVM in-kernel handling is dropped.
* Error injection is reimplemented based syscall, instead of KVM in-kerenl
handling. The logic for error injection token management is moved to
QEMU. The error injection request is routed to QEMU and then possiblly
to host kernel.
v2 -> v3:
* Make the fields in struct eeh_vfio_pci_addr, struct vfio_eeh_info based
on the comments from Alexey.
* Define macros for EEH VFIO operations (Alexey).
* Clear frozen state after successful PE reset.
* Merge original [PATCH 1/2/3] to one.
v3 -> v4:
* Remove the error injection from the patchset. Mike or I will work on that
later.
* Rename CONFIG_VFIO_EEH to VFIO_PCI_EEH.
* Rename the IOCTL command to VFIO_EEH_OP and it's handled by VFIO-PCI device
instead of VFIO container.
* Rename the IOCTL argument structure to "vfio_eeh_op" accordingly. Also, more
fields added to hold return values for RTAS requests.
* The address mapping stuff is totally removed. When opening or releasing VFIO
PCI device, notification sent to EEH to update the flags indicates the device
is passed to guest or not.
* Change pr_warn() to pr_debug() to avoid DOS as pointed by Alex.W
* Argument size check issue pointed by Alex.W.
v4 -> v5:
* Functions for VFIO PCI EEH support are moved to eeh.c and exported from there.
VFIO PCI driver just uses those functions to tackle IOCTL command VFIO_EEH_OP.
All of this is to make the code organized in a good way as suggested by Alex.G.
Another potential benefit is PowerNV/pSeries are sharing "eeh_ops" and same
infrastructure could possiblly work for KVM_PR and KVM_HV mode at the same time.
* Don't clear error injection registers after finishing PE reset as the patchset
is doing nothing related to error injection.
* Amending Documentation/vfio.txt, which was missed in last revision.
* No QEMU changes for this revision. "v4" works well. Also, remove "RFC" from the
subject as the design is basically recognized.
v5 -> v6:
* CONFIG_VFIO_PCI_EEH removed. Instead to use CONFIG_EEH.
* Split one ioctl command to 5.
* In eeh.c, description has been added for those exported functions. Also, the
functions have negative return values for error and information with other values.
All digital numbers have been replaced by macros defined in eeh.h. The comments,
including the function names have been amended not to mention "guest" or "vfio".
* Add one mutex to protect flag in eeh_dev_open()/release().
* More information on how to use those ioctl commands to Documentation/vfio.txt.
v6 -> v7:
* Remove ioctl command VFIO_EEH_PE_GET_ADDR, the PE address will be figured out
in userland (e.g. QEMU) as Alex.G suggested.
* Let sPAPR VFIO container process the ioctl commands as VFIO container is naturally
corresponds to IOMMU group (aka PE on sPAPR platform).
* All VFIO PCI EEH ioctl commands have "argsz+flags" for its companion data struct.
* For VFIO PCI EEH ioctl commands, ioctl() returns negative number to indicate error
or zero for success. Additinal output information is transported by the companion
data struct.
* Explaining PE in Documentation/vfio.txt, typo fixes, more comments suggested by
Alex.G.
* Split/merge patches according to suggestions from Alex.G and Alex.W.
* To have EEH stub in drivers/vfio/pci/, which was suggested by Alex.W.
* Define various EEH options as macros in vfio.h for userland to use.
Gavin Shan (3):
powerpc/eeh: Avoid event on passed PE
powerpc/eeh: EEH support for VFIO PCI device
drivers/vfio: EEH support for VFIO PCI device
Documentation/vfio.txt | 92 +++++++++++++++++++++++++++++++++++++++++++-
arch/powerpc/include/asm/eeh.h | 47 +++++++++++++++++++++++
arch/powerpc/kernel/eeh.c | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/platforms/powernv/eeh-ioda.c | 3 +-
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 ++++++++++++++++++++++++++++++++
10 files changed, 651 insertions(+), 8 deletions(-)
--
1.8.3.2
^ permalink raw reply
* [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Gavin Shan @ 2014-05-27 8:40 UTC (permalink / raw)
To: kvm-ppc; +Cc: aik, agraf, Gavin Shan, alex.williamson, qiudayu, linuxppc-dev
In-Reply-To: <1401180052-6060-1-git-send-email-gwshan@linux.vnet.ibm.com>
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
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>
+#ifdef CONFIG_EEH
+#include <asm/eeh.h>
+#endif
+
+#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);
+
#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
#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;
+ }
+ 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
+
+ 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);
}
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 */
+};
+
+#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;
+};
+
+#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 */
+};
+
+#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;
+};
+
+#define VFIO_EEH_PE_CONFIGURE _IO(VFIO_TYPE, VFIO_BASE + 24)
+
/* ***************************************************************** */
#endif /* _UAPIVFIO_H */
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH V4 0/2] mm: FAULT_AROUND_ORDER patchset performance data for powerpc
From: Kirill A. Shutemov @ 2014-05-27 10:21 UTC (permalink / raw)
To: Madhavan Srinivasan
Cc: linux-arch, riel, x86, dave.hansen, peterz, Rusty Russell,
Hugh Dickins, linux-kernel, linux-mm, ak, paulus, mgorman,
Andrew Morton, linuxppc-dev, mingo, Kirill A. Shutemov
In-Reply-To: <53842FB1.7090909@linux.vnet.ibm.com>
Madhavan Srinivasan wrote:
> On Tuesday 20 May 2014 03:57 PM, Kirill A. Shutemov wrote:
> > Rusty Russell wrote:
> >> "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> writes:
> >>> Andrew Morton wrote:
> >>>> On Mon, 19 May 2014 16:23:07 -0700 (PDT) Hugh Dickins <hughd@google.com> wrote:
> >>>>
> >>>>> Shouldn't FAULT_AROUND_ORDER and fault_around_order be changed to be
> >>>>> the order of the fault-around size in bytes, and fault_around_pages()
> >>>>> use 1UL << (fault_around_order - PAGE_SHIFT)
> >>>>
> >>>> Yes. And shame on me for missing it (this time!) at review.
> >>>>
> >>>> There's still time to fix this. Patches, please.
> >>>
> >>> Here it is. Made at 3.30 AM, build tested only.
> >>
> >> Prefer on top of Maddy's patch which makes it always a variable, rather
> >> than CONFIG_DEBUG_FS. It's got enough hair as it is.
> >
> > Something like this?
> >
> > From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
> > Date: Tue, 20 May 2014 13:02:03 +0300
> > Subject: [PATCH] mm: nominate faultaround area in bytes rather then page order
> >
> > There are evidences that faultaround feature is less relevant on
> > architectures with page size bigger then 4k. Which makes sense since
> > page fault overhead per byte of mapped area should be less there.
> >
> > Let's rework the feature to specify faultaround area in bytes instead of
> > page order. It's 64 kilobytes for now.
> >
> > The patch effectively disables faultaround on architectures with
> > page size >= 64k (like ppc64).
> >
> > It's possible that some other size of faultaround area is relevant for a
> > platform. We can expose `fault_around_bytes' variable to arch-specific
> > code once such platforms will be found.
> >
> > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> > ---
> > mm/memory.c | 62 +++++++++++++++++++++++--------------------------------------
> > 1 file changed, 23 insertions(+), 39 deletions(-)
> >
> > diff --git a/mm/memory.c b/mm/memory.c
> > index 037b812a9531..252b319e8cdf 100644
> > --- a/mm/memory.c
> > +++ b/mm/memory.c
> > @@ -3402,63 +3402,47 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address,
> > update_mmu_cache(vma, address, pte);
> > }
> >
> > -#define FAULT_AROUND_ORDER 4
> > +static unsigned long fault_around_bytes = 65536;
> > +
> > +static inline unsigned long fault_around_pages(void)
> > +{
> > + return rounddown_pow_of_two(fault_around_bytes) / PAGE_SIZE;
> > +}
> > +
> > +static inline unsigned long fault_around_mask(void)
> > +{
> > + return ~(rounddown_pow_of_two(fault_around_bytes) - 1) & PAGE_MASK;
> > +}
> >
> > -#ifdef CONFIG_DEBUG_FS
> > -static unsigned int fault_around_order = FAULT_AROUND_ORDER;
> >
> > -static int fault_around_order_get(void *data, u64 *val)
> > +#ifdef CONFIG_DEBUG_FS
> > +static int fault_around_bytes_get(void *data, u64 *val)
> > {
> > - *val = fault_around_order;
> > + *val = fault_around_bytes;
> > return 0;
> > }
> >
> > -static int fault_around_order_set(void *data, u64 val)
> > +static int fault_around_bytes_set(void *data, u64 val)
> > {
>
> Kindly ignore the question if not relevant. Even though we need root
> access to alter the value, will we be fine with
> negative value?.
val is u64. or I miss something?
--
Kirill A. Shutemov
^ permalink raw reply
* Re: [PATCH V4 0/2] mm: FAULT_AROUND_ORDER patchset performance data for powerpc
From: Madhavan Srinivasan @ 2014-05-27 10:44 UTC (permalink / raw)
To: Kirill A. Shutemov
Cc: linux-arch, riel, x86, dave.hansen, peterz, Rusty Russell,
Hugh Dickins, linux-kernel, linux-mm, ak, paulus, mgorman,
Andrew Morton, linuxppc-dev, mingo
In-Reply-To: <20140527102200.012BBE009B@blue.fi.intel.com>
On Tuesday 27 May 2014 03:51 PM, Kirill A. Shutemov wrote:
> Madhavan Srinivasan wrote:
>> On Tuesday 20 May 2014 03:57 PM, Kirill A. Shutemov wrote:
>>> Rusty Russell wrote:
>>>> "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> writes:
>>>>> Andrew Morton wrote:
>>>>>> On Mon, 19 May 2014 16:23:07 -0700 (PDT) Hugh Dickins <hughd@google.com> wrote:
>>>>>>
>>>>>>> Shouldn't FAULT_AROUND_ORDER and fault_around_order be changed to be
>>>>>>> the order of the fault-around size in bytes, and fault_around_pages()
>>>>>>> use 1UL << (fault_around_order - PAGE_SHIFT)
>>>>>>
>>>>>> Yes. And shame on me for missing it (this time!) at review.
>>>>>>
>>>>>> There's still time to fix this. Patches, please.
>>>>>
>>>>> Here it is. Made at 3.30 AM, build tested only.
>>>>
>>>> Prefer on top of Maddy's patch which makes it always a variable, rather
>>>> than CONFIG_DEBUG_FS. It's got enough hair as it is.
>>>
>>> Something like this?
>>>
>>> From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
>>> Date: Tue, 20 May 2014 13:02:03 +0300
>>> Subject: [PATCH] mm: nominate faultaround area in bytes rather then page order
>>>
>>> There are evidences that faultaround feature is less relevant on
>>> architectures with page size bigger then 4k. Which makes sense since
>>> page fault overhead per byte of mapped area should be less there.
>>>
>>> Let's rework the feature to specify faultaround area in bytes instead of
>>> page order. It's 64 kilobytes for now.
>>>
>>> The patch effectively disables faultaround on architectures with
>>> page size >= 64k (like ppc64).
>>>
>>> It's possible that some other size of faultaround area is relevant for a
>>> platform. We can expose `fault_around_bytes' variable to arch-specific
>>> code once such platforms will be found.
>>>
>>> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
>>> ---
>>> mm/memory.c | 62 +++++++++++++++++++++++--------------------------------------
>>> 1 file changed, 23 insertions(+), 39 deletions(-)
>>>
>>> diff --git a/mm/memory.c b/mm/memory.c
>>> index 037b812a9531..252b319e8cdf 100644
>>> --- a/mm/memory.c
>>> +++ b/mm/memory.c
>>> @@ -3402,63 +3402,47 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address,
>>> update_mmu_cache(vma, address, pte);
>>> }
>>>
>>> -#define FAULT_AROUND_ORDER 4
>>> +static unsigned long fault_around_bytes = 65536;
>>> +
>>> +static inline unsigned long fault_around_pages(void)
>>> +{
>>> + return rounddown_pow_of_two(fault_around_bytes) / PAGE_SIZE;
>>> +}
>>> +
>>> +static inline unsigned long fault_around_mask(void)
>>> +{
>>> + return ~(rounddown_pow_of_two(fault_around_bytes) - 1) & PAGE_MASK;
>>> +}
>>>
>>> -#ifdef CONFIG_DEBUG_FS
>>> -static unsigned int fault_around_order = FAULT_AROUND_ORDER;
>>>
>>> -static int fault_around_order_get(void *data, u64 *val)
>>> +#ifdef CONFIG_DEBUG_FS
>>> +static int fault_around_bytes_get(void *data, u64 *val)
>>> {
>>> - *val = fault_around_order;
>>> + *val = fault_around_bytes;
>>> return 0;
>>> }
>>>
>>> -static int fault_around_order_set(void *data, u64 val)
>>> +static int fault_around_bytes_set(void *data, u64 val)
>>> {
>>
>> Kindly ignore the question if not relevant. Even though we need root
>> access to alter the value, will we be fine with
>> negative value?.
> ppc
> val is u64. or I miss something?
>
My Bad. What I wanted to check was for all 0xf input and guess we are
fine. Sorry about that.
Regards
Maddy
^ permalink raw reply
* [PATCH] powerpc, kexec: Fix "Processor X is stuck" issue during kexec from ST mode
From: Srivatsa S. Bhat @ 2014-05-27 10:55 UTC (permalink / raw)
To: benh, paulus, ebiederm, vgoyal
Cc: ego, mahesh, kexec, linux-kernel, suzuki, Srivatsa S. Bhat,
linuxppc-dev
If we try to perform a kexec when the machine is in ST (Single-Threaded) mode
(ppc64_cpu --smt=off), the kexec operation doesn't succeed properly, and we
get the following messages during boot:
[ 0.089866] POWER8 performance monitor hardware support registered
[ 0.089985] power8-pmu: PMAO restore workaround active.
[ 5.095419] Processor 1 is stuck.
[ 10.097933] Processor 2 is stuck.
[ 15.100480] Processor 3 is stuck.
[ 20.102982] Processor 4 is stuck.
[ 25.105489] Processor 5 is stuck.
[ 30.108005] Processor 6 is stuck.
[ 35.110518] Processor 7 is stuck.
[ 40.113369] Processor 9 is stuck.
[ 45.115879] Processor 10 is stuck.
[ 50.118389] Processor 11 is stuck.
[ 55.120904] Processor 12 is stuck.
[ 60.123425] Processor 13 is stuck.
[ 65.125970] Processor 14 is stuck.
[ 70.128495] Processor 15 is stuck.
[ 75.131316] Processor 17 is stuck.
Note that only the sibling threads are stuck, while the primary threads (0, 8,
16 etc) boot just fine. Looking closer at the previous step of kexec, we observe
that kexec tries to wakeup (bring online) the sibling threads of all the cores,
before performing kexec:
[ 9464.131231] Starting new kernel
[ 9464.148507] kexec: Waking offline cpu 1.
[ 9464.148552] kexec: Waking offline cpu 2.
[ 9464.148600] kexec: Waking offline cpu 3.
[ 9464.148636] kexec: Waking offline cpu 4.
[ 9464.148671] kexec: Waking offline cpu 5.
[ 9464.148708] kexec: Waking offline cpu 6.
[ 9464.148743] kexec: Waking offline cpu 7.
[ 9464.148779] kexec: Waking offline cpu 9.
[ 9464.148815] kexec: Waking offline cpu 10.
[ 9464.148851] kexec: Waking offline cpu 11.
[ 9464.148887] kexec: Waking offline cpu 12.
[ 9464.148922] kexec: Waking offline cpu 13.
[ 9464.148958] kexec: Waking offline cpu 14.
[ 9464.148994] kexec: Waking offline cpu 15.
[ 9464.149030] kexec: Waking offline cpu 17.
Instrumenting this piece of code revealed that the cpu_up() operation actually
fails with -EBUSY. Thus, only the primary threads of all the cores are online
during kexec, and hence this is a sure-shot receipe for disaster, as explained
in commit e8e5c2155b (powerpc/kexec: Fix orphaned offline CPUs across kexec),
as well as in the comment above wake_offline_cpus().
It turns out that cpu_up() was returning -EBUSY because the variable
'cpu_hotplug_disabled' was set to 1; and this disabling of CPU hotplug was done
by migrate_to_reboot_cpu() inside kernel_kexec().
Now, migrate_to_reboot_cpu() was originally written with the assumption that
any further code will not need to perform CPU hotplug, since we are anyway in
the reboot path. However, kexec is clearly not such a case, since we depend on
onlining CPUs, atleast on powerpc.
So re-enable cpu-hotplug after returning from migrate_to_reboot_cpu() in the
kexec path, to fix this regression in kexec on powerpc.
Also, wrap the cpu_up() in powerpc kexec code within a WARN_ON(), so that we
can catch such issues more easily in the future.
Fixes: c97102ba963 (kexec: migrate to reboot cpu)
Cc: stable@vger.kernel.org
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
---
arch/powerpc/kernel/machine_kexec_64.c | 2 +-
kernel/kexec.c | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 59d229a..879b3aa 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -237,7 +237,7 @@ static void wake_offline_cpus(void)
if (!cpu_online(cpu)) {
printk(KERN_INFO "kexec: Waking offline cpu %d.\n",
cpu);
- cpu_up(cpu);
+ WARN_ON(cpu_up(cpu));
}
}
}
diff --git a/kernel/kexec.c b/kernel/kexec.c
index c8380ad..28c5706 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1683,6 +1683,14 @@ int kernel_kexec(void)
kexec_in_progress = true;
kernel_restart_prepare(NULL);
migrate_to_reboot_cpu();
+
+ /*
+ * migrate_to_reboot_cpu() disables CPU hotplug assuming that
+ * no further code needs to use CPU hotplug (which is true in
+ * the reboot case). However, the kexec path depends on using
+ * CPU hotplug again; so re-enable it here.
+ */
+ cpu_hotplug_enable();
printk(KERN_EMERG "Starting new kernel\n");
machine_shutdown();
}
^ permalink raw reply related
* Re: [V6 00/11] perf: New conditional branch filter
From: Stephane Eranian @ 2014-05-27 12:09 UTC (permalink / raw)
To: Anshuman Khandual
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: <1399280953-31442-1-git-send-email-khandual@linux.vnet.ibm.com>
Hi,
On Mon, May 5, 2014 at 11:09 AM, Anshuman Khandual
<khandual@linux.vnet.ibm.com> wrote:
>
> This patchset is the re-spin of the original branch stack sampling
> patchset which introduced new PERF_SAMPLE_BRANCH_COND branch filter. This patchset
> also enables SW based branch filtering support for book3s powerpc platforms which
> have PMU HW backed branch stack sampling support.
>
> Summary of code changes in this patchset:
>
> (1) Introduces a new PERF_SAMPLE_BRANCH_COND branch filter
> (2) Add the "cond" branch filter options in the "perf record" tool
> (3) Enable PERF_SAMPLE_BRANCH_COND in X86 platforms
> (4) Enable PERF_SAMPLE_BRANCH_COND in POWER8 platform
> (5) Update the documentation regarding "perf record" tool
> (6) Add some new powerpc instruction analysis functions in code-patching library
> (7) Enable SW based branch filter support for powerpc book3s
> (8) Changed BHRB configuration in POWER8 to accommodate SW branch filters
>
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.
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.
when eliminating the bogus entries, my tests yielded only return
branch instruction addresses
which is good. Will run more tests.
> With this new SW enablement, the branch filter support for book3s platforms have
> been extended to include all these combinations discussed below with a sample test
> application program (included here).
>
> Changes in V2
> =============
> (1) Enabled PPC64 SW branch filtering support
> (2) Incorporated changes required for all previous comments
>
> Changes in V3
> =============
> (1) Split the SW branch filter enablement into multiple patches
> (2) Added PMU neutral SW branch filtering code, PMU specific HW branch filtering code
> (3) Added new instruction analysis functionality into powerpc code-patching library
> (4) Changed name for some of the functions
> (5) Fixed couple of spelling mistakes
> (6) Changed code documentation in multiple places
>
> Changes in V4
> =============
> (1) Changed the commit message for patch (01/10)
> (2) Changed the patch (02/10) to accommodate review comments from Michael Ellerman
> (3) Rebased the patchset against latest Linus's tree
>
> Changes in V5
> =============
> (1) Added a precursor patch to cleanup the indentation problem in power_pmu_bhrb_read
> (2) Added a precursor patch to re-arrange P8 PMU BHRB filter config which improved the clarity
> (3) Merged the previous 10th patch into the 8th patch
> (4) Moved SW based branch analysis code from core perf into code-patching library as suggested by Michael
> (5) Simplified the logic in branch analysis library
> (6) Fixed some ambiguities in documentation at various places
> (7) Added some more in-code documentation blocks at various places
> (8) Renamed some local variable and function names
> (9) Fixed some indentation and white space errors in the code
> (10) Implemented almost all the review comments and suggestions made by Michael Ellerman on V4 patchset
> (11) Enabled privilege mode SW branch filter
> (12) Simplified and generalized the SW implemented conditional branch filter
> (13) PERF_SAMPLE_BRANCH_COND filter is now supported only through SW implementation
> (14) Adjusted other patches to deal with the above changes
>
> Changes in V6
> =============
> (1) Rebased the patchset against the master
> (2) Added "Reviewed-by: Andi Kleen" in the first four patches in the series which changes the
> generic or X86 perf code. [https://lkml.org/lkml/2014/4/7/130]
>
> HW implemented branch filters
> =============================
>
> (1) perf record -j any_call -e branch-misses:u ./cprog
>
> # Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
> # ........ ....... .................... ....................... .................... ....................
> #
> 7.85% cprog cprog [.] sw_3_1 cprog [.] success_3_1_2
> 5.66% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_2
> 5.65% cprog cprog [.] hw_1_1 cprog [.] symbol1
> 5.42% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_3
> 5.40% cprog cprog [.] callme cprog [.] hw_1_1
> 5.40% cprog cprog [.] sw_3_1 cprog [.] success_3_1_1
> 5.40% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_1
> 5.39% cprog cprog [.] sw_4_2 cprog [.] lr_addr
> 5.39% cprog cprog [.] callme cprog [.] sw_4_2
> 5.39% cprog [unknown] [.] 00000000 cprog [.] ctr_addr
> 5.38% cprog cprog [.] hw_1_2 cprog [.] symbol2
> 5.38% cprog cprog [.] callme cprog [.] hw_1_2
> 5.16% cprog cprog [.] sw_3_1 cprog [.] success_3_1_3
> 5.15% cprog cprog [.] callme cprog [.] sw_3_2
> 5.14% cprog cprog [.] callme cprog [.] hw_2_2
> 2.96% cprog cprog [.] callme cprog [.] sw_3_1
> 2.94% cprog cprog [.] callme cprog [.] hw_2_1
> 2.71% cprog cprog [.] main cprog [.] callme
> 2.71% cprog [unknown] [.] 00000000 cprog [.] lr_addr
> 2.70% cprog cprog [.] sw_4_1 cprog [.] ctr_addr
> 2.70% cprog cprog [.] callme cprog [.] sw_4_1
> 0.09% cprog [unknown] [.] 0xf7ad76c4 [unknown] [.] 0xf7ac22c0
> 0.00% cprog libc-2.11.2.so [.] vfprintf libc-2.11.2.so [.] __errno_location
> 0.00% cprog libc-2.11.2.so [.] printf libc-2.11.2.so [.] vfprintf
> 0.00% cprog libc-2.11.2.so [.] _IO_file_doallocate libc-2.11.2.so [.] isatty
> 0.00% cprog libc-2.11.2.so [.] _IO_file_doallocate libc-2.11.2.so [.] mmap
> 0.00% cprog libc-2.11.2.so [.] isatty libc-2.11.2.so [.] tcgetattr
> 0.00% cprog cprog [.] main [unknown] [.] 0x10000950
> 0.00% cprog [unknown] [.] 00000000 libc-2.11.2.so [.] _IO_file_stat
> 0.00% cprog [unknown] [.] 0xf7acfca4 cprog [.] _fini
> 0.00% cprog [unknown] [k] 00000000 cprog [k] ctr_addr
> 0.00% cprog [unknown] [k] 00000000 cprog [k] lr_addr
>
> SW implemented branch filters
> =============================
>
> (2) perf record -j cond -e branch-misses:u ./cprog
>
> # Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
> # ........ ....... .................... ...................... .................... ......................
> #
> 25.82% cprog [unknown] [.] 00000000 cprog [.] sw_3_1
> 12.66% cprog cprog [.] sw_4_2 cprog [.] lr_addr
> 12.63% cprog [unknown] [.] 00000000 cprog [.] callme
> 9.42% cprog cprog [.] hw_2_2 cprog [.] address2
> 9.39% cprog cprog [.] sw_3_1 cprog [.] success_3_1_2
> 4.91% cprog cprog [.] sw_3_1 cprog [.] success_3_1_1
> 4.91% cprog cprog [.] sw_3_1 cprog [.] success_3_1_3
> 3.35% cprog cprog [.] sw_3_1_3 cprog [.] sw_3_1
> 3.34% cprog cprog [.] sw_3_1_1 cprog [.] sw_3_1
> 3.31% cprog cprog [.] hw_1_2 cprog [.] symbol2
> 3.31% cprog cprog [.] sw_4_1 cprog [.] ctr_addr
> 3.29% cprog cprog [.] hw_2_1 cprog [.] address1
> 3.27% cprog cprog [.] sw_3_1_2 cprog [.] sw_3_1
> 0.32% cprog [unknown] [.] 0xf7c62328 [unknown] [.] 0xf7c62320
> 0.01% cprog libc-2.11.2.so [.] vfprintf libc-2.11.2.so [.] vfprintf
> 0.01% cprog libc-2.11.2.so [.] _IO_file_xsputn libc-2.11.2.so [.] _IO_file_xsputn
> 0.01% cprog libc-2.11.2.so [.] _IO_default_xsputn libc-2.11.2.so [.] _IO_default_xsputn
> 0.01% cprog libc-2.11.2.so [.] strchrnul libc-2.11.2.so [.] strchrnul
> 0.01% cprog [unknown] [.] 00000000 libc-2.11.2.so [.] _IO_file_xsputn
> 0.01% cprog [unknown] [k] 00000000 cprog [k] callme
>
>
> (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
> 3.13% cprog cprog [.] sw_3_1_1 cprog [.] sw_3_1
> 3.12% cprog cprog [.] back2 cprog [.] callme
> 3.12% cprog cprog [.] sw_3_1 cprog [.] callme
> 3.11% cprog cprog [.] back1 cprog [.] callme
> 3.11% cprog cprog [.] sw_3_1_2 cprog [.] sw_3_1
> 3.11% cprog cprog [.] sw_3_1_3 cprog [.] sw_3_1
> 3.10% cprog cprog [.] sw_3_2 cprog [.] callme
> 3.09% cprog cprog [.] success_3_1_2 cprog [.] sw_3_1
> 0.03% cprog [unknown] [.] 0x100009b0 [unknown] [.] 0xf7d5581c
> 0.01% cprog libc-2.11.2.so [.] _IO_file_overflow libc-2.11.2.so [.] _IO_file_xsputn
> 0.01% cprog libc-2.11.2.so [.] _IO_file_setbuf [unknown] [.] 0x0fee1084
> 0.01% cprog [unknown] [.] 0xf7d5589c libc-2.11.2.so [.] printf
> 0.01% cprog [unknown] [.] 00000000 libc-2.11.2.so [.] _IO_file_overflow
> 0.01% cprog [unknown] [.] 00000000 libc-2.11.2.so [.] _IO_file_setbuf
> 0.01% cprog [unknown] [k] 00000000 cprog [k] callme
>
> (4) perf record -j ind_call -e branch-misses:u ./cprog
>
> # Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
> # ........ ....... .................... .............. .................... .....................
> #
> 42.59% cprog [unknown] [.] 00000000 cprog [.] sw_3_1
> 25.88% cprog cprog [.] sw_4_2 cprog [.] lr_addr
> 25.65% cprog [unknown] [.] 00000000 cprog [.] callme
> 5.58% cprog cprog [.] sw_4_1 cprog [.] ctr_addr
> 0.23% cprog [unknown] [k] 00000000 cprog [k] callme
> 0.05% cprog [unknown] [.] 00000000 [unknown] [.] 0xf79fd740
> 0.03% cprog [unknown] [.] 00000000 libc-2.11.2.so [.] _IO_file_overflow
>
>
> (5) perf record -j any_call,any_ret -e branch-misses:u ./cprog
>
> # Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
> # ........ ....... .................... ......................... .................... .....................
> #
> 10.00% cprog [unknown] [.] 00000000 cprog [.] sw_3_1
> 4.20% cprog cprog [.] sw_4_2 cprog [.] lr_addr
> 4.17% cprog cprog [.] lr_addr cprog [.] sw_4_2
> 4.16% cprog cprog [.] symbol1 cprog [.] hw_1_1
> 4.12% cprog [unknown] [.] 00000000 cprog [.] callme
> 4.12% cprog cprog [.] symbol2 cprog [.] hw_1_2
> 4.11% cprog cprog [.] success_3_1_3 cprog [.] sw_3_1
> 4.11% cprog cprog [.] ctr_addr cprog [.] sw_4_1
> 4.10% cprog cprog [.] sw_4_2 cprog [.] callme
> 2.42% cprog cprog [.] callme cprog [.] sw_4_2
> 2.40% cprog cprog [.] sw_3_1_3 cprog [.] sw_3_1
> 2.40% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_3
> 2.39% cprog cprog [.] hw_1_2 cprog [.] symbol2
> 2.39% cprog cprog [.] back1 cprog [.] callme
> 2.39% cprog cprog [.] sw_3_1_1 cprog [.] sw_3_1
> 2.39% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_1
> 2.39% cprog cprog [.] sw_3_1 cprog [.] callme
> 2.39% cprog cprog [.] sw_4_1 cprog [.] ctr_addr
> 2.39% cprog cprog [.] callme cprog [.] hw_1_2
> 2.39% cprog cprog [.] callme cprog [.] sw_3_1
> 2.39% cprog cprog [.] sw_3_1_2 cprog [.] sw_3_1
> 2.39% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_2
> 2.38% cprog cprog [.] hw_1_1 cprog [.] symbol1
> 2.38% cprog cprog [.] callme cprog [.] hw_1_1
> 1.78% cprog cprog [.] back2 cprog [.] callme
> 1.78% cprog cprog [.] hw_1_1 cprog [.] callme
> 1.76% cprog cprog [.] success_3_1_2 cprog [.] sw_3_1
> 1.76% cprog cprog [.] sw_3_1 cprog [.] success_3_1_2
> 1.76% cprog cprog [.] sw_3_2 cprog [.] callme
> 1.76% cprog cprog [.] callme cprog [.] sw_3_2
> 1.73% cprog cprog [.] success_3_1_1 cprog [.] sw_3_1
> 1.73% cprog cprog [.] sw_3_1 cprog [.] success_3_1_1
> 1.73% cprog cprog [.] hw_1_2 cprog [.] callme
> 1.71% cprog cprog [.] sw_3_1 cprog [.] success_3_1_3
> 1.71% cprog cprog [.] sw_4_1 cprog [.] callme
> 1.71% cprog cprog [.] callme cprog [.] main
> 0.05% cprog [unknown] [k] 00000000 cprog [k] callme
> 0.03% cprog [unknown] [.] 0xf7aa9d4c [unknown] [.] 0xf7aa5f80
> 0.01% cprog libc-2.11.2.so [.] __errno_location libc-2.11.2.so [.] vfprintf
> 0.01% cprog libc-2.11.2.so [.] vfprintf libc-2.11.2.so [.] __errno_location
> 0.01% cprog libc-2.11.2.so [.] _IO_doallocbuf libc-2.11.2.so [.] _IO_file_overflow
> 0.01% cprog cprog [.] __do_global_dtors_aux [unknown] [.] 0xf7a9fc74
> 0.01% cprog [unknown] [.] 0xf7a9fca4 cprog [.] _fini
>
> (6) perf record -j any_call,ind_call -e branch-misses:u ./cprog
>
> # Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
> # ........ ....... .................... ...................... .................... ......................
> #
> 17.38% cprog [unknown] [.] 00000000 cprog [.] sw_3_1
> 7.76% cprog cprog [.] sw_4_2 cprog [.] lr_addr
> 7.64% cprog [unknown] [.] 00000000 cprog [.] callme
> 6.00% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_1
> 6.00% cprog cprog [.] callme cprog [.] sw_3_1
> 5.98% cprog cprog [.] sw_4_1 cprog [.] ctr_addr
> 5.97% cprog cprog [.] hw_1_1 cprog [.] symbol1
> 5.97% cprog cprog [.] hw_1_2 cprog [.] symbol2
> 5.97% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_3
> 5.97% cprog cprog [.] callme cprog [.] hw_1_1
> 5.97% cprog cprog [.] callme cprog [.] hw_1_2
> 5.96% cprog cprog [.] callme cprog [.] sw_4_2
> 5.95% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_2
> 1.83% cprog cprog [.] sw_3_1 cprog [.] success_3_1_2
> 1.82% cprog cprog [.] sw_3_1 cprog [.] success_3_1_1
> 1.82% cprog cprog [.] sw_3_1 cprog [.] success_3_1_3
> 1.82% cprog cprog [.] callme cprog [.] sw_3_2
> 0.14% cprog [unknown] [k] 00000000 cprog [k] callme
> 0.01% cprog libc-2.11.2.so [.] vfprintf libc-2.11.2.so [.] strchrnul
> 0.01% cprog libc-2.11.2.so [.] _IO_file_xsputn libc-2.11.2.so [.] _IO_default_xsputn
> 0.01% cprog libc-2.11.2.so [.] _IO_default_xsputn libc-2.11.2.so [.] _IO_file_overflow
> 0.01% cprog ld-2.11.2.so [.] calloc [unknown] [.] 0xf795b390
> 0.01% cprog [unknown] [.] 0x0fee00fc libc-2.11.2.so [.] _IO_file_overflow
> 0.01% cprog [unknown] [.] 00000000 ld-2.11.2.so [.] calloc
> 0.01% cprog [unknown] [.] 0xf794b41c [unknown] [.] 0xf794ab70
>
> (7) perf record -j cond,any_ret -e branch-misses:u ./cprog
>
> # Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
> # ........ ....... .................... ...................... .................... ......................
> #
> 12.43% cprog [unknown] [.] 00000000 cprog [.] sw_3_1
> 4.91% cprog cprog [.] lr_addr cprog [.] sw_4_2
> 4.89% cprog [unknown] [.] 00000000 cprog [.] callme
> 4.87% cprog cprog [.] sw_4_2 cprog [.] lr_addr
> 4.87% cprog cprog [.] symbol1 cprog [.] hw_1_1
> 4.19% cprog cprog [.] hw_2_2 cprog [.] address2
> 4.19% cprog cprog [.] back2 cprog [.] callme
> 4.19% cprog cprog [.] sw_3_2 cprog [.] callme
> 4.18% cprog cprog [.] hw_1_1 cprog [.] callme
> 4.18% cprog cprog [.] success_3_1_2 cprog [.] sw_3_1
> 4.18% cprog cprog [.] sw_3_1 cprog [.] success_3_1_2
> 4.16% cprog cprog [.] sw_4_2 cprog [.] callme
> 4.13% cprog cprog [.] ctr_addr cprog [.] sw_4_1
> 4.12% cprog cprog [.] symbol2 cprog [.] hw_1_2
> 4.12% cprog cprog [.] success_3_1_3 cprog [.] sw_3_1
> 3.43% cprog cprog [.] callme cprog [.] main
> 3.42% cprog cprog [.] sw_3_1 cprog [.] success_3_1_3
> 3.41% cprog cprog [.] success_3_1_1 cprog [.] sw_3_1
> 3.41% cprog cprog [.] sw_3_1 cprog [.] success_3_1_1
> 3.41% cprog cprog [.] sw_4_1 cprog [.] callme
> 3.40% cprog cprog [.] hw_1_2 cprog [.] callme
> 0.73% cprog cprog [.] sw_3_1_3 cprog [.] sw_3_1
> 0.73% cprog cprog [.] sw_4_1 cprog [.] ctr_addr
> 0.72% cprog cprog [.] hw_1_2 cprog [.] symbol2
> 0.72% cprog cprog [.] sw_3_1_1 cprog [.] sw_3_1
> 0.70% cprog cprog [.] hw_2_1 cprog [.] address1
> 0.70% cprog cprog [.] back1 cprog [.] callme
> 0.70% cprog cprog [.] sw_3_1_2 cprog [.] sw_3_1
> 0.70% cprog cprog [.] sw_3_1 cprog [.] callme
> 0.19% cprog [unknown] [.] 0xf7c12328 [unknown] [.] 0xf7c12320
> 0.01% cprog libc-2.11.2.so [.] __errno_location libc-2.11.2.so [.] vfprintf
> 0.01% cprog libc-2.11.2.so [.] vfprintf libc-2.11.2.so [.] vfprintf
> 0.01% cprog libc-2.11.2.so [.] _IO_file_overflow [unknown] [.] 0x0fee0100
> 0.01% cprog libc-2.11.2.so [.] _IO_default_xsputn libc-2.11.2.so [.] _IO_default_xsputn
> 0.01% cprog [unknown] [.] 00000000 libc-2.11.2.so [.] _IO_file_overflow
>
> (8) perf record -j cond,ind_call -e branch-misses:u ./cprog
>
> # Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
> # ........ ....... .................... .............. .................... .................
> #
> 20.70% cprog [unknown] [.] 00000000 cprog [.] sw_3_1
> 9.99% cprog cprog [.] sw_4_2 cprog [.] lr_addr
> 9.91% cprog [unknown] [.] 00000000 cprog [.] callme
> 9.45% cprog cprog [.] sw_3_1_3 cprog [.] sw_3_1
> 9.44% cprog cprog [.] hw_2_1 cprog [.] address1
> 9.43% cprog cprog [.] sw_3_1_1 cprog [.] sw_3_1
> 9.42% cprog cprog [.] hw_1_2 cprog [.] symbol2
> 9.42% cprog cprog [.] sw_3_1_2 cprog [.] sw_3_1
> 9.42% cprog cprog [.] sw_4_1 cprog [.] ctr_addr
> 0.65% cprog cprog [.] sw_3_1 cprog [.] success_3_1_1
> 0.62% cprog cprog [.] sw_3_1 cprog [.] success_3_1_3
> 0.56% cprog cprog [.] hw_2_2 cprog [.] address2
> 0.55% cprog cprog [.] sw_3_1 cprog [.] success_3_1_2
> 0.29% cprog [unknown] [.] 0xf7f72328 [unknown] [.] 0xf7f72320
> 0.10% cprog [unknown] [k] 00000000 cprog [k] callme
> 0.02% cprog libc-2.11.2.so [.] _IO_setb libc-2.11.2.so [.] _IO_setb
>
> (9) perf record -e branch-misses:u -j any_call,any_ret,ind_call,cond ./cprog
>
> # Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
> # ........ ....... .................... .................. .................... .......................
> #
> 9.31% cprog [unknown] [.] 00000000 cprog [.] sw_3_1
> 4.04% cprog cprog [.] symbol1 cprog [.] hw_1_1
> 4.03% cprog cprog [.] lr_addr cprog [.] sw_4_2
> 4.03% cprog cprog [.] sw_4_2 cprog [.] lr_addr
> 4.00% cprog [unknown] [.] 00000000 cprog [.] callme
> 3.88% cprog cprog [.] ctr_addr cprog [.] sw_4_1
> 3.87% cprog cprog [.] sw_4_2 cprog [.] callme
> 3.86% cprog cprog [.] symbol2 cprog [.] hw_1_2
> 3.86% cprog cprog [.] success_3_1_3 cprog [.] sw_3_1
> 2.49% cprog cprog [.] sw_4_1 cprog [.] ctr_addr
> 2.47% cprog cprog [.] hw_1_1 cprog [.] symbol1
> 2.47% cprog cprog [.] sw_3_1_1 cprog [.] sw_3_1
> 2.47% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_1
> 2.47% cprog cprog [.] callme cprog [.] hw_1_1
> 2.47% cprog cprog [.] callme cprog [.] sw_3_1
> 2.47% cprog cprog [.] hw_1_2 cprog [.] symbol2
> 2.47% cprog cprog [.] hw_2_1 cprog [.] address1
> 2.47% cprog cprog [.] back1 cprog [.] callme
> 2.47% cprog cprog [.] sw_3_1_3 cprog [.] sw_3_1
> 2.47% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_3
> 2.47% cprog cprog [.] sw_3_1 cprog [.] callme
> 2.47% cprog cprog [.] callme cprog [.] hw_1_2
> 2.47% cprog cprog [.] callme cprog [.] sw_4_2
> 2.46% cprog cprog [.] sw_3_1_2 cprog [.] sw_3_1
> 2.46% cprog cprog [.] sw_3_1 cprog [.] sw_3_1_2
> 1.57% cprog cprog [.] success_3_1_2 cprog [.] sw_3_1
> 1.57% cprog cprog [.] sw_3_1 cprog [.] success_3_1_2
> 1.57% cprog cprog [.] hw_1_1 cprog [.] callme
> 1.56% cprog cprog [.] hw_2_2 cprog [.] address2
> 1.56% cprog cprog [.] back2 cprog [.] callme
> 1.56% cprog cprog [.] sw_3_2 cprog [.] callme
> 1.56% cprog cprog [.] callme cprog [.] sw_3_2
> 1.41% cprog cprog [.] success_3_1_1 cprog [.] sw_3_1
> 1.41% cprog cprog [.] sw_3_1 cprog [.] success_3_1_1
> 1.40% cprog cprog [.] sw_4_1 cprog [.] callme
> 1.39% cprog cprog [.] hw_1_2 cprog [.] callme
> 1.39% cprog cprog [.] sw_3_1 cprog [.] success_3_1_3
> 1.39% cprog cprog [.] callme cprog [.] main
> 0.14% cprog [unknown] [.] 0xf7d72328 [unknown] [.] 0xf7d72320
> 0.03% cprog [unknown] [k] 00000000 cprog [k] callme
> 0.01% cprog libc-2.11.2.so [.] _IO_doallocbuf libc-2.11.2.so [.] _IO_doallocbuf
> 0.01% cprog libc-2.11.2.so [.] printf cprog [.] main
> 0.01% cprog libc-2.11.2.so [.] _IO_doallocbuf libc-2.11.2.so [.] _IO_file_doallocate
> 0.01% cprog ld-2.11.2.so [.] malloc [unknown] [.] 0xf7d8b380
> 0.01% cprog cprog [.] main [unknown] [.] 0x0fe7f63c
> 0.01% cprog [unknown] [.] 0xf7d8b388 ld-2.11.2.so [.] __libc_memalign
> 0.01% cprog [unknown] [.] 00000000 ld-2.11.2.so [.] malloc
>
> Please refer to the V4 version of the patchset to learn about the sample test case and it's makefile.
>
> Anshuman Khandual (11):
> perf: Add PERF_SAMPLE_BRANCH_COND
> perf, tool: Conditional branch filter 'cond' added to perf record
> x86, perf: Add conditional branch filtering support
> perf, documentation: Description for conditional branch filter
> powerpc, perf: Re-arrange BHRB processing
> powerpc, perf: Re-arrange PMU based branch filter processing in POWER8
> powerpc, perf: Change the name of HW PMU branch filter tracking variable
> powerpc, lib: Add new branch analysis support functions
> powerpc, perf: Enable SW filtering in branch stack sampling framework
> power8, perf: Adapt BHRB PMU configuration to work with SW filters
> powerpc, perf: Enable privilege mode SW branch filters
>
> arch/powerpc/include/asm/code-patching.h | 16 ++
> arch/powerpc/include/asm/perf_event_server.h | 6 +-
> arch/powerpc/lib/code-patching.c | 80 +++++++
> arch/powerpc/perf/core-book3s.c | 323 ++++++++++++++++++++++-----
> arch/powerpc/perf/power8-pmu.c | 70 ++++--
> arch/x86/kernel/cpu/perf_event_intel_lbr.c | 5 +
> include/uapi/linux/perf_event.h | 3 +-
> tools/perf/Documentation/perf-record.txt | 3 +-
> tools/perf/builtin-record.c | 1 +
> 9 files changed, 429 insertions(+), 78 deletions(-)
>
> --
> 1.7.11.7
>
^ permalink raw reply
* Re: [2/2] powerpc/corenet64_smp_defconfig: enable RTC support
From: Kumar Gala @ 2014-05-27 15:33 UTC (permalink / raw)
To: Shengzhou.Liu; +Cc: Scott Wood, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <a1c1a49caf9f4f2b82b517c5c2d598d1@DM2PR03MB398.namprd03.prod.outlook.com>
On May 25, 2014, at 10:08 PM, Shengzhou.Liu@freescale.com wrote:
>=20
>> -----Original Message-----
>> From: Wood Scott-B07421
>> Sent: Saturday, May 24, 2014 1:06 AM
>> To: Liu Shengzhou-B36685
>> Cc: linuxppc-dev@lists.ozlabs.org
>> Subject: Re: [2/2] powerpc/corenet64_smp_defconfig: enable RTC =
support
>>=20
>> On Fri, 2014-05-23 at 03:03 -0500, Liu Shengzhou-B36685 wrote:
>>>> -----Original Message-----
>>>> From: Wood Scott-B07421
>>>> Sent: Friday, May 23, 2014 6:52 AM
>>>> To: Liu Shengzhou-B36685
>>>> Cc: linuxppc-dev@lists.ozlabs.org
>>>> Subject: Re: [2/2] powerpc/corenet64_smp_defconfig: enable RTC
>>>> support
>>>>=20
>>>>> +++ b/arch/powerpc/configs/corenet64_smp_defconfig
>>>>> @@ -125,6 +125,11 @@ CONFIG_USB_EHCI_FSL=3Dy CONFIG_USB_STORAGE=3Dy=
>>>>> CONFIG_MMC=3Dy CONFIG_MMC_SDHCI=3Dy
>>>>> +CONFIG_RTC_CLASS=3Dy
>>>>> +CONFIG_RTC_DRV_CMOS=3Dy
>>>>> +CONFIG_RTC_DRV_DS1307=3Dy
>>>>> +CONFIG_RTC_DRV_DS1374=3Dy
>>>>> +CONFIG_RTC_DRV_DS3232=3Dy
>>>>> CONFIG_EDAC=3Dy
>>>>> CONFIG_EDAC_MM_EDAC=3Dy
>>>>> CONFIG_DMADEVICES=3Dy
>>>>=20
>>>> Why only corenet64 and not corenet32?
>>>>=20
>>>> -Scott
>>> [Shengzhou] There is already RTC support in corenet32, only missing =
in
>> corenet64.
>>=20
>> Only DS3232, not DS1307 or DS1374. Which boards use the latter two?
>>=20
>> Why do we need CONFIG_RTC_DRV_CMOS?
>>=20
>> -Scott
>>=20
> [Shengzhou] so far DS1307 and DS1374 occur only on those boards with =
corenet64.=20
> CONFIG_RTC_DRV_CMOS is enabled in mpc85xx_defconfig, =
mpc85xx_smp_defconfig, corenet32_smp_defconfig, etc, here keeps =
consistent in corenet64.
> It seems CONFIG_RTC_DRV_CMOS is not needed on 85xx platform, do we =
need to remove CONFIG_RTC_DRV_CMOS from all 85xx/corenet defconfig? If =
so, I will post a new patch to do it.
The CDS board uses an RTC over ISA if I remember correctly, not sure =
what driver deals with that (if its CONFIG_RTC_DRV_CMOS) or something =
else.
- k=
^ permalink raw reply
* Re: [2/2] powerpc/corenet64_smp_defconfig: enable RTC support
From: Scott Wood @ 2014-05-27 16:21 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev@lists.ozlabs.org, Shengzhou.Liu
In-Reply-To: <DA0A87E9-4152-4A7F-9399-20206E13ACFB@kernel.crashing.org>
On Tue, 2014-05-27 at 10:33 -0500, Kumar Gala wrote:
> On May 25, 2014, at 10:08 PM, Shengzhou.Liu@freescale.com wrote:
>
> >
> >> -----Original Message-----
> >> From: Wood Scott-B07421
> >> Sent: Saturday, May 24, 2014 1:06 AM
> >> To: Liu Shengzhou-B36685
> >> Cc: linuxppc-dev@lists.ozlabs.org
> >> Subject: Re: [2/2] powerpc/corenet64_smp_defconfig: enable RTC support
> >>
> >> On Fri, 2014-05-23 at 03:03 -0500, Liu Shengzhou-B36685 wrote:
> >>>> -----Original Message-----
> >>>> From: Wood Scott-B07421
> >>>> Sent: Friday, May 23, 2014 6:52 AM
> >>>> To: Liu Shengzhou-B36685
> >>>> Cc: linuxppc-dev@lists.ozlabs.org
> >>>> Subject: Re: [2/2] powerpc/corenet64_smp_defconfig: enable RTC
> >>>> support
> >>>>
> >>>>> +++ b/arch/powerpc/configs/corenet64_smp_defconfig
> >>>>> @@ -125,6 +125,11 @@ CONFIG_USB_EHCI_FSL=y CONFIG_USB_STORAGE=y
> >>>>> CONFIG_MMC=y CONFIG_MMC_SDHCI=y
> >>>>> +CONFIG_RTC_CLASS=y
> >>>>> +CONFIG_RTC_DRV_CMOS=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
> >>>>
> >>>> Why only corenet64 and not corenet32?
> >>>>
> >>>> -Scott
> >>> [Shengzhou] There is already RTC support in corenet32, only missing in
> >> corenet64.
> >>
> >> Only DS3232, not DS1307 or DS1374. Which boards use the latter two?
> >>
> >> Why do we need CONFIG_RTC_DRV_CMOS?
> >>
> >> -Scott
> >>
> > [Shengzhou] so far DS1307 and DS1374 occur only on those boards with corenet64.
Which boards? I don't see them in any corenet dts files. I do see some
instances of ds1374 in the dts files of boards non-corenet mpc85xx
boards (mpc8568mds, mpc8569mds, and p1021mds), yet it's not in the
mpc85xx_defconfig or mpc85xx_smp_defconfig.
> > CONFIG_RTC_DRV_CMOS is enabled in mpc85xx_defconfig, mpc85xx_smp_defconfig, corenet32_smp_defconfig, etc, here keeps consistent in corenet64.
> > It seems CONFIG_RTC_DRV_CMOS is not needed on 85xx platform, do we need to remove CONFIG_RTC_DRV_CMOS from all 85xx/corenet defconfig? If so, I will post a new patch to do it.
>
> The CDS board uses an RTC over ISA if I remember correctly, not sure what driver deals with that (if its CONFIG_RTC_DRV_CMOS) or something else.
If it's just CDS then we don't need it in either corenet config.
-Scott
^ permalink raw reply
* Re: [PATCH v6 2/3] drivers/vfio: EEH support for VFIO PCI device
From: Alex Williamson @ 2014-05-27 17:39 UTC (permalink / raw)
To: Gavin Shan; +Cc: aik, agraf, kvm-ppc, qiudayu, linuxppc-dev
In-Reply-To: <20140524020620.GB4900@shangw>
On Sat, 2014-05-24 at 12:06 +1000, Gavin Shan wrote:
> On Fri, May 23, 2014 at 08:29:59AM -0600, Alex Williamson wrote:
> >On Fri, 2014-05-23 at 14:37 +1000, Gavin Shan wrote:
> >> On Thu, May 22, 2014 at 09:10:53PM -0600, Alex Williamson wrote:
> >> >On Thu, 2014-05-22 at 18:23 +1000, Gavin Shan wrote:
>
> .../...
>
> >No, sorry, I mean how does the user get information about the error?
> >The interface we have here is:
> >a) find that something bad has happened
> >b) kick it into working again
> >c) continue
> >
> >How does the user figure out what happened and if it makes sense to
> >attempt to recover? Where does the user learn that their disk is on
> >fire?
> >
>
> When 0xFF's returned from config or IO read, user should check the
> device (PE)'s state with ioctl command VFIO_EEH_PE_GET_STATE. If the
> device (PE) has been put into "frozen" state, It's confirmed the device
> ("disk" you mentioned) is on fire.
No, this only confirms that something bad happened, not _what_ bad thing
happened.
> User should kick off recovery, which
> includes:
And here you're just describing the kick operation again...
>
> - User stops any operatins (config, IO, DMA) on the device because any
> PCI traffic to "frozen" device will be dropped from software or hardware
> level. Also, we don't expect DMA traffic during recovery. Otherwise,
> we will bump into recursive errors and the recovery should fail.
> - VFIO_EEH_PE_SET_OPTION to enable I/O path ("DMA" path is still under frozen
> state). EEH_VFIO_PE_CONFIGURE to reconfigure affected PCI bridges and then
> do error log retrieval.
These logs, where do they go? How does the user get access? That's
what I'm trying to ask about.
> - VFIO_EEH_PE_RESET to reset the affected device (PE). EEH_VFIO_PE_CONFIUGRE
> to restore BARs.
> - User resumes the device to start PCI traffic and device is brought to
> funtional state.
>
> .../...
>
> >
> >No, I prefer to stay consistent with the rest of the VFIO API and use
> >argsz + flags.
> >
>
> Here's the recap for previous reply: I have several cases for ioctl().
>
> - ioctl(fd, cmd, NULL): I needn't any input info.
> - ioctl(fd, cmd, &data): I need input info
>
> For all the cases, should I simply have a data struct to include "argsz+flags"?
Anything that requires data should have argsz+flags, if it doesn't
require data, it doesn't need them, but think long an hard about whether
there's any possibility that we'll need parameters in the future.
> For return value from ioctl(), can we simply to have additional field in the
> above data struct to carry it? "0" is the information I have to return for
> some of the cases.
If for instance your ioctl is returning something like "number of
errors", then it's perfectly fine to use that as the ioctl return. <0
is error, >= zero is a success with value.
^ permalink raw reply
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Alex Williamson @ 2014-05-27 18:15 UTC (permalink / raw)
To: Gavin Shan; +Cc: aik, agraf, kvm-ppc, qiudayu, linuxppc-dev
In-Reply-To: <1401180052-6060-4-git-send-email-gwshan@linux.vnet.ibm.com>
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?
> 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
> +#ifdef CONFIG_EEH
> +#include <asm/eeh.h>
> +#endif
This shouldn't even be compiles w/o CONFIG_EEH
> +
> +#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.
> +
> #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?
>
> #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.
> + 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.
> +
> + 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?
> }
>
> 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.
> +};
> +
> +#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?
> +
> +#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?
> +};
> +
> +#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.
> +
> +#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?
^ permalink raw reply
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Benjamin Herrenschmidt @ 2014-05-27 20:30 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, 2014-05-27 at 12:15 -0600, Alex Williamson wrote:
> > +/*
> > + * 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?
The usual way is the driver asks for one or the other, this plumbs back
into the guest EEH code which itself plumbs into the PCIe error recovery
framework in Linux.
However I do have a question for Gavin here: Why do we expose an
explicit "deactivate" ? The reset functions should do the whole
reset sequence (assertion, delay, deassertion). In fact the firmware
doesn't really give you a choice for PERST right ? Or do we have
a requirement to expose both phases for RTAS? (In that case I'm
happy to ignore the deassertion there too).
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Alex Williamson @ 2014-05-27 20:37 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: aik, Gavin Shan, kvm-ppc, agraf, qiudayu, linuxppc-dev
In-Reply-To: <1401222649.20915.83.camel@pasglop>
On Wed, 2014-05-28 at 06:30 +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2014-05-27 at 12:15 -0600, Alex Williamson wrote:
>
> > > +/*
> > > + * 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?
>
> The usual way is the driver asks for one or the other, this plumbs back
> into the guest EEH code which itself plumbs into the PCIe error recovery
> framework in Linux.
So magic?
>
> However I do have a question for Gavin here: Why do we expose an
> explicit "deactivate" ? The reset functions should do the whole
> reset sequence (assertion, delay, deassertion). In fact the firmware
> doesn't really give you a choice for PERST right ? Or do we have
> a requirement to expose both phases for RTAS? (In that case I'm
> happy to ignore the deassertion there too).
>
> Cheers,
> Ben.
>
^ permalink raw reply
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Benjamin Herrenschmidt @ 2014-05-27 20:41 UTC (permalink / raw)
To: Alex Williamson; +Cc: aik, Gavin Shan, kvm-ppc, agraf, qiudayu, linuxppc-dev
In-Reply-To: <1401223069.3289.653.camel@ul30vt.home>
On Tue, 2014-05-27 at 14:37 -0600, Alex Williamson wrote:
> > The usual way is the driver asks for one or the other, this plumbs back
> > into the guest EEH code which itself plumbs into the PCIe error recovery
> > framework in Linux.
>
> So magic?
Yes. The driver is expected to more or less knows what kind of reset it
wants for its device. Ideally hot reset is sufficient but some drivers
knows that the device they drive is crappy enough that it mostly ignores
hot reset and really needs a PERST for example...
Also we have other reasons to expose those interfaces outside of EEH.
For example, some drivers might want to specifically trigger a PERST
after a microcode update. IE. There are path outside of EEH error
recovery where drivers in the guest might want to trigger a reset
to the device and they have control under some circumstances on
which kind of reset they are doing (and the guest Linux does have
different code path to do a hot reset vs. a fundamental reset).
So we need to expose that distinction to be able to honor the guest
decision.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH v2 00/13] Refactor pci_is_brdige() to simplify code
From: Bjorn Helgaas @ 2014-05-27 21:05 UTC (permalink / raw)
To: Yijing Wang
Cc: Tony Luck, linux-ia64, x86, linux-pci, sparclinux,
Thomas Gleixner, linuxppc-dev, David S. Miller
In-Reply-To: <1399177428-3784-1-git-send-email-wangyijing@huawei.com>
On Sun, May 04, 2014 at 12:23:35PM +0800, Yijing Wang wrote:
> v1->v2: Add comments for new pci_is_bridge().
>
> This patchset rename the current pci_is_bridge() to pci_has_subordinate(),
> and introduce a new pci_is_bridge() which determine pci bridge by check
> dev->hdr_type. The new one is more accurate. PCI Spec define the pci
> device is a bridge by the dev->hdr_type = 0x01 || 0x02.
>
> There is no guarantee that a PCI bridge must attached a subordinate bus.
> When PCI bridge is created but before the scan child bus, it has no
> subordinate bus. Also users can remove the pci bus using
> interface pci_remove_bus() in remove.c.
>
> So use new pci_is_bridge() check if the PCI device is bridge is better
> choice. If user want check PCI bridge whether has a subordinate bus,
> pci_has_subordinate() is a candidate.
>
>
> Yijing Wang (13):
> PCI: rename pci_is_bridge() to pci_has_subordinate()
> PCI: Introduce new pci_is_bridge() helper function
> PCI: Use new pci_is_bridge() to simplify code
> x86/PCI: Use new pci_is_bridge() to simplify code
> IA64/PCI: Use new pci_is_bridge() to simplify code
> powerpc/PCI: Use new pci_is_bridge() to simplify code
> sparc/PCI: Use new pci_is_bridge() to simplify code
> PCI, rpaphp: Use new pci_is_bridge() to simplify code
> PCI, shpchp: Use new pci_is_bridge() to simplify code
> PCI, cpcihp: Use new pci_is_bridge() to simplify code
> PCI, acpiphp: Use new pci_is_bridge() to simplify code
> PCI, pcmcia: Use new pci_is_bridge() to simplify code
> PCI, pciehp: Use new pci_is_bridge() to simplify code
>
> arch/ia64/pci/fixup.c | 4 +---
> arch/powerpc/kernel/pci-hotplug.c | 3 +--
> arch/powerpc/kernel/pci_of_scan.c | 3 +--
> arch/sparc/kernel/pci.c | 3 +--
> arch/x86/pci/fixup.c | 4 +---
> drivers/pci/hotplug/acpiphp_glue.c | 3 +--
> drivers/pci/hotplug/cpci_hotplug_pci.c | 3 +--
> drivers/pci/hotplug/pciehp_pci.c | 3 +--
> drivers/pci/hotplug/rpadlpar_core.c | 3 +--
> drivers/pci/hotplug/shpchp_pci.c | 3 +--
> drivers/pci/pci-acpi.c | 8 +-------
> drivers/pci/pci-driver.c | 8 ++++----
> drivers/pci/pci.h | 2 +-
> drivers/pci/probe.c | 3 +--
> drivers/pci/setup-bus.c | 4 +---
> drivers/pcmcia/cardbus.c | 3 +--
> include/linux/pci.h | 13 +++++++++++++
> 17 files changed, 32 insertions(+), 41 deletions(-)
Applied to pci/pci_is_bridge for v3.16, thanks,
Bjorn
^ permalink raw reply
* Re: [PATCH v7 3/3] drivers/vfio: EEH support for VFIO PCI device
From: Alexander Graf @ 2014-05-27 22:49 UTC (permalink / raw)
To: Alex Williamson, Gavin Shan; +Cc: aik, qiudayu, linuxppc-dev, kvm-ppc
In-Reply-To: <1401214527.3289.611.camel@ul30vt.home>
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.
Alex
^ permalink raw reply
* Kernel 3.15: Boot problems with a PA6T board
From: Christian Zigotzky @ 2014-05-27 23:08 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev
In-Reply-To: <1401107166.23096.1.camel@concordia>
Hi Michael,
Thanks a lot for your answer.
On 26.05.2014 14:26, Michael Ellerman wrote:
>
> Hi Christian,
>
> I'm almost certain that is not the commit which breaks your machine. Or if it
> is, something *really* weird is going on.
>
> The code changed in that commit should never run on a PA6T.
You're right. I think this patch is for Power 8.
>> Experimental protocol:
>>
>> git checkout -f 01d8885785a60ae8f4c37b0ed75bdc96d0fc6a44; git clean -fdx
>> (from 02/04/14) -> Kernel boots
>> git checkout -f f1553174a207f68a4ec19d436003097e0a4dc405; git clean -fdx
>> (from 03/04/14) -> Kernel boots
>> git checkout -f d40326f4b9f9617cdfd30f83a2db57d47e9c5bac; git clean -fdx
>> (from 04/04/14) -> Kernel boots
>> git checkout -f 930b440cd8256f3861bdb0a59d26efaadac7941a; git clean -fdx
>> (from 05/04/14) -> doesn't boot (rtc error)
>> git checkout -f 2b3a8fd735f86ebeb2b9d061054003000c36b654; git clean -fdx
>> (from 06/04/14) -> doesn't boot (rtc error)
>> git checkout -f 26c12d93348f0bda0756aff83f4867d9ae58a5a6; git clean -fdx
>> (from 07/04/14) -> doesn't boot (rtc error)
>> git checkout -f a6c8aff022d4d06e4b41455ae9b2a5d3d503bf76; git clean -fdx
>> (from 08/04/14) -> Kernel boots
>> git checkout -f 035328c202d26a824b8632fd3b00635db5aee5a2; git clean -fdx
>> (from 08/04/14) -> Kernel boots
>> git checkout -f 9000c17dc0f9c910267d2661225c9d33a227b27e; git clean -fdx
>> (from 08/04/14) powerpc/powernv: Fix endian issues with sensor code
>> One OPAL call and one device tree property needed byte swapping. ->
>> doesn't boot (prom_init)
>> git checkout -f d3d35d957a9d0733dc51f14b5abc0bff5d3c5f3a; git clean -fdx
>> (from 08/04/14) -> doesn't boot (prom_init)
>> git checkout -f c4586256f0c440bc2bdb29d2cbb915f0ca785d26; git clean -fdx
>> (from 09/04/14) -> doesn't boot (prom_init)
> So it looks like you manually picked commits based on the date?
Yes, it is.
> That's a good start, but if you want to find the actual problem commit you need
> to do a proper bisect.
>
>> I'm not a programmer but what can I do to solve this boot problem?
> To start with you can probably narrow it down a bit by testing the following
> commits:
>
> 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.
Cheers,
Christian
^ permalink raw reply
* Re: [RFC PATCH v2 1/2] powerpc: numa: enable USE_PERCPU_NUMA_NODE_ID
From: Nishanth Aravamudan @ 2014-05-27 23:44 UTC (permalink / raw)
To: Andrew Morton
Cc: Lee Schermerhorn, Christoph Lameter, Mel Gorman, linux-mm,
Anton Blanchard, David Rientjes, Joonsoo Kim, linuxppc-dev
In-Reply-To: <20140519181423.GL8941@linux.vnet.ibm.com>
On 19.05.2014 [11:14:23 -0700], Nishanth Aravamudan wrote:
> Hi Andrew,
>
> I found one issue with my patch, fixed below...
>
> On 16.05.2014 [16:39:45 -0700], Nishanth Aravamudan wrote:
> > Based off 3bccd996 for ia64, convert powerpc to use the generic per-CPU
> > topology tracking, specifically:
> >
> > initialize per cpu numa_node entry in start_secondary
> > remove the powerpc cpu_to_node()
> > define CONFIG_USE_PERCPU_NUMA_NODE_ID if NUMA
> >
> > Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
>
> <snip>
>
> > diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> > index e2a4232..b95be24 100644
> > --- a/arch/powerpc/kernel/smp.c
> > +++ b/arch/powerpc/kernel/smp.c
> > @@ -750,6 +750,11 @@ void start_secondary(void *unused)
> > }
> > traverse_core_siblings(cpu, true);
> >
> > + /*
> > + * numa_node_id() works after this.
> > + */
> > + set_numa_node(numa_cpu_lookup_table[cpu]);
> > +
>
> Similar change is needed for the boot CPU. Update patch:
>
>
> powerpc: numa: enable USE_PERCPU_NUMA_NODE_ID
>
> Based off 3bccd996 for ia64, convert powerpc to use the generic per-CPU
> topology tracking, specifically:
>
> initialize per cpu numa_node entry in start_secondary
> remove the powerpc cpu_to_node()
> define CONFIG_USE_PERCPU_NUMA_NODE_ID if NUMA
>
> Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
Ping on this and patch 2/2. Ben, would you be willing to pull these into
your -next branch so they'd get some testing?
http://patchwork.ozlabs.org/patch/350368/
http://patchwork.ozlabs.org/patch/349838/
Without any further changes, these two help quite a bit with the slab
consumption on CONFIG_SLUB kernels when memoryless nodes are present.
Thanks,
Nish
^ permalink raw reply
* Re: [RFC PATCH v2 1/2] powerpc: numa: enable USE_PERCPU_NUMA_NODE_ID
From: Benjamin Herrenschmidt @ 2014-05-27 23:56 UTC (permalink / raw)
To: Nishanth Aravamudan
Cc: Lee Schermerhorn, Christoph Lameter, Mel Gorman, linux-mm,
Anton Blanchard, David Rientjes, Andrew Morton, linuxppc-dev,
Joonsoo Kim
In-Reply-To: <20140527234420.GE4104@linux.vnet.ibm.com>
On Tue, 2014-05-27 at 16:44 -0700, Nishanth Aravamudan wrote:
> > Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
>
> Ping on this and patch 2/2. Ben, would you be willing to pull these
> into
> your -next branch so they'd get some testing?
>
> http://patchwork.ozlabs.org/patch/350368/
> http://patchwork.ozlabs.org/patch/349838/
>
> Without any further changes, these two help quite a bit with the slab
> consumption on CONFIG_SLUB kernels when memoryless nodes are present.
I don't mind at all :-) I haven't really been following that story
so I was waiting for the dust to settle and maybe acks from MM people
but if you tell me they are good I'm prepared to trust you.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH] tty/hvc/hvc_console: Fix wakeup of HVC thread on hvc_kick()
From: Benjamin Herrenschmidt @ 2014-05-28 0:01 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: linuxppc-dev list, Jiri Slaby, Linux Kernel list
In-Reply-To: <1400838066.29150.69.camel@pasglop>
On Fri, 2014-05-23 at 19:41 +1000, Benjamin Herrenschmidt wrote:
> Some backends call hvc_kick() to wakeup the HVC thread from its
> slumber upon incoming characters. This however doesn't work
> properly because it uses msleep_interruptible() which is mostly
> immune to wake_up_process(). It will basically go back to sleep
> until the timeout is expired (only signals can really wake it).
>
> Replace it with a simple shedule_timeout_interruptible() instead,
> which may wakeup earlier every now and then but we really don't
> care in this case.
Nobody commented ? :-)
Greg, do you want to take this in the tty tree or can I stick it in
powerpc ?
Cheers,
Ben
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> drivers/tty/hvc/hvc_console.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
> index 94f9e3a..1094265 100644
> --- a/drivers/tty/hvc/hvc_console.c
> +++ b/drivers/tty/hvc/hvc_console.c
> @@ -760,10 +760,17 @@ static int khvcd(void *unused)
> if (poll_mask == 0)
> schedule();
> else {
> + unsigned long j_timeout;
> +
> if (timeout < MAX_TIMEOUT)
> timeout += (timeout >> 6) + 1;
>
> - msleep_interruptible(timeout);
> + /*
> + * We don't use msleep_interruptible otherwise
> + * "kick" will fail to wake us up
> + */
> + j_timeout = msecs_to_jiffies(timeout) + 1;
> + schedule_timeout_interruptible(j_timeout);
> }
> }
> __set_current_state(TASK_RUNNING);
>
^ permalink raw reply
* Re: [RFC PATCH v2 1/2] powerpc: numa: enable USE_PERCPU_NUMA_NODE_ID
From: Nishanth Aravamudan @ 2014-05-28 0:09 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Lee Schermerhorn, Christoph Lameter, Mel Gorman, linux-mm,
Anton Blanchard, David Rientjes, Andrew Morton, linuxppc-dev,
Joonsoo Kim
In-Reply-To: <1401234974.8262.8.camel@pasglop>
On 28.05.2014 [09:56:14 +1000], Benjamin Herrenschmidt wrote:
> On Tue, 2014-05-27 at 16:44 -0700, Nishanth Aravamudan wrote:
> > > Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
> >
> > Ping on this and patch 2/2. Ben, would you be willing to pull these
> > into
> > your -next branch so they'd get some testing?
> >
> > http://patchwork.ozlabs.org/patch/350368/
> > http://patchwork.ozlabs.org/patch/349838/
> >
> > Without any further changes, these two help quite a bit with the slab
> > consumption on CONFIG_SLUB kernels when memoryless nodes are present.
>
> I don't mind at all :-) I haven't really been following that story
> so I was waiting for the dust to settle and maybe acks from MM people
> but if you tell me they are good I'm prepared to trust you.
The patches themselves are pretty minimal and similar to the ia64
changes (and the affected code seems like it hasn't changed in some
time, beyond in the common code). I'd mostly like to get some
broad-range build & boot testing.
Also, is NUMA a sufficient symbol to depend, you think? I figure most of
the PPC NUMA systems are the pSeries/IBM variety, which is where I've
run into memoryless nodes in the first place.
Thanks,
Nish
^ permalink raw reply
* [PATCH 00/16] perf: add support for parameterized events from sysfs (powerpc 24x7)
From: Cody P Schafer @ 2014-05-28 0:21 UTC (permalink / raw)
To: LKML, Linux PPC, Adrian Hunter, Andi Kleen, Anshuman Khandual,
Arnaldo Carvalho de Melo, Benjamin Herrenschmidt, Borislav Petkov,
Cody P Schafer, David Ahern, Ingo Molnar, Jiri Olsa,
Michael Ellerman, Namhyung Kim, Peter Zijlstra, Runzhen Wang,
Stephane Eranian, Sukadev Bhattiprolu
Cc: linux-doc
What this patchset does:
- the first patch (override sysfs in tools/perf via SYSFS_PATH) was sent out
previously, but needed a resend anyhow. Having it is useful for testing the
later changes to tools/perf.
- the second patch is a bugfix to the powerpc hv-24x7 code which was
previously sent out, which is a good idea to have when testing these patches
on POWER8 hardware.
- document perf sysfs and the changes to add parameterized events
- semi-notably: removes the growing list of specific POWER cpu events and
begins documenting them generically, much like the docs for
/sys/modules/MODULENAME do for modules.
- tools/perf changes to support parameterized events
- export some parameterized events from the powerpc pmus hv_24x7 and hv_gpci
Description of "event parameters" from the documentation patch:
Event parameters are a basic way for partial events to be specified in
sysfs with per-event names given to the fields that need to be filled in
when using a particular event.
It is intended for supporting cases where the single 'cpu' parameter is
insufficient. For example, POWER 8 has events for physical
sockets/cores/cpus that are accessible from with virtual machines. To
keep using the single 'cpu' parameter we'd need to perform a mapping
between Linux's cpus and the physical machine's cpus (in this case
Linux is running under a hypervisor). This isn't possible because
bindings between our cpus and physical cpus may not be fixed, and we
probably won't have a "cpu" on each physical cpu.
Description of the sysfs contents when events are parameterized (copied from an
included patch):
Examples:
domain=0x1,offset=0x8,starting_index=phys_cpu
In the case of the last example, a value replacing "phys_cpu"
would need to be provided by the user selecting the particular
event. This is refered to as "event parameterization". All
non-numerical values indicate an event parameter.
Notes on how perf-list displays parameterized events (and how to use them,
again culled from an included patch):
PARAMETERIZED EVENTS
--------------------
Some pmu events listed by 'perf-list' will be displayed with '?' in them. For
example:
hv_gpci/dtbp_ptitc,phys_processor_idx=?/
This means that when provided as an event, a value for phys_processor_idx must
also be supplied. For example:
perf stat -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ...
Cody P Schafer (16):
tools/perf: allow overriding sysfs and proc finding with env var
powerpc/perf/hv-24x7: use kmem_cache instead of aligned stack
allocations
perf Documentation: sysfs events/ interfaces
perf Documentation: remove duplicated docs for powerpc cpu specific
events
perf Documentation: add event parameters
tools/perf: annotate list_head with type info
tools/perf: support parsing parameterized events
tools/perf: extend format_alias() to include event parameters
tools/perf: document parameterized events and note symbolically formed
events
perf: provide sysfs_show for struct perf_pmu_events_attr
byteorder: provide a linux/byteorder.h with {be,le}_to_cpu() and
cpu_to_{be,le}() macros
powerpc/perf/hv-24x7: parse catalog and populate sysfs with events
powerpc/perf/hv-24x7: Documentaion for new sysfs entries which expose
descriptions
perf: add PMU_EVENT_ATTR_STRING() helper
powerpc/perf/{hv-gpci,hv-common}: generate requests with counters
annotated
powerpc/perf/hv-gpci: add the remaining gpci requests
.../testing/sysfs-bus-event_source-devices-events | 617 ++--------------
.../testing/sysfs-bus-event_source-devices-hv_24x7 | 22 +
arch/powerpc/perf/hv-24x7-catalog.h | 25 +
arch/powerpc/perf/hv-24x7-domains.h | 19 +
arch/powerpc/perf/hv-24x7.c | 812 ++++++++++++++++++++-
arch/powerpc/perf/hv-24x7.h | 12 +-
arch/powerpc/perf/hv-common.c | 10 +-
arch/powerpc/perf/hv-gpci-requests.h | 258 +++++++
arch/powerpc/perf/hv-gpci.c | 8 +
arch/powerpc/perf/hv-gpci.h | 37 +-
arch/powerpc/perf/req-gen/_begin.h | 13 +
arch/powerpc/perf/req-gen/_clear.h | 5 +
arch/powerpc/perf/req-gen/_end.h | 4 +
arch/powerpc/perf/req-gen/_request-begin.h | 15 +
arch/powerpc/perf/req-gen/_request-end.h | 8 +
arch/powerpc/perf/req-gen/perf.h | 155 ++++
include/linux/byteorder.h | 34 +
include/linux/perf_event.h | 10 +
kernel/events/core.c | 8 +
tools/lib/api/fs/fs.c | 43 +-
tools/perf/Documentation/perf-list.txt | 13 +
tools/perf/Documentation/perf-record.txt | 5 +
tools/perf/util/parse-events.h | 1 +
tools/perf/util/pmu.c | 85 ++-
tools/perf/util/pmu.h | 6 +-
25 files changed, 1589 insertions(+), 636 deletions(-)
create mode 100644 arch/powerpc/perf/hv-24x7-domains.h
create mode 100644 arch/powerpc/perf/hv-gpci-requests.h
create mode 100644 arch/powerpc/perf/req-gen/_begin.h
create mode 100644 arch/powerpc/perf/req-gen/_clear.h
create mode 100644 arch/powerpc/perf/req-gen/_end.h
create mode 100644 arch/powerpc/perf/req-gen/_request-begin.h
create mode 100644 arch/powerpc/perf/req-gen/_request-end.h
create mode 100644 arch/powerpc/perf/req-gen/perf.h
create mode 100644 include/linux/byteorder.h
--
1.9.3
^ permalink raw reply
* [PATCH 01/16] tools/perf: allow overriding sysfs and proc finding with env var
From: Cody P Schafer @ 2014-05-28 0:21 UTC (permalink / raw)
To: LKML, Linux PPC, Arnaldo Carvalho de Melo, Borislav Petkov,
Cody P Schafer, Jiri Olsa
Cc: Sukadev Bhattiprolu
In-Reply-To: <1401236684-10579-1-git-send-email-dev@codyps.com>
SYSFS_PATH and PROC_PATH environment variables now let the user override
the detection of sysfs and proc locations for testing purposes.
CC: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: Cody P Schafer <dev@codyps.com>
---
tools/lib/api/fs/fs.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index 5b5eb78..c1b49c3 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -1,8 +1,10 @@
/* TODO merge/factor in debugfs.c here */
+#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/vfs.h>
@@ -96,12 +98,51 @@ static bool fs__check_mounts(struct fs *fs)
return false;
}
+static void mem_toupper(char *f, size_t len)
+{
+ while (len) {
+ *f = toupper(*f);
+ f++;
+ len--;
+ }
+}
+
+/*
+ * Check for "NAME_PATH" environment variable to override fs location (for
+ * testing). This matches the recommendation in Documentation/sysfs-rules.txt
+ * for SYSFS_PATH.
+ */
+static bool fs__env_override(struct fs *fs)
+{
+ char *override_path;
+ size_t name_len = strlen(fs->name);
+ /* name + "_PATH" + '\0' */
+ char upper_name[name_len + 5 + 1];
+ memcpy(upper_name, fs->name, name_len);
+ mem_toupper(upper_name, name_len);
+ strcpy(&upper_name[name_len], "_PATH");
+
+ override_path = getenv(upper_name);
+ if (!override_path)
+ return false;
+
+ fs->found = true;
+ strncpy(fs->path, override_path, sizeof(fs->path));
+ return true;
+}
+
static const char *fs__get_mountpoint(struct fs *fs)
{
+ if (fs__env_override(fs))
+ return fs->path;
+
if (fs__check_mounts(fs))
return fs->path;
- return fs__read_mounts(fs) ? fs->path : NULL;
+ if (fs__read_mounts(fs))
+ return fs->path;
+
+ return NULL;
}
static const char *fs__mountpoint(int idx)
--
1.9.3
^ permalink raw reply related
* [PATCH 02/16] powerpc/perf/hv-24x7: use kmem_cache instead of aligned stack allocations
From: Cody P Schafer @ 2014-05-28 0:21 UTC (permalink / raw)
To: LKML, Linux PPC, Benjamin Herrenschmidt, Cody P Schafer,
Michael Ellerman
Cc: Sukadev Bhattiprolu, Paul Mackerras
In-Reply-To: <1401236684-10579-1-git-send-email-dev@codyps.com>
Ian pointed out the use of __aligned(4096) caused rather large stack
consumption in single_24x7_request(), so use the kmem_cache
hv_page_cache (which we've already got set up for other allocations)
insead of allocating locally.
CC: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Reported-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Cody P Schafer <dev@codyps.com>
---
arch/powerpc/perf/hv-24x7.c | 52 ++++++++++++++++++++++++++++++++-------------
1 file changed, 37 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index e0766b8..9a7a830 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -294,7 +294,7 @@ static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
u16 lpar, u64 *res,
bool success_expected)
{
- unsigned long ret;
+ unsigned long ret = -ENOMEM;
/*
* request_buffer and result_buffer are not required to be 4k aligned,
@@ -304,7 +304,27 @@ static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
struct reqb {
struct hv_24x7_request_buffer buf;
struct hv_24x7_request req;
- } __packed __aligned(4096) request_buffer = {
+ } __packed *request_buffer;
+ struct resb {
+ struct hv_24x7_data_result_buffer buf;
+ struct hv_24x7_result res;
+ struct hv_24x7_result_element elem;
+ __be64 result;
+ } __packed *result_buffer;
+
+ BUILD_BUG_ON(sizeof(*request_buffer) > 4096);
+ BUILD_BUG_ON(sizeof(*result_buffer) > 4096);
+
+ request_buffer = kmem_cache_alloc(hv_page_cache, GFP_USER);
+
+ if (!request_buffer)
+ goto out_reqb;
+
+ result_buffer = kmem_cache_zalloc(hv_page_cache, GFP_USER);
+ if (!result_buffer)
+ goto out_resb;
+
+ *request_buffer = (struct reqb) {
.buf = {
.interface_version = HV_24X7_IF_VERSION_CURRENT,
.num_requests = 1,
@@ -320,28 +340,30 @@ static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
}
};
- struct resb {
- struct hv_24x7_data_result_buffer buf;
- struct hv_24x7_result res;
- struct hv_24x7_result_element elem;
- __be64 result;
- } __packed __aligned(4096) result_buffer = {};
-
ret = plpar_hcall_norets(H_GET_24X7_DATA,
- virt_to_phys(&request_buffer), sizeof(request_buffer),
- virt_to_phys(&result_buffer), sizeof(result_buffer));
+ virt_to_phys(request_buffer), sizeof(*request_buffer),
+ virt_to_phys(result_buffer), sizeof(*result_buffer));
if (ret) {
if (success_expected)
pr_err_ratelimited("hcall failed: %d %#x %#x %d => 0x%lx (%ld) detail=0x%x failing ix=%x\n",
domain, offset, ix, lpar,
ret, ret,
- result_buffer.buf.detailed_rc,
- result_buffer.buf.failing_request_ix);
- return ret;
+ result_buffer->buf.detailed_rc,
+ result_buffer->buf.failing_request_ix);
+ goto out_hcall;
}
- *res = be64_to_cpu(result_buffer.result);
+ *res = be64_to_cpu(result_buffer->result);
+ kfree(result_buffer);
+ kfree(request_buffer);
+ return ret;
+
+out_hcall:
+ kfree(result_buffer);
+out_resb:
+ kfree(request_buffer);
+out_reqb:
return ret;
}
--
1.9.3
^ permalink raw reply related
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