* [PATCH] powerpc: Add VDSO version of getcpu
From: Anton Blanchard @ 2012-06-25 1:55 UTC (permalink / raw)
To: benh, paulus; +Cc: linuxppc-dev
We had a request for a fast method of getting CPU and NUMA node IDs
from userspace. Ben suggested we use SPRG3 which is userspace
readable. This is a quick hack to try that out.
I have a glibc patch to implement sched_getcpu using this. Testing
on a POWER7:
baseline: 538 cycles
vdso: 30 cycles
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Outstanding issues:
- Do we have any KVM issues?
- This will only work with 64 bit kernels for now, do we need to come up
with a scheme for 32 bit?
- Implement 32 bit userspace version (running on 64 bit kernels)
Index: linux-build/arch/powerpc/include/asm/reg.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/reg.h 2012-06-25 10:05:52.193076424 +1000
+++ linux-build/arch/powerpc/include/asm/reg.h 2012-06-25 10:09:02.932316659 +1000
@@ -491,6 +491,7 @@
#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
+#define SPRN_USPRG3 0x103 /* SPRG3 userspace read */
#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */
#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */
#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */
@@ -753,14 +754,14 @@
* 64-bit server:
* - SPRG0 unused (reserved for HV on Power4)
* - SPRG2 scratch for exception vectors
- * - SPRG3 unused (user visible)
+ * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
* - HSPRG0 stores PACA in HV mode
* - HSPRG1 scratch for "HV" exceptions
*
* 64-bit embedded
* - SPRG0 generic exception scratch
* - SPRG2 TLB exception stack
- * - SPRG3 unused (user visible)
+ * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
* - SPRG4 unused (user visible)
* - SPRG6 TLB miss scratch (user visible, sorry !)
* - SPRG7 critical exception scratch
Index: linux-build/arch/powerpc/kernel/vdso.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso.c 2012-06-25 10:05:52.229077036 +1000
+++ linux-build/arch/powerpc/kernel/vdso.c 2012-06-25 10:12:50.256171890 +1000
@@ -706,6 +706,25 @@ static void __init vdso_setup_syscall_ma
}
}
+#ifdef CONFIG_PPC64
+int __cpuinit vdso_getcpu_init(void)
+{
+ unsigned long cpu, node;
+
+ /*
+ * SPRG3 contains the CPU in the bottom 32 bits and the NUMA node in the
+ * top 32 bits.
+ */
+ cpu = get_cpu();
+ node = cpu_to_node(cpu);
+ mtspr(SPRN_SPRG3, cpu | (node << 32));
+ put_cpu();
+
+ return 0;
+}
+/* We need to call this before SMP init */
+early_initcall(vdso_getcpu_init);
+#endif
static int __init vdso_init(void)
{
Index: linux-build/arch/powerpc/kernel/vdso64/Makefile
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso64/Makefile 2012-06-25 10:05:52.209076696 +1000
+++ linux-build/arch/powerpc/kernel/vdso64/Makefile 2012-06-25 10:05:53.737102674 +1000
@@ -1,6 +1,6 @@
# List of files in the vdso, has to be asm only for now
-obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
+obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o
# Build rules
Index: linux-build/arch/powerpc/kernel/vdso64/vdso64.lds.S
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso64/vdso64.lds.S 2012-06-25 10:05:52.217076832 +1000
+++ linux-build/arch/powerpc/kernel/vdso64/vdso64.lds.S 2012-06-25 10:05:53.737102674 +1000
@@ -146,6 +146,7 @@ VERSION
__kernel_sync_dicache;
__kernel_sync_dicache_p5;
__kernel_sigtramp_rt64;
+ __kernel_getcpu;
local: *;
};
Index: linux-build/arch/powerpc/kernel/vdso64/getcpu.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-build/arch/powerpc/kernel/vdso64/getcpu.S 2012-06-25 10:09:11.796467121 +1000
@@ -0,0 +1,44 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2012
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#include <asm/ppc_asm.h>
+#include <asm/vdso.h>
+
+ .text
+/*
+ * Exact prototype of getcpu
+ *
+ * int __kernel_getcpu(unsigned *cpu, unsigned *node);
+ *
+ */
+V_FUNCTION_BEGIN(__kernel_getcpu)
+ .cfi_startproc
+ mfspr r5,SPRN_USPRG3
+ cmpdi cr0,r3,0
+ cmpdi cr1,r4,0
+ srdi r6,r5,32
+ beq cr0,1f
+ stw r5,0(r3)
+1: beq cr1,2f
+ stw r6,0(r4)
+2: crclr cr0*4+so
+ li r3,0 /* always success */
+ blr
+ .cfi_endproc
+V_FUNCTION_END(__kernel_getcpu)
Index: linux-build/arch/powerpc/kernel/smp.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/smp.c 2012-06-25 10:05:52.197076492 +1000
+++ linux-build/arch/powerpc/kernel/smp.c 2012-06-25 10:13:54.897266908 +1000
@@ -48,6 +48,7 @@
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#endif
+#include <asm/vdso.h>
#include <asm/debug.h>
#ifdef DEBUG
@@ -570,6 +571,8 @@ void __devinit start_secondary(void *unu
#ifdef CONFIG_PPC64
if (system_state == SYSTEM_RUNNING)
vdso_data->processorCount++;
+
+ vdso_getcpu_init();
#endif
ipi_call_lock();
notify_cpu_starting(cpu);
Index: linux-build/arch/powerpc/include/asm/vdso.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/vdso.h 2012-06-25 10:05:52.181076220 +1000
+++ linux-build/arch/powerpc/include/asm/vdso.h 2012-06-25 10:05:53.737102674 +1000
@@ -22,6 +22,8 @@ extern unsigned long vdso64_rt_sigtramp;
extern unsigned long vdso32_sigtramp;
extern unsigned long vdso32_rt_sigtramp;
+int __cpuinit vdso_getcpu_init(void);
+
#else /* __ASSEMBLY__ */
#ifdef __VDSO64__
^ permalink raw reply
* [PATCH V3 2/2] PCI: minimal alignment for bars of P2P bridges
From: Gavin Shan @ 2012-06-25 3:10 UTC (permalink / raw)
To: linux-pci, linuxppc-dev; +Cc: bhelgaas, Gavin Shan
In-Reply-To: <1340593821-19011-1-git-send-email-shangw@linux.vnet.ibm.com>
On some powerpc platforms, device BARs need to be assigned to separate
"segments" of the address space in order for the error isolation and HW
virtualization mechanisms (EEH) to work properly. Those "segments" have
a minimum size that can be fairly large (16M). In order to be able to
use the generic resource assignment code rather than re-inventing our
own, we chose to group devices by bus. That way, a simple change of the
minimum alignment requirements of resources assigned to PCI to PCI (P2P)
bridges is enough to ensure that all BARs for devices below those bridges
will fit into contiguous sets of segments and there will be no overlap.
This patch provides a way for the host bridge to override the default
alignment values used by the resource allocation code for that purpose.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Reviewed-by: Ram Pai <linuxram@us.ibm.com>
Reviewed-by: Richard Yang <weiyang@linux.vnet.ibm.com>
---
drivers/pci/probe.c | 5 +++++
drivers/pci/setup-bus.c | 28 +++++++++++++++++++++-------
include/linux/pci.h | 8 ++++++++
3 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 658ac97..a196529 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -431,6 +431,11 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
if (bridge) {
INIT_LIST_HEAD(&bridge->windows);
bridge->bus = b;
+
+ /* Set minimal alignment shift of P2P bridges */
+ bridge->io_align_shift = PCI_DEFAULT_IO_ALIGN_SHIFT;
+ bridge->mem_align_shift = PCI_DEFAULT_MEM_ALIGN_SHIFT;
+ bridge->pmem_align_shift = PCI_DEFAULT_PMEM_ALIGN_SHIFT;
}
return bridge;
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8fa2d4b..7c3e90d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -706,10 +706,12 @@ static resource_size_t calculate_memsize(resource_size_t size,
static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
resource_size_t add_size, struct list_head *realloc_head)
{
+ struct pci_host_bridge *phb;
struct pci_dev *dev;
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
unsigned long size = 0, size0 = 0, size1 = 0;
resource_size_t children_add_size = 0;
+ resource_size_t io_align;
if (!b_res)
return;
@@ -735,13 +737,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
children_add_size += get_res_add_size(realloc_head, r);
}
}
+
+ phb = pci_bus_host_bridge(bus);
+ io_align = (1 << phb->io_align_shift);
+
size0 = calculate_iosize(size, min_size, size1,
- resource_size(b_res), 4096);
+ resource_size(b_res), io_align);
if (children_add_size > add_size)
add_size = children_add_size;
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
calculate_iosize(size, min_size, add_size + size1,
- resource_size(b_res), 4096);
+ resource_size(b_res), io_align);
if (!size0 && !size1) {
if (b_res->start || b_res->end)
dev_info(&bus->self->dev, "disabling bridge window "
@@ -751,11 +757,11 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
return;
}
/* Alignment of the IO window is always 4K */
- b_res->start = 4096;
+ b_res->start = io_align;
b_res->end = b_res->start + size0 - 1;
b_res->flags |= IORESOURCE_STARTALIGN;
if (size1 > size0 && realloc_head) {
- add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
+ add_to_list(realloc_head, bus->self, b_res, size1-size0, io_align);
dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
"%pR to [bus %02x-%02x] add_size %lx\n", b_res,
bus->secondary, bus->subordinate, size1-size0);
@@ -778,6 +784,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
resource_size_t add_size,
struct list_head *realloc_head)
{
+ struct pci_host_bridge *phb;
struct pci_dev *dev;
resource_size_t min_align, align, size, size0, size1;
resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
@@ -785,10 +792,17 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
struct resource *b_res = find_free_bus_resource(bus, type);
unsigned int mem64_mask = 0;
resource_size_t children_add_size = 0;
+ int mem_align_shift;
if (!b_res)
return 0;
+ phb = pci_bus_host_bridge(bus);
+ if (type & IORESOURCE_PREFETCH)
+ mem_align_shift = phb->pmem_align_shift;
+ else
+ mem_align_shift = phb->mem_align_shift;
+
memset(aligns, 0, sizeof(aligns));
max_order = 0;
size = 0;
@@ -818,8 +832,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
#endif
/* For bridges size != alignment */
align = pci_resource_alignment(dev, r);
- order = __ffs(align) - 20;
- if (order > 11) {
+ order = __ffs(align) - mem_align_shift;
+ if (order > (11 - (mem_align_shift - 20))) {
dev_warn(&dev->dev, "disabling BAR %d: %pR "
"(bad alignment %#llx)\n", i, r,
(unsigned long long) align);
@@ -846,7 +860,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
for (order = 0; order <= max_order; order++) {
resource_size_t align1 = 1;
- align1 <<= (order + 20);
+ align1 <<= (order + mem_align_shift);
if (!align)
min_align = align1;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6d5bb1c..ed55e58 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -376,9 +376,17 @@ struct pci_host_bridge_window {
resource_size_t offset; /* bus address + offset = CPU address */
};
+/* Default shits for P2P I/O and MMIO bar minimal alignment shifts */
+#define PCI_DEFAULT_IO_ALIGN_SHIFT 12 /* 4KB */
+#define PCI_DEFAULT_MEM_ALIGN_SHIFT 20 /* 1MB */
+#define PCI_DEFAULT_PMEM_ALIGN_SHIFT 20 /* 1MB */
+
struct pci_host_bridge {
struct device dev;
struct pci_bus *bus; /* root bus */
+ int io_align_shift; /* P2P I/O bar minimal alignment shift */
+ int mem_align_shift; /* P2P MMIO bar minimal alignment shift */
+ int pmem_align_shift; /* P2P prefetchable MMIO bar minimal alignment shift */
struct list_head windows; /* pci_host_bridge_windows */
void (*release_fn)(struct pci_host_bridge *);
void *release_data;
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 1/2] PCI: retrieve host bridge by PCI bus
From: Gavin Shan @ 2012-06-25 3:10 UTC (permalink / raw)
To: linux-pci, linuxppc-dev; +Cc: bhelgaas, Gavin Shan
With current implementation, there is one function to retrieve
the corresponding host bridge (struct pci_host_bridge) according
to the given PCI device (struct pci_dev) and that function has
been declared as "static". Further, we don't have the public
function to retrieve host bridge from PCI bus yet. The function
is useful somewhere.
The additional information like minimal resource alignment for I/O
and MMIO bars of p2p bridges will be put into the PCI host bridge.
The patch introduces the public function pci_bus_host_bridge() to
retrieve the corresponding PCI host bridge according to the specified
PCI bus, then accessing the information regarding the minimal resource
alignment for I/O and MMIO bars of p2p bridges.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Reviewed-by: Ram Pai <linuxram@us.ibm.com>
Reviewed-by: Richard Yang <weiyang@linux.vnet.ibm.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/pci/host-bridge.c | 13 +++++++++++++
include/linux/pci.h | 2 +-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index a68dc61..b95f0ce 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -27,6 +27,19 @@ static struct pci_host_bridge *find_pci_host_bridge(struct pci_dev *dev)
return to_pci_host_bridge(bus->bridge);
}
+struct pci_host_bridge *pci_bus_host_bridge(struct pci_bus *bus)
+{
+ struct pci_bus *b = bus;
+
+ /* Find the PCI root bus */
+ while (b->parent)
+ b = b->parent;
+
+ return to_pci_host_bridge(b->bridge);
+}
+
+EXPORT_SYMBOL(pci_bus_host_bridge);
+
void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
void (*release_fn)(struct pci_host_bridge *),
void *release_data)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index fefb4e1..6d5bb1c 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -656,7 +656,7 @@ void pcibios_update_irq(struct pci_dev *, int irq);
void pci_fixup_cardbus(struct pci_bus *);
/* Generic PCI functions used internally */
-
+struct pci_host_bridge *pci_bus_host_bridge(struct pci_bus *bus);
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
struct resource *res);
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/4] powerpc: vio: Remove dma not supported warnings
From: Anton Blanchard @ 2012-06-25 4:23 UTC (permalink / raw)
To: benh, paulus, michael, miltonm, nacc, brking, rcj; +Cc: linuxppc-dev
During boot we see a number of these warnings:
vio 30000000: Warning: IOMMU dma not supported: mask 0xffffffffffffffff, table unavailable
The reason for this is that we set IOMMU properties for all VIO
devices even if they are not DMA capable.
Only set DMA ops, table and mask for devices with a DMA window.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/kernel/vio.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vio.c 2012-06-08 14:02:05.548512941 +1000
+++ linux-build/arch/powerpc/kernel/vio.c 2012-06-25 13:49:54.349806390 +1000
@@ -1397,21 +1397,27 @@ struct vio_dev *vio_register_device_node
viodev->name = of_node->name;
viodev->dev.of_node = of_node_get(of_node);
- if (firmware_has_feature(FW_FEATURE_CMO))
- vio_cmo_set_dma_ops(viodev);
- else
- set_dma_ops(&viodev->dev, &dma_iommu_ops);
- set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev));
set_dev_node(&viodev->dev, of_node_to_nid(of_node));
/* init generic 'struct device' fields: */
viodev->dev.parent = &vio_bus_device.dev;
viodev->dev.bus = &vio_bus_type;
viodev->dev.release = vio_dev_release;
- /* needed to ensure proper operation of coherent allocations
- * later, in case driver doesn't set it explicitly */
- dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
- dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
+
+ if (of_get_property(viodev->dev.of_node, "ibm,my-dma-window", NULL)) {
+ if (firmware_has_feature(FW_FEATURE_CMO))
+ vio_cmo_set_dma_ops(viodev);
+ else
+ set_dma_ops(&viodev->dev, &dma_iommu_ops);
+
+ set_iommu_table_base(&viodev->dev,
+ vio_build_iommu_table(viodev));
+
+ /* needed to ensure proper operation of coherent allocations
+ * later, in case driver doesn't set it explicitly */
+ dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
+ dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
+ }
/* register with generic device framework */
if (device_register(&viodev->dev)) {
^ permalink raw reply
* [PATCH 2/4] powerpc: vio: Separate vio bus probe and device probe
From: Anton Blanchard @ 2012-06-25 4:24 UTC (permalink / raw)
To: benh, paulus, michael, miltonm, nacc, brking, rcj; +Cc: linuxppc-dev
In-Reply-To: <20120625142353.0a92791a@kryten>
Similar to PCI, separate the bus probe from device probe. This allows
us to attach bus notifiers for DMA debug and IOMMU fault injection
before devices have been probed.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/kernel/vio.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vio.c 2012-06-08 09:14:19.282098456 +1000
+++ linux-build/arch/powerpc/kernel/vio.c 2012-06-08 09:16:53.856359566 +1000
@@ -1497,12 +1497,18 @@ static int __init vio_bus_init(void)
if (firmware_has_feature(FW_FEATURE_CMO))
vio_cmo_bus_init();
+ return 0;
+}
+postcore_initcall(vio_bus_init);
+
+static int __init vio_device_init(void)
+{
vio_bus_scan_register_devices("vdevice");
vio_bus_scan_register_devices("ibm,platform-facilities");
return 0;
}
-__initcall(vio_bus_init);
+device_initcall(vio_device_init);
static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buf)
^ permalink raw reply
* [PATCH 3/4] powerpc: call dma_debug_add_bus for PCI and VIO buses
From: Anton Blanchard @ 2012-06-25 4:25 UTC (permalink / raw)
To: benh, paulus, michael, miltonm, nacc, brking, rcj; +Cc: linuxppc-dev
In-Reply-To: <20120625142353.0a92791a@kryten>
The DMA API debug code has hooks to verify all DMA entries have been
freed at time of hot unplug. We need to call dma_debug_add_bus for
this to work.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/kernel/vio.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vio.c 2012-06-08 09:16:53.856359566 +1000
+++ linux-build/arch/powerpc/kernel/vio.c 2012-06-08 09:17:43.625089518 +1000
@@ -37,8 +37,6 @@
#include <asm/page.h>
#include <asm/hvcall.h>
-static struct bus_type vio_bus_type;
-
static struct vio_dev vio_bus_device = { /* fake "parent" device */
.name = "vio",
.type = "",
@@ -1580,7 +1578,7 @@ static int vio_hotplug(struct device *de
return 0;
}
-static struct bus_type vio_bus_type = {
+struct bus_type vio_bus_type = {
.name = "vio",
.dev_attrs = vio_dev_attrs,
.uevent = vio_hotplug,
Index: linux-build/arch/powerpc/kernel/dma.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/dma.c 2012-06-08 09:12:47.356758198 +1000
+++ linux-build/arch/powerpc/kernel/dma.c 2012-06-08 09:17:43.625089518 +1000
@@ -11,6 +11,8 @@
#include <linux/gfp.h>
#include <linux/memblock.h>
#include <linux/export.h>
+#include <linux/pci.h>
+#include <asm/vio.h>
#include <asm/bug.h>
#include <asm/abs_addr.h>
#include <asm/machdep.h>
@@ -205,7 +207,13 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask)
static int __init dma_init(void)
{
- dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+#ifdef CONFIG_PCI
+ dma_debug_add_bus(&pci_bus_type);
+#endif
+#ifdef CONFIG_IBMVIO
+ dma_debug_add_bus(&vio_bus_type);
+#endif
return 0;
}
Index: linux-build/arch/powerpc/include/asm/vio.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/vio.h 2012-06-08 09:12:47.344758025 +1000
+++ linux-build/arch/powerpc/include/asm/vio.h 2012-06-08 09:17:43.625089518 +1000
@@ -44,6 +44,8 @@
*/
#define VIO_CMO_MIN_ENT 1562624
+extern struct bus_type vio_bus_type;
+
struct iommu_table;
/*
^ permalink raw reply
* [PATCH 4/4] powerpc: IOMMU fault injection
From: Anton Blanchard @ 2012-06-25 4:26 UTC (permalink / raw)
To: benh, paulus, michael, miltonm, nacc, brking, rcj; +Cc: linuxppc-dev
In-Reply-To: <20120625142353.0a92791a@kryten>
Add the ability to inject IOMMU faults. We enable this per device
via a fail_iommu sysfs property, similar to fault injection on other
subsystems.
An example:
# lspci
...
0003:01:00.1 Ethernet controller: Emulex Corporation OneConnect 10Gb NIC (be3) (rev 02)
To inject one error to this device:
echo 1 > /sys/bus/pci/devices/0003:01:00.1/fail_iommu
echo 1 > /sys/kernel/debug/fail_iommu/probability
echo 1 > /sys/kernel/debug/fail_iommu/times
As feared, the first failure injected on the be3 results in an
unrecoverable error, taking down both functions of the card
permanently:
be2net 0003:01:00.1: Unrecoverable error in the card
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/kernel/iommu.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/iommu.c 2012-06-08 09:01:02.785709100 +1000
+++ linux-build/arch/powerpc/kernel/iommu.c 2012-06-08 09:01:07.489784856 +1000
@@ -33,7 +33,9 @@
#include <linux/bitmap.h>
#include <linux/iommu-helper.h>
#include <linux/crash_dump.h>
+#include <linux/fault-inject.h>
#include <asm/io.h>
+#include <asm/vio.h>
#include <asm/prom.h>
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
@@ -58,6 +60,94 @@ static int __init setup_iommu(char *str)
__setup("iommu=", setup_iommu);
+#ifdef CONFIG_FAIL_IOMMU
+
+static DECLARE_FAULT_ATTR(fail_iommu);
+
+static int __init setup_fail_iommu(char *str)
+{
+ return setup_fault_attr(&fail_iommu, str);
+}
+__setup("fail_iommu=", setup_fail_iommu);
+
+static bool should_fail_iommu(struct device *dev)
+{
+ return dev->archdata.fail_iommu && should_fail(&fail_iommu, 1);
+}
+
+static int __init fail_iommu_debugfs(void)
+{
+ struct dentry *dir = fault_create_debugfs_attr("fail_iommu",
+ NULL, &fail_iommu);
+
+ return IS_ERR(dir) ? PTR_ERR(dir) : 0;
+}
+late_initcall(fail_iommu_debugfs);
+
+static ssize_t fail_iommu_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", dev->archdata.fail_iommu);
+}
+
+static ssize_t fail_iommu_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int i;
+
+ if (count > 0 && sscanf(buf, "%d", &i) > 0)
+ dev->archdata.fail_iommu = (i == 0) ? 0 : 1;
+
+ return count;
+}
+
+static DEVICE_ATTR(fail_iommu, S_IRUGO|S_IWUSR, fail_iommu_show,
+ fail_iommu_store);
+
+static int fail_iommu_bus_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+
+ if (action == BUS_NOTIFY_ADD_DEVICE) {
+ if (device_create_file(dev, &dev_attr_fail_iommu))
+ pr_warn("Unable to create IOMMU fault injection sysfs "
+ "entries\n");
+ } else if (action == BUS_NOTIFY_DEL_DEVICE) {
+ device_remove_file(dev, &dev_attr_fail_iommu);
+ }
+
+ return 0;
+}
+
+static struct notifier_block fail_iommu_bus_notifier = {
+ .notifier_call = fail_iommu_bus_notify
+};
+
+static int __init fail_iommu_setup(void)
+{
+#ifdef CONFIG_PCI
+ bus_register_notifier(&pci_bus_type, &fail_iommu_bus_notifier);
+#endif
+#ifdef CONFIG_IBMVIO
+ bus_register_notifier(&vio_bus_type, &fail_iommu_bus_notifier);
+#endif
+
+ return 0;
+}
+/*
+ * Must execute after PCI and VIO subsystem have initialised but before
+ * devices are probed.
+ */
+arch_initcall(fail_iommu_setup);
+#else
+static inline bool should_fail_iommu(struct device *dev)
+{
+ return false;
+}
+#endif
+
static unsigned long iommu_range_alloc(struct device *dev,
struct iommu_table *tbl,
unsigned long npages,
@@ -83,6 +173,9 @@ static unsigned long iommu_range_alloc(s
return DMA_ERROR_CODE;
}
+ if (should_fail_iommu(dev))
+ return DMA_ERROR_CODE;
+
if (handle && *handle)
start = *handle;
else
Index: linux-build/arch/powerpc/include/asm/device.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/device.h 2012-06-08 09:01:02.765708778 +1000
+++ linux-build/arch/powerpc/include/asm/device.h 2012-06-08 09:01:07.489784856 +1000
@@ -34,6 +34,9 @@ struct dev_archdata {
#ifdef CONFIG_EEH
struct eeh_dev *edev;
#endif
+#ifdef CONFIG_FAIL_IOMMU
+ int fail_iommu;
+#endif
};
struct pdev_archdata {
Index: linux-build/arch/powerpc/Kconfig.debug
===================================================================
--- linux-build.orig/arch/powerpc/Kconfig.debug 2012-06-08 09:01:02.753708585 +1000
+++ linux-build/arch/powerpc/Kconfig.debug 2012-06-08 09:01:07.489784856 +1000
@@ -331,4 +331,13 @@ config STRICT_DEVMEM
If you are unsure, say Y.
+config FAIL_IOMMU
+ bool "Fault-injection capability for IOMMU"
+ depends on FAULT_INJECTION
+ help
+ Provide fault-injection capability for IOMMU. Each device can
+ be selectively enabled via the fail_iommu property.
+
+ If you are unsure, say N.
+
endmenu
^ permalink raw reply
* [PATCH v2 1/1] of: reform prom_update_property function
From: Dong Aisheng @ 2012-06-25 6:28 UTC (permalink / raw)
To: linux-kernel; +Cc: devicetree-discuss, rob.herring, paulus, linuxppc-dev
From: Dong Aisheng <dong.aisheng@linaro.org>
prom_update_property() currently fails if the property doesn't
actually exist yet which isn't what we want. Change to add-or-update
instead of update-only, then we can remove a lot duplicated lines.
Suggested-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
---
ChangeLog v1->v2:
* keep reconfig.c behavior the same as before after changes
---
arch/powerpc/platforms/85xx/p1022_ds.c | 8 +-------
arch/powerpc/platforms/pseries/mobility.c | 8 +-------
arch/powerpc/platforms/pseries/reconfig.c | 16 ++++++----------
drivers/of/base.c | 15 +++++++++++----
fs/proc/proc_devtree.c | 5 +++++
include/linux/of.h | 3 +--
6 files changed, 25 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index f700c81..d66631c 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -348,13 +348,7 @@ void __init p1022_ds_pic_init(void)
*/
static void __init disable_one_node(struct device_node *np, struct property *new)
{
- struct property *old;
-
- old = of_find_property(np, new->name, NULL);
- if (old)
- prom_update_property(np, new, old);
- else
- prom_add_property(np, new);
+ prom_update_property(np, new);
}
/* TRUE if there is a "video=fslfb" command-line parameter. */
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 029a562..dd30b12 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -67,7 +67,6 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
const char *name, u32 vd, char *value)
{
struct property *new_prop = *prop;
- struct property *old_prop;
int more = 0;
/* A negative 'vd' value indicates that only part of the new property
@@ -117,12 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
}
if (!more) {
- old_prop = of_find_property(dn, new_prop->name, NULL);
- if (old_prop)
- prom_update_property(dn, new_prop, old_prop);
- else
- prom_add_property(dn, new_prop);
-
+ prom_update_property(dn, new_prop);
new_prop = NULL;
}
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 7b3bf76..db1b7b1 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -432,7 +432,7 @@ static int do_update_property(char *buf, size_t bufsize)
unsigned char *value;
char *name, *end, *next_prop;
int rc, length;
- struct property *newprop, *oldprop;
+ struct property *newprop;
buf = parse_node(buf, bufsize, &np);
end = buf + bufsize;
@@ -443,6 +443,9 @@ static int do_update_property(char *buf, size_t bufsize)
if (!next_prop)
return -EINVAL;
+ if (!strlen(name)
+ return -ENODEV;
+
newprop = new_property(name, length, value, NULL);
if (!newprop)
return -ENOMEM;
@@ -450,18 +453,11 @@ static int do_update_property(char *buf, size_t bufsize)
if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
slb_set_size(*(int *)value);
- oldprop = of_find_property(np, name,NULL);
- if (!oldprop) {
- if (strlen(name))
- return prom_add_property(np, newprop);
- return -ENODEV;
- }
-
upd_value.node = np;
upd_value.property = newprop;
pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value);
- rc = prom_update_property(np, newprop, oldprop);
+ rc = prom_update_property(np, newprop);
if (rc)
return rc;
@@ -486,7 +482,7 @@ static int do_update_property(char *buf, size_t bufsize)
rc = pSeries_reconfig_notify(action, value);
if (rc) {
- prom_update_property(np, oldprop, newprop);
+ prom_update_property(np, newprop);
return rc;
}
}
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d9bfd49..a14f109 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1051,7 +1051,8 @@ int prom_remove_property(struct device_node *np, struct property *prop)
}
/*
- * prom_update_property - Update a property in a node.
+ * prom_update_property - Update a property in a node, if the property does
+ * not exist, add it.
*
* Note that we don't actually remove it, since we have given out
* who-knows-how-many pointers to the data using get-property.
@@ -1059,13 +1060,19 @@ int prom_remove_property(struct device_node *np, struct property *prop)
* and add the new property to the property list
*/
int prom_update_property(struct device_node *np,
- struct property *newprop,
- struct property *oldprop)
+ struct property *newprop)
{
- struct property **next;
+ struct property **next, *oldprop;
unsigned long flags;
int found = 0;
+ if (!newprop->name)
+ return -EINVAL;
+
+ oldprop = of_find_property(np, newprop->name, NULL);
+ if (!oldprop)
+ return prom_add_property(np, newprop);
+
write_lock_irqsave(&devtree_lock, flags);
next = &np->properties;
while (*next) {
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 927cbd1..df7dd08 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -101,6 +101,11 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde,
{
struct proc_dir_entry *ent;
+ if (!oldprop) {
+ proc_device_tree_add_prop(pde, newprop);
+ return;
+ }
+
for (ent = pde->subdir; ent != NULL; ent = ent->next)
if (ent->data == oldprop)
break;
diff --git a/include/linux/of.h b/include/linux/of.h
index 2ec1083..b27c871 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -260,8 +260,7 @@ extern int of_machine_is_compatible(const char *compat);
extern int prom_add_property(struct device_node* np, struct property* prop);
extern int prom_remove_property(struct device_node *np, struct property *prop);
extern int prom_update_property(struct device_node *np,
- struct property *newprop,
- struct property *oldprop);
+ struct property *newprop);
#if defined(CONFIG_OF_DYNAMIC)
/* For updating the device tree at runtime */
--
1.7.0.4
^ permalink raw reply related
* [PATCH] bluetooth: opcode field of sent commands is little endian.
From: Michel Dänzer @ 2012-06-25 6:38 UTC (permalink / raw)
To: Johan Hedberg, Marcel Holtmann; +Cc: linux-bluetooth, linuxppc-dev
Fixes built-in Bluetooth not working on Apple PowerBooks, regression from
commit 75fb0e324daa48ec458fb5c2960eb07b80cfad9d ('Bluetooth: Fix init sequence
for some CSR based controllers').
Cc: stable@vger.kernel.org [v3.4]
Signed-off-by: Michel Dänzer <michel@daenzer.net>
---
net/bluetooth/hci_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d6dc44c..e039e3d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -92,7 +92,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
* command.
*/
- if (cmd != HCI_OP_RESET || sent->opcode == HCI_OP_RESET)
+ if (cmd != HCI_OP_RESET || sent->opcode == cpu_to_le16(HCI_OP_RESET))
return;
skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH v2 1/1] of: reform prom_update_property function
From: Benjamin Herrenschmidt @ 2012-06-25 6:46 UTC (permalink / raw)
To: Dong Aisheng
Cc: devicetree-discuss, linux-kernel, rob.herring, paulus,
linuxppc-dev
In-Reply-To: <1340605714-25206-1-git-send-email-b29396@freescale.com>
On Mon, 2012-06-25 at 14:28 +0800, Dong Aisheng wrote:
> From: Dong Aisheng <dong.aisheng@linaro.org>
>
> prom_update_property() currently fails if the property doesn't
> actually exist yet which isn't what we want. Change to add-or-update
> instead of update-only, then we can remove a lot duplicated lines.
>
> Suggested-by: Grant Likely <grant.likely@secretlab.ca>
> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
> ---
Grand, should I merge that via the powerpc tree or will you take care of
it ?
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cheers,
Ben.
> ChangeLog v1->v2:
> * keep reconfig.c behavior the same as before after changes
> ---
> arch/powerpc/platforms/85xx/p1022_ds.c | 8 +-------
> arch/powerpc/platforms/pseries/mobility.c | 8 +-------
> arch/powerpc/platforms/pseries/reconfig.c | 16 ++++++----------
> drivers/of/base.c | 15 +++++++++++----
> fs/proc/proc_devtree.c | 5 +++++
> include/linux/of.h | 3 +--
> 6 files changed, 25 insertions(+), 30 deletions(-)
>
> diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
> index f700c81..d66631c 100644
> --- a/arch/powerpc/platforms/85xx/p1022_ds.c
> +++ b/arch/powerpc/platforms/85xx/p1022_ds.c
> @@ -348,13 +348,7 @@ void __init p1022_ds_pic_init(void)
> */
> static void __init disable_one_node(struct device_node *np, struct property *new)
> {
> - struct property *old;
> -
> - old = of_find_property(np, new->name, NULL);
> - if (old)
> - prom_update_property(np, new, old);
> - else
> - prom_add_property(np, new);
> + prom_update_property(np, new);
> }
>
> /* TRUE if there is a "video=fslfb" command-line parameter. */
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index 029a562..dd30b12 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -67,7 +67,6 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
> const char *name, u32 vd, char *value)
> {
> struct property *new_prop = *prop;
> - struct property *old_prop;
> int more = 0;
>
> /* A negative 'vd' value indicates that only part of the new property
> @@ -117,12 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
> }
>
> if (!more) {
> - old_prop = of_find_property(dn, new_prop->name, NULL);
> - if (old_prop)
> - prom_update_property(dn, new_prop, old_prop);
> - else
> - prom_add_property(dn, new_prop);
> -
> + prom_update_property(dn, new_prop);
> new_prop = NULL;
> }
>
> diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
> index 7b3bf76..db1b7b1 100644
> --- a/arch/powerpc/platforms/pseries/reconfig.c
> +++ b/arch/powerpc/platforms/pseries/reconfig.c
> @@ -432,7 +432,7 @@ static int do_update_property(char *buf, size_t bufsize)
> unsigned char *value;
> char *name, *end, *next_prop;
> int rc, length;
> - struct property *newprop, *oldprop;
> + struct property *newprop;
> buf = parse_node(buf, bufsize, &np);
> end = buf + bufsize;
>
> @@ -443,6 +443,9 @@ static int do_update_property(char *buf, size_t bufsize)
> if (!next_prop)
> return -EINVAL;
>
> + if (!strlen(name)
> + return -ENODEV;
> +
> newprop = new_property(name, length, value, NULL);
> if (!newprop)
> return -ENOMEM;
> @@ -450,18 +453,11 @@ static int do_update_property(char *buf, size_t bufsize)
> if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
> slb_set_size(*(int *)value);
>
> - oldprop = of_find_property(np, name,NULL);
> - if (!oldprop) {
> - if (strlen(name))
> - return prom_add_property(np, newprop);
> - return -ENODEV;
> - }
> -
> upd_value.node = np;
> upd_value.property = newprop;
> pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value);
>
> - rc = prom_update_property(np, newprop, oldprop);
> + rc = prom_update_property(np, newprop);
> if (rc)
> return rc;
>
> @@ -486,7 +482,7 @@ static int do_update_property(char *buf, size_t bufsize)
>
> rc = pSeries_reconfig_notify(action, value);
> if (rc) {
> - prom_update_property(np, oldprop, newprop);
> + prom_update_property(np, newprop);
> return rc;
> }
> }
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d9bfd49..a14f109 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -1051,7 +1051,8 @@ int prom_remove_property(struct device_node *np, struct property *prop)
> }
>
> /*
> - * prom_update_property - Update a property in a node.
> + * prom_update_property - Update a property in a node, if the property does
> + * not exist, add it.
> *
> * Note that we don't actually remove it, since we have given out
> * who-knows-how-many pointers to the data using get-property.
> @@ -1059,13 +1060,19 @@ int prom_remove_property(struct device_node *np, struct property *prop)
> * and add the new property to the property list
> */
> int prom_update_property(struct device_node *np,
> - struct property *newprop,
> - struct property *oldprop)
> + struct property *newprop)
> {
> - struct property **next;
> + struct property **next, *oldprop;
> unsigned long flags;
> int found = 0;
>
> + if (!newprop->name)
> + return -EINVAL;
> +
> + oldprop = of_find_property(np, newprop->name, NULL);
> + if (!oldprop)
> + return prom_add_property(np, newprop);
> +
> write_lock_irqsave(&devtree_lock, flags);
> next = &np->properties;
> while (*next) {
> diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
> index 927cbd1..df7dd08 100644
> --- a/fs/proc/proc_devtree.c
> +++ b/fs/proc/proc_devtree.c
> @@ -101,6 +101,11 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde,
> {
> struct proc_dir_entry *ent;
>
> + if (!oldprop) {
> + proc_device_tree_add_prop(pde, newprop);
> + return;
> + }
> +
> for (ent = pde->subdir; ent != NULL; ent = ent->next)
> if (ent->data == oldprop)
> break;
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 2ec1083..b27c871 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -260,8 +260,7 @@ extern int of_machine_is_compatible(const char *compat);
> extern int prom_add_property(struct device_node* np, struct property* prop);
> extern int prom_remove_property(struct device_node *np, struct property *prop);
> extern int prom_update_property(struct device_node *np,
> - struct property *newprop,
> - struct property *oldprop);
> + struct property *newprop);
>
> #if defined(CONFIG_OF_DYNAMIC)
> /* For updating the device tree at runtime */
^ permalink raw reply
* Re: [PATCH] bluetooth: opcode field of sent commands is little endian.
From: Marcel Holtmann @ 2012-06-25 6:51 UTC (permalink / raw)
To: Michel Dänzer; +Cc: linux-bluetooth, Johan Hedberg, linuxppc-dev
In-Reply-To: <1340606319-32187-1-git-send-email-michel@daenzer.net>
Hi Michel,
> Fixes built-in Bluetooth not working on Apple PowerBooks, regression from
> commit 75fb0e324daa48ec458fb5c2960eb07b80cfad9d ('Bluetooth: Fix init sequence
> for some CSR based controllers').
>
> Cc: stable@vger.kernel.org [v3.4]
> Signed-off-by: Michel Dänzer <michel@daenzer.net>
> ---
> net/bluetooth/hci_core.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index d6dc44c..e039e3d 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -92,7 +92,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
> * command.
> */
>
> - if (cmd != HCI_OP_RESET || sent->opcode == HCI_OP_RESET)
> + if (cmd != HCI_OP_RESET || sent->opcode == cpu_to_le16(HCI_OP_RESET))
> return;
actually you could use __constant_cpu_to_le16() here.
That said, this got actually fixed differently upstream. So I prefer if
that patch gets merged into stable and not this one.
commit 1036b89042df96e71c0cb941be212f8053ecccc0
Author: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Date: Mon Mar 12 15:59:33 2012 +0200
Bluetooth: Fix opcode access in hci_complete
In general patches need to get into Linus' tree first before you can
even request them for stable.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] bluetooth: opcode field of sent commands is little endian.
From: Michel Dänzer @ 2012-06-25 7:06 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth, Johan Hedberg, linuxppc-dev
In-Reply-To: <1340607113.29898.3.camel@aeonflux>
On Son, 2012-06-24 at 23:51 -0700, Marcel Holtmann wrote:=20
> Hi Michel,
>=20
> > Fixes built-in Bluetooth not working on Apple PowerBooks, regression fr=
om
> > commit 75fb0e324daa48ec458fb5c2960eb07b80cfad9d ('Bluetooth: Fix init s=
equence
> > for some CSR based controllers').
> >=20
> > Cc: stable@vger.kernel.org [v3.4]
> > Signed-off-by: Michel D=E4nzer <michel@daenzer.net>
> > ---
> > net/bluetooth/hci_core.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >=20
> > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > index d6dc44c..e039e3d 100644
> > --- a/net/bluetooth/hci_core.c
> > +++ b/net/bluetooth/hci_core.c
> > @@ -92,7 +92,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd=
, int result)
> > * command.
> > */
> > =20
> > - if (cmd !=3D HCI_OP_RESET || sent->opcode =3D=3D HCI_OP_RESET)
> > + if (cmd !=3D HCI_OP_RESET || sent->opcode =3D=3D cpu_to_le16(HCI_OP_=
RESET))
> > return;
>=20
> actually you could use __constant_cpu_to_le16() here.
Yes, but I checked and that's not used anywhere in the bluetooth code
yet, so I thought I'd stay consistent for now.
> That said, this got actually fixed differently upstream. So I prefer if
> that patch gets merged into stable and not this one.
>=20
> commit 1036b89042df96e71c0cb941be212f8053ecccc0
> Author: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> Date: Mon Mar 12 15:59:33 2012 +0200
>=20
> Bluetooth: Fix opcode access in hci_complete
Fine with me, though FWIW that not only doesn't use
__constant_cpu_to_le16() but actually swaps the non-constant value.
Also, it would have been nice if that fix was promoted to stable, so I
wouldn't have had to spend a good part of the weekend bisecting...
> In general patches need to get into Linus' tree first before you can
> even request them for stable.
I know, that's why I only put the stable tag in commit logs but don't
submit patches there via e-mail.
--=20
Earthling Michel D=E4nzer | http://www.amd.com
Libre software enthusiast | Debian, X and DRI developer
^ permalink raw reply
* Re: [PATCH] bluetooth: opcode field of sent commands is little endian.
From: Marcel Holtmann @ 2012-06-25 7:22 UTC (permalink / raw)
To: Michel Dänzer; +Cc: linux-bluetooth, Johan Hedberg, linuxppc-dev
In-Reply-To: <1340607965.5461.40.camel@thor.local>
Hi Michel,
> > > Fixes built-in Bluetooth not working on Apple PowerBooks, regression from
> > > commit 75fb0e324daa48ec458fb5c2960eb07b80cfad9d ('Bluetooth: Fix init sequence
> > > for some CSR based controllers').
> > >
> > > Cc: stable@vger.kernel.org [v3.4]
> > > Signed-off-by: Michel Dänzer <michel@daenzer.net>
> > > ---
> > > net/bluetooth/hci_core.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > > index d6dc44c..e039e3d 100644
> > > --- a/net/bluetooth/hci_core.c
> > > +++ b/net/bluetooth/hci_core.c
> > > @@ -92,7 +92,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
> > > * command.
> > > */
> > >
> > > - if (cmd != HCI_OP_RESET || sent->opcode == HCI_OP_RESET)
> > > + if (cmd != HCI_OP_RESET || sent->opcode == cpu_to_le16(HCI_OP_RESET))
> > > return;
> >
> > actually you could use __constant_cpu_to_le16() here.
>
> Yes, but I checked and that's not used anywhere in the bluetooth code
> yet, so I thought I'd stay consistent for now.
not sure what code you are looking at, but I count 18 occurrences and we
have been fixing the ones we missed initially.
> > That said, this got actually fixed differently upstream. So I prefer if
> > that patch gets merged into stable and not this one.
> >
> > commit 1036b89042df96e71c0cb941be212f8053ecccc0
> > Author: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> > Date: Mon Mar 12 15:59:33 2012 +0200
> >
> > Bluetooth: Fix opcode access in hci_complete
>
> Fine with me, though FWIW that not only doesn't use
> __constant_cpu_to_le16() but actually swaps the non-constant value.
Don't see what point you are trying to make here. Swapping the value
from the actual command structure is always fine with me.
> Also, it would have been nice if that fix was promoted to stable, so I
> wouldn't have had to spend a good part of the weekend bisecting...
Thinks like this happen. However after you bisected the issue you could
have just checked what is in Linus' or bluetooth-next tree. Since the
first thing I did is go through bluetooth-next and check if we have not
fixed that yet.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] bluetooth: opcode field of sent commands is little endian.
From: Michel Dänzer @ 2012-06-25 7:32 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth, Johan Hedberg, linuxppc-dev
In-Reply-To: <1340608972.29898.13.camel@aeonflux>
On Mon, 2012-06-25 at 00:22 -0700, Marcel Holtmann wrote:=20
> Hi Michel,
>=20
> > > > Fixes built-in Bluetooth not working on Apple PowerBooks, regressio=
n from
> > > > commit 75fb0e324daa48ec458fb5c2960eb07b80cfad9d ('Bluetooth: Fix in=
it sequence
> > > > for some CSR based controllers').
> > > >=20
> > > > Cc: stable@vger.kernel.org [v3.4]
> > > > Signed-off-by: Michel D=E4nzer <michel@daenzer.net>
> > > > ---
> > > > net/bluetooth/hci_core.c | 2 +-
> > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > >=20
> > > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > > > index d6dc44c..e039e3d 100644
> > > > --- a/net/bluetooth/hci_core.c
> > > > +++ b/net/bluetooth/hci_core.c
> > > > @@ -92,7 +92,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16=
cmd, int result)
> > > > * command.
> > > > */
> > > > =20
> > > > - if (cmd !=3D HCI_OP_RESET || sent->opcode =3D=3D HCI_OP_RESET)
> > > > + if (cmd !=3D HCI_OP_RESET || sent->opcode =3D=3D cpu_to_le16(HCI=
_OP_RESET))
> > > > return;
> > >=20
> > > actually you could use __constant_cpu_to_le16() here.
> >=20
> > Yes, but I checked and that's not used anywhere in the bluetooth code
> > yet, so I thought I'd stay consistent for now.
>=20
> not sure what code you are looking at, but I count 18 occurrences and we
> have been fixing the ones we missed initially.
Okay, good then. As you probably noticed from the rest of my posts, I
only checked up to 3.4.
> > > That said, this got actually fixed differently upstream. So I prefer =
if
> > > that patch gets merged into stable and not this one.
> > >=20
> > > commit 1036b89042df96e71c0cb941be212f8053ecccc0
> > > Author: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> > > Date: Mon Mar 12 15:59:33 2012 +0200
> > >=20
> > > Bluetooth: Fix opcode access in hci_complete
> >=20
> > Fine with me, though FWIW that not only doesn't use
> > __constant_cpu_to_le16() but actually swaps the non-constant value.
>=20
> Don't see what point you are trying to make here. Swapping the value
> from the actual command structure is always fine with me.
The point is that the result of swapping a constant value is just
another constant value, whereas the fix in mainline swaps a value from
memory. Not a big deal.
> > Also, it would have been nice if that fix was promoted to stable, so I
> > wouldn't have had to spend a good part of the weekend bisecting...
>=20
> Thinks like this happen. However after you bisected the issue you could
> have just checked what is in Linus' or bluetooth-next tree.
You're probably right. It just didn't occur to me that someone would
have fixed this but not forwarded the fix to stable, because I generally
do that. :}
Will you submit the fix to stable, or should I?
--=20
Earthling Michel D=E4nzer | http://www.amd.com
Libre software enthusiast | Debian, X and DRI developer
^ permalink raw reply
* Re: [PATCH] bluetooth: opcode field of sent commands is little endian.
From: Andrei Emeltchenko @ 2012-06-25 8:02 UTC (permalink / raw)
To: Michel Dänzer, Gustavo Padovan
Cc: linux-bluetooth, Marcel Holtmann, Johan Hedberg, linuxppc-dev
In-Reply-To: <1340609570.5461.50.camel@thor.local>
Hi Michel,
On Mon, Jun 25, 2012 at 09:32:50AM +0200, Michel Dänzer wrote:
> > > Also, it would have been nice if that fix was promoted to stable, so I
> > > wouldn't have had to spend a good part of the weekend bisecting...
> >
> > Thinks like this happen. However after you bisected the issue you could
> > have just checked what is in Linus' or bluetooth-next tree.
>
> You're probably right. It just didn't occur to me that someone would
> have fixed this but not forwarded the fix to stable, because I generally
> do that. :}
Sorry for that, this and bunch of other fixes for byte order bugs needs to
be promoted to stable.
> Will you submit the fix to stable, or should I?
I added Gustavo to CC as he usually makes pull requests.
Best regards
Andrei Emeltchenko
^ permalink raw reply
* RE: [PATCH] bluetooth: opcode field of sent commands is little endian.
From: David Laight @ 2012-06-25 9:20 UTC (permalink / raw)
To: Michel Dänzer, Marcel Holtmann
Cc: linux-bluetooth, Johan Hedberg, linuxppc-dev
In-Reply-To: <1340609570.5461.50.camel@thor.local>
=20
> > > Fine with me, though FWIW that not only doesn't use
> > > __constant_cpu_to_le16() but actually swaps the non-constant =
value.
> >=20
> > Don't see what point you are trying to make here. Swapping the value
> > from the actual command structure is always fine with me.
>=20
> The point is that the result of swapping a constant value is just
> another constant value, whereas the fix in mainline swaps a value from
> memory. Not a big deal.
Surely, but surely, the definition of cpu_to_le16() uses
gcc 'magic' to determine that the argument is a constant
and then automatically selects the 'constant' form.
David
^ permalink raw reply
* Re: [PATCH] bluetooth: opcode field of sent commands is little endian.
From: Michel Dänzer @ 2012-06-25 9:33 UTC (permalink / raw)
To: David Laight
Cc: linux-bluetooth, Marcel Holtmann, Johan Hedberg, linuxppc-dev
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B6F62@saturn3.aculab.com>
On Mon, 2012-06-25 at 10:20 +0100, David Laight wrote:=20
> > > > Fine with me, though FWIW that not only doesn't use
> > > > __constant_cpu_to_le16() but actually swaps the non-constant value.
> > >=20
> > > Don't see what point you are trying to make here. Swapping the value
> > > from the actual command structure is always fine with me.
> >=20
> > The point is that the result of swapping a constant value is just
> > another constant value, whereas the fix in mainline swaps a value from
> > memory. Not a big deal.
>=20
> Surely, but surely, the definition of cpu_to_le16() uses
> gcc 'magic' to determine that the argument is a constant
> and then automatically selects the 'constant' form.
It can only do that if the argument is constant in the first place
though. :)
--=20
Earthling Michel D=E4nzer | http://www.amd.com
Libre software enthusiast | Debian, X and DRI developer
^ permalink raw reply
* Re: [PATCH] powerpc: Add VDSO version of getcpu
From: Benjamin Herrenschmidt @ 2012-06-25 9:44 UTC (permalink / raw)
To: Anton Blanchard; +Cc: linuxppc-dev, paulus
In-Reply-To: <20120625115540.2a7ad9c5@kryten>
On Mon, 2012-06-25 at 11:55 +1000, Anton Blanchard wrote:
> We had a request for a fast method of getting CPU and NUMA node IDs
> from userspace. Ben suggested we use SPRG3 which is userspace
> readable. This is a quick hack to try that out.
>
> I have a glibc patch to implement sched_getcpu using this. Testing
> on a POWER7:
>
> baseline: 538 cycles
> vdso: 30 cycles
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
>
> Outstanding issues:
>
> - Do we have any KVM issues?
Yes we do. We need to restore SPRG3 somewhere in book3s_hv_rmhandlers.S
or it will remain to the value set by the guest. I suggest storing the
"proper" value in the PACA at boot time so we avoid having to save it
on each guest entry.
On the other hand, paulus was thinking of a hack for some other type
of process that might want to use SPRG3... (and set it using a syscall)
in which case we'd have to disable the getcpu optimization for those and
actually context switch SPRG3.. dunno what happened with that code.
Cheers,
Ben.,
> - This will only work with 64 bit kernels for now, do we need to come up
> with a scheme for 32 bit?
>
> - Implement 32 bit userspace version (running on 64 bit kernels)
>
> Index: linux-build/arch/powerpc/include/asm/reg.h
> ===================================================================
> --- linux-build.orig/arch/powerpc/include/asm/reg.h 2012-06-25 10:05:52.193076424 +1000
> +++ linux-build/arch/powerpc/include/asm/reg.h 2012-06-25 10:09:02.932316659 +1000
> @@ -491,6 +491,7 @@
> #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
> #define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
> #define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
> +#define SPRN_USPRG3 0x103 /* SPRG3 userspace read */
> #define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */
> #define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */
> #define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */
> @@ -753,14 +754,14 @@
> * 64-bit server:
> * - SPRG0 unused (reserved for HV on Power4)
> * - SPRG2 scratch for exception vectors
> - * - SPRG3 unused (user visible)
> + * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
> * - HSPRG0 stores PACA in HV mode
> * - HSPRG1 scratch for "HV" exceptions
> *
> * 64-bit embedded
> * - SPRG0 generic exception scratch
> * - SPRG2 TLB exception stack
> - * - SPRG3 unused (user visible)
> + * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
> * - SPRG4 unused (user visible)
> * - SPRG6 TLB miss scratch (user visible, sorry !)
> * - SPRG7 critical exception scratch
> Index: linux-build/arch/powerpc/kernel/vdso.c
> ===================================================================
> --- linux-build.orig/arch/powerpc/kernel/vdso.c 2012-06-25 10:05:52.229077036 +1000
> +++ linux-build/arch/powerpc/kernel/vdso.c 2012-06-25 10:12:50.256171890 +1000
> @@ -706,6 +706,25 @@ static void __init vdso_setup_syscall_ma
> }
> }
>
> +#ifdef CONFIG_PPC64
> +int __cpuinit vdso_getcpu_init(void)
> +{
> + unsigned long cpu, node;
> +
> + /*
> + * SPRG3 contains the CPU in the bottom 32 bits and the NUMA node in the
> + * top 32 bits.
> + */
> + cpu = get_cpu();
> + node = cpu_to_node(cpu);
> + mtspr(SPRN_SPRG3, cpu | (node << 32));
> + put_cpu();
> +
> + return 0;
> +}
> +/* We need to call this before SMP init */
> +early_initcall(vdso_getcpu_init);
> +#endif
>
> static int __init vdso_init(void)
> {
> Index: linux-build/arch/powerpc/kernel/vdso64/Makefile
> ===================================================================
> --- linux-build.orig/arch/powerpc/kernel/vdso64/Makefile 2012-06-25 10:05:52.209076696 +1000
> +++ linux-build/arch/powerpc/kernel/vdso64/Makefile 2012-06-25 10:05:53.737102674 +1000
> @@ -1,6 +1,6 @@
> # List of files in the vdso, has to be asm only for now
>
> -obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
> +obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o
>
> # Build rules
>
> Index: linux-build/arch/powerpc/kernel/vdso64/vdso64.lds.S
> ===================================================================
> --- linux-build.orig/arch/powerpc/kernel/vdso64/vdso64.lds.S 2012-06-25 10:05:52.217076832 +1000
> +++ linux-build/arch/powerpc/kernel/vdso64/vdso64.lds.S 2012-06-25 10:05:53.737102674 +1000
> @@ -146,6 +146,7 @@ VERSION
> __kernel_sync_dicache;
> __kernel_sync_dicache_p5;
> __kernel_sigtramp_rt64;
> + __kernel_getcpu;
>
> local: *;
> };
> Index: linux-build/arch/powerpc/kernel/vdso64/getcpu.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-build/arch/powerpc/kernel/vdso64/getcpu.S 2012-06-25 10:09:11.796467121 +1000
> @@ -0,0 +1,44 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + *
> + * Copyright (C) IBM Corporation, 2012
> + *
> + * Author: Anton Blanchard <anton@au.ibm.com>
> + */
> +#include <asm/ppc_asm.h>
> +#include <asm/vdso.h>
> +
> + .text
> +/*
> + * Exact prototype of getcpu
> + *
> + * int __kernel_getcpu(unsigned *cpu, unsigned *node);
> + *
> + */
> +V_FUNCTION_BEGIN(__kernel_getcpu)
> + .cfi_startproc
> + mfspr r5,SPRN_USPRG3
> + cmpdi cr0,r3,0
> + cmpdi cr1,r4,0
> + srdi r6,r5,32
> + beq cr0,1f
> + stw r5,0(r3)
> +1: beq cr1,2f
> + stw r6,0(r4)
> +2: crclr cr0*4+so
> + li r3,0 /* always success */
> + blr
> + .cfi_endproc
> +V_FUNCTION_END(__kernel_getcpu)
> Index: linux-build/arch/powerpc/kernel/smp.c
> ===================================================================
> --- linux-build.orig/arch/powerpc/kernel/smp.c 2012-06-25 10:05:52.197076492 +1000
> +++ linux-build/arch/powerpc/kernel/smp.c 2012-06-25 10:13:54.897266908 +1000
> @@ -48,6 +48,7 @@
> #ifdef CONFIG_PPC64
> #include <asm/paca.h>
> #endif
> +#include <asm/vdso.h>
> #include <asm/debug.h>
>
> #ifdef DEBUG
> @@ -570,6 +571,8 @@ void __devinit start_secondary(void *unu
> #ifdef CONFIG_PPC64
> if (system_state == SYSTEM_RUNNING)
> vdso_data->processorCount++;
> +
> + vdso_getcpu_init();
> #endif
> ipi_call_lock();
> notify_cpu_starting(cpu);
> Index: linux-build/arch/powerpc/include/asm/vdso.h
> ===================================================================
> --- linux-build.orig/arch/powerpc/include/asm/vdso.h 2012-06-25 10:05:52.181076220 +1000
> +++ linux-build/arch/powerpc/include/asm/vdso.h 2012-06-25 10:05:53.737102674 +1000
> @@ -22,6 +22,8 @@ extern unsigned long vdso64_rt_sigtramp;
> extern unsigned long vdso32_sigtramp;
> extern unsigned long vdso32_rt_sigtramp;
>
> +int __cpuinit vdso_getcpu_init(void);
> +
> #else /* __ASSEMBLY__ */
>
> #ifdef __VDSO64__
^ permalink raw reply
* [PATCH SLUB 1/2] duplicate the cache name in saved_alias list
From: Li Zhong @ 2012-06-25 9:53 UTC (permalink / raw)
To: LKML
Cc: Christoph Lameter, Pekka Enberg, linux-mm, Paul Mackerras,
Matt Mackall, PowerPC email list
SLUB duplicates the cache name in kmem_cache_create(). However if the
cache could be merged to others during early booting, the name pointer
is saved in saved_alias list, and the string needs to be kept valid
before slab_sysfs_init() is called.
This patch tries to duplicate the cache name in saved_alias list, so
that the cache name could be safely kfreed after calling
kmem_cache_create(), if that name is kmalloced.
Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
---
mm/slub.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/mm/slub.c b/mm/slub.c
index 8c691fa..3dc8ed5 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5373,6 +5373,11 @@ static int sysfs_slab_alias(struct kmem_cache *s,
const char *name)
al->s = s;
al->name = name;
+ al->name = kstrdup(name, GFP_KERNEL);
+ if (!al->name) {
+ kfree(al);
+ return -ENOMEM;
+ }
al->next = alias_list;
alias_list = al;
return 0;
@@ -5409,6 +5414,7 @@ static int __init slab_sysfs_init(void)
if (err)
printk(KERN_ERR "SLUB: Unable to add boot slab alias"
" %s to sysfs\n", s->name);
+ kfree(al->name);
kfree(al);
}
--
1.7.1
^ permalink raw reply related
* [PATCH powerpc 2/2] kfree the cache name of pgtable cache if SLUB is used
From: Li Zhong @ 2012-06-25 9:54 UTC (permalink / raw)
To: LKML
Cc: Christoph Lameter, Pekka Enberg, linux-mm, Paul Mackerras,
Matt Mackall, PowerPC email list
In-Reply-To: <1340617984.13778.37.camel@ThinkPad-T420>
This patch tries to kfree the cache name of pgtables cache if SLUB is
used, as SLUB duplicates the cache name, and the original one is leaked.
This patch depends on patch 1 -- (duplicate the cache name in
saved_alias list) in this mail thread. As the pgtables cache might be
merged to other caches. In this case, the name could be safely kfreed
after calling kmem_cache_create() with patch 1.
Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
---
arch/powerpc/mm/init_64.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 620b7ac..c9d2a7f 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -130,6 +130,9 @@ void pgtable_cache_add(unsigned shift, void
(*ctor)(void *))
align = max_t(unsigned long, align, minalign);
name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift);
new = kmem_cache_create(name, table_size, align, 0, ctor);
+#ifdef CONFIG_SLUB
+ kfree(name); /* SLUB duplicates the cache name */
+#endif
PGT_CACHE(shift) = new;
pr_debug("Allocated pgtable cache for order %d\n", shift);
--
1.7.1
^ permalink raw reply related
* Re: [PATCH SLUB 1/2] duplicate the cache name in saved_alias list
From: Wanlong Gao @ 2012-06-25 10:54 UTC (permalink / raw)
To: Li Zhong
Cc: Christoph Lameter, LKML, Pekka Enberg, linux-mm, Paul Mackerras,
Matt Mackall, PowerPC email list
In-Reply-To: <1340617984.13778.37.camel@ThinkPad-T420>
On 06/25/2012 05:53 PM, Li Zhong wrote:
> SLUB duplicates the cache name in kmem_cache_create(). However if the
> cache could be merged to others during early booting, the name pointer
> is saved in saved_alias list, and the string needs to be kept valid
> before slab_sysfs_init() is called.
>
> This patch tries to duplicate the cache name in saved_alias list, so
> that the cache name could be safely kfreed after calling
> kmem_cache_create(), if that name is kmalloced.
>
> Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
> ---
> mm/slub.c | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/mm/slub.c b/mm/slub.c
> index 8c691fa..3dc8ed5 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -5373,6 +5373,11 @@ static int sysfs_slab_alias(struct kmem_cache *s,
> const char *name)
>
> al->s = s;
> al->name = name;
> + al->name = kstrdup(name, GFP_KERNEL);
dup assigned the al->name ?
Thanks,
Wanlong Gao
> + if (!al->name) {
> + kfree(al);
> + return -ENOMEM;
> + }
> al->next = alias_list;
> alias_list = al;
> return 0;
> @@ -5409,6 +5414,7 @@ static int __init slab_sysfs_init(void)
> if (err)
> printk(KERN_ERR "SLUB: Unable to add boot slab alias"
> " %s to sysfs\n", s->name);
> + kfree(al->name);
> kfree(al);
> }
>
>
^ permalink raw reply
* Re: [PATCH SLUB 1/2] duplicate the cache name in saved_alias list
From: Glauber Costa @ 2012-06-25 11:10 UTC (permalink / raw)
To: Li Zhong
Cc: Christoph Lameter, LKML, Pekka Enberg, linux-mm, Paul Mackerras,
Matt Mackall, PowerPC email list
In-Reply-To: <1340617984.13778.37.camel@ThinkPad-T420>
On 06/25/2012 01:53 PM, Li Zhong wrote:
> SLUB duplicates the cache name in kmem_cache_create(). However if the
> cache could be merged to others during early booting, the name pointer
> is saved in saved_alias list, and the string needs to be kept valid
> before slab_sysfs_init() is called.
>
> This patch tries to duplicate the cache name in saved_alias list, so
> that the cache name could be safely kfreed after calling
> kmem_cache_create(), if that name is kmalloced.
>
> Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
> ---
> mm/slub.c | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/mm/slub.c b/mm/slub.c
> index 8c691fa..3dc8ed5 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -5373,6 +5373,11 @@ static int sysfs_slab_alias(struct kmem_cache *s,
> const char *name)
>
> al->s = s;
> al->name = name;
> + al->name = kstrdup(name, GFP_KERNEL);
> + if (!al->name) {
> + kfree(al);
> + return -ENOMEM;
> + }
> al->next = alias_list;
> alias_list = al;
> return 0;
> @@ -5409,6 +5414,7 @@ static int __init slab_sysfs_init(void)
> if (err)
> printk(KERN_ERR "SLUB: Unable to add boot slab alias"
> " %s to sysfs\n", s->name);
> + kfree(al->name);
> kfree(al);
> }
>
>
What's unsafe about the current state of affairs ?
Whenever we alias, we'll increase the reference counter.
kmem_cache_destroy will only actually destroy the structure whenever
that refcnt reaches zero.
This means that kfree shouldn't happen until then. So what is exactly
that you are seeing?
Now, if you ask me, keeping the name around in user-visible files like
/proc/slabinfo for caches that are removed already can be a bit
confusing (that is because we don't add aliases to the slab_cache list)
If you want to touch this, one thing you can do is to keep a list of
names bundled in an alias. If an alias is removed, you free that name.
If that name is the representative name of the bundle, you move to the
next one.
^ permalink raw reply
* [RFC PATCH 03/17] KVM: PPC64: booke: Add EPCR support in sregs
From: Mihai Caraman @ 2012-06-25 12:26 UTC (permalink / raw)
To: kvm-ppc, kvm, linuxppc-dev, qemu-ppc; +Cc: Mihai Caraman
In-Reply-To: <1340627195-11544-1-git-send-email-mihai.caraman@freescale.com>
Add KVM_SREGS_E_64 feature and EPCR spr support in get/set sregs
for 64-bit hosts.
Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
arch/powerpc/kvm/booke.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index f9fa260..d15c4b5 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1052,6 +1052,9 @@ static void get_sregs_base(struct kvm_vcpu *vcpu,
u64 tb = get_tb();
sregs->u.e.features |= KVM_SREGS_E_BASE;
+#ifdef CONFIG_64BIT
+ sregs->u.e.features |= KVM_SREGS_E_64;
+#endif
sregs->u.e.csrr0 = vcpu->arch.csrr0;
sregs->u.e.csrr1 = vcpu->arch.csrr1;
@@ -1063,6 +1066,9 @@ static void get_sregs_base(struct kvm_vcpu *vcpu,
sregs->u.e.dec = kvmppc_get_dec(vcpu, tb);
sregs->u.e.tb = tb;
sregs->u.e.vrsave = vcpu->arch.vrsave;
+#ifdef CONFIG_64BIT
+ sregs->u.e.epcr = vcpu->arch.epcr;
+#endif
}
static int set_sregs_base(struct kvm_vcpu *vcpu,
@@ -1071,6 +1077,11 @@ static int set_sregs_base(struct kvm_vcpu *vcpu,
if (!(sregs->u.e.features & KVM_SREGS_E_BASE))
return 0;
+#ifdef CONFIG_64BIT
+ if (!(sregs->u.e.features & KVM_SREGS_E_64))
+ return 0;
+#endif
+
vcpu->arch.csrr0 = sregs->u.e.csrr0;
vcpu->arch.csrr1 = sregs->u.e.csrr1;
vcpu->arch.mcsr = sregs->u.e.mcsr;
@@ -1078,6 +1089,9 @@ static int set_sregs_base(struct kvm_vcpu *vcpu,
set_guest_dear(vcpu, sregs->u.e.dear);
vcpu->arch.vrsave = sregs->u.e.vrsave;
kvmppc_set_tcr(vcpu, sregs->u.e.tcr);
+#ifdef CONFIG_64BIT
+ kvmppc_set_epcr(vcpu, sregs->u.e.epcr);
+#endif
if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DEC) {
vcpu->arch.dec = sregs->u.e.dec;
--
1.7.4.1
^ permalink raw reply related
* [RFC PATCH 04/17] KVM: PPC64: booke: Add guest computation mode for irq delivery
From: Mihai Caraman @ 2012-06-25 12:26 UTC (permalink / raw)
To: kvm-ppc, kvm, linuxppc-dev, qemu-ppc; +Cc: Mihai Caraman
In-Reply-To: <1340627195-11544-1-git-send-email-mihai.caraman@freescale.com>
When delivering guest IRQs, update MSR computaion mode according to guest
interrupt computation mode found in EPCR.
Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
arch/powerpc/kvm/booke.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index d15c4b5..93b48e0 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -287,6 +287,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
bool crit;
bool keep_irq = false;
enum int_class int_class;
+ ulong msr_cm = 0;
/* Truncate crit indicators in 32 bit mode */
if (!(vcpu->arch.shared->msr & MSR_SF)) {
@@ -299,6 +300,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
/* ... and we're in supervisor mode */
crit = crit && !(vcpu->arch.shared->msr & MSR_PR);
+#ifdef CONFIG_64BIT
+ msr_cm = vcpu->arch.epcr & SPRN_EPCR_ICM ? MSR_CM : 0;
+#endif
+
if (priority == BOOKE_IRQPRIO_EXTERNAL_LEVEL) {
priority = BOOKE_IRQPRIO_EXTERNAL;
keep_irq = true;
@@ -381,7 +386,8 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
set_guest_esr(vcpu, vcpu->arch.queued_esr);
if (update_dear == true)
set_guest_dear(vcpu, vcpu->arch.queued_dear);
- kvmppc_set_msr(vcpu, vcpu->arch.shared->msr & msr_mask);
+ kvmppc_set_msr(vcpu, (vcpu->arch.shared->msr & msr_mask)
+ | msr_cm);
if (!keep_irq)
clear_bit(priority, &vcpu->arch.pending_exceptions);
--
1.7.4.1
^ permalink raw reply related
* [RFC PATCH 05/17] KVM: PPC: booke: Extend MAS2 EPN mask for 64-bit
From: Mihai Caraman @ 2012-06-25 12:26 UTC (permalink / raw)
To: kvm-ppc, kvm, linuxppc-dev, qemu-ppc; +Cc: Mihai Caraman
In-Reply-To: <1340627195-11544-1-git-send-email-mihai.caraman@freescale.com>
Extend MAS2 EPN mask for 64-bit hosts, to retain most significant bits.
Change get tlb eaddr to use this mask.
Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
arch/powerpc/include/asm/mmu-book3e.h | 2 +-
arch/powerpc/kvm/e500.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h
index eeabcdb..99d43e0 100644
--- a/arch/powerpc/include/asm/mmu-book3e.h
+++ b/arch/powerpc/include/asm/mmu-book3e.h
@@ -59,7 +59,7 @@
#define MAS1_TSIZE_SHIFT 7
#define MAS1_TSIZE(x) (((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK)
-#define MAS2_EPN 0xFFFFF000
+#define MAS2_EPN (~0xFFFUL)
#define MAS2_X0 0x00000040
#define MAS2_X1 0x00000020
#define MAS2_W 0x00000010
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index aa8b814..3e31098 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -155,7 +155,7 @@ get_tlb_size(const struct kvm_book3e_206_tlb_entry *tlbe)
static inline gva_t get_tlb_eaddr(const struct kvm_book3e_206_tlb_entry *tlbe)
{
- return tlbe->mas2 & 0xfffff000;
+ return tlbe->mas2 & MAS2_EPN;
}
static inline u64 get_tlb_bytes(const struct kvm_book3e_206_tlb_entry *tlbe)
--
1.7.4.1
^ 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