summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kokshaysky <ink@jurassic.park.msu.ru>2003-01-14 19:24:54 -0800
committerRichard Henderson <rth@are.twiddle.net>2003-01-14 19:24:54 -0800
commitecb581fd5b50d40b14938f618b7d1f9a0908694e (patch)
tree9ec4753d8a131cb9965c6932c394693a4d696d49
parentada49be09ff46903a04afe22edf3f5947865c071 (diff)
[PATCH] alpha numa iommu
From Jeff.Wiedemeier@hp.com: On NUMA alpha systems, attempt to allocate scatter-gather tables local to IO processor. If that doesn't work, then allocate anywhere in the system.
-rw-r--r--arch/alpha/kernel/pci_impl.h4
-rw-r--r--arch/alpha/kernel/pci_iommu.c38
2 files changed, 40 insertions, 2 deletions
diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
index 7139e6c2da71..a7c201aa89bd 100644
--- a/arch/alpha/kernel/pci_impl.h
+++ b/arch/alpha/kernel/pci_impl.h
@@ -155,6 +155,10 @@ extern u8 common_swizzle(struct pci_dev *, u8 *);
extern struct pci_controller *alloc_pci_controller(void);
extern struct resource *alloc_resource(void);
+extern struct pci_iommu_arena *iommu_arena_new_node(int,
+ struct pci_controller *,
+ dma_addr_t, unsigned long,
+ unsigned long);
extern struct pci_iommu_arena *iommu_arena_new(struct pci_controller *,
dma_addr_t, unsigned long,
unsigned long);
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 4276b64a9bcb..436502888e12 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -58,8 +58,8 @@ size_for_memory(unsigned long max)
}
struct pci_iommu_arena *
-iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
- unsigned long window_size, unsigned long align)
+iommu_arena_new_node(int nid, struct pci_controller *hose, dma_addr_t base,
+ unsigned long window_size, unsigned long align)
{
unsigned long mem_size;
struct pci_iommu_arena *arena;
@@ -73,9 +73,36 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
if (align < mem_size)
align = mem_size;
+
+#ifdef CONFIG_DISCONTIGMEM
+
+ if (!NODE_DATA(nid) ||
+ (NULL == (arena = alloc_bootmem_node(NODE_DATA(nid),
+ sizeof(*arena))))) {
+ printk("%s: couldn't allocate arena from node %d\n"
+ " falling back to system-wide allocation\n",
+ __FUNCTION__, nid);
+ arena = alloc_bootmem(sizeof(*arena));
+ }
+
+ if (!NODE_DATA(nid) ||
+ (NULL == (arena->ptes = __alloc_bootmem_node(NODE_DATA(nid),
+ mem_size,
+ align,
+ 0)))) {
+ printk("%s: couldn't allocate arena ptes from node %d\n"
+ " falling back to system-wide allocation\n",
+ __FUNCTION__, nid);
+ arena->ptes = __alloc_bootmem(mem_size, align, 0);
+ }
+
+#else /* CONFIG_DISCONTIGMEM */
+
arena = alloc_bootmem(sizeof(*arena));
arena->ptes = __alloc_bootmem(mem_size, align, 0);
+#endif /* CONFIG_DISCONTIGMEM */
+
spin_lock_init(&arena->lock);
arena->hose = hose;
arena->dma_base = base;
@@ -89,6 +116,13 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
return arena;
}
+struct pci_iommu_arena *
+iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
+ unsigned long window_size, unsigned long align)
+{
+ return iommu_arena_new_node(0, hose, base, window_size, align);
+}
+
/* Must be called with the arena lock held */
static long
iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask)