aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2006-06-10 06:58:08 -0400
committerPaul Mackerras <paulus@samba.org>2006-06-15 05:31:26 -0400
commitca1588e71b70534e18368a46a3aad9b25dff941d (patch)
tree5bee264d69ba4cbd8b5f5ffaf7f981cab161a52b
parent357518fa34d9dceda42bfc09642356a58370050d (diff)
[POWERPC] node local IOMMU tables
Allocate IOMMU tables local to the relevant node. Signed-off-by: Anton Blanchard <anton@samba.org> Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/iommu.c9
-rw-r--r--arch/powerpc/kernel/vio.c6
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c2
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c23
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c2
-rw-r--r--include/asm-powerpc/iommu.h3
6 files changed, 25 insertions, 20 deletions
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index cef8cba8329b..7cb77c20fc5d 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -418,10 +418,11 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
418 * Build a iommu_table structure. This contains a bit map which 418 * Build a iommu_table structure. This contains a bit map which
419 * is used to manage allocation of the tce space. 419 * is used to manage allocation of the tce space.
420 */ 420 */
421struct iommu_table *iommu_init_table(struct iommu_table *tbl) 421struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
422{ 422{
423 unsigned long sz; 423 unsigned long sz;
424 static int welcomed = 0; 424 static int welcomed = 0;
425 struct page *page;
425 426
426 /* Set aside 1/4 of the table for large allocations. */ 427 /* Set aside 1/4 of the table for large allocations. */
427 tbl->it_halfpoint = tbl->it_size * 3 / 4; 428 tbl->it_halfpoint = tbl->it_size * 3 / 4;
@@ -429,10 +430,10 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)
429 /* number of bytes needed for the bitmap */ 430 /* number of bytes needed for the bitmap */
430 sz = (tbl->it_size + 7) >> 3; 431 sz = (tbl->it_size + 7) >> 3;
431 432
432 tbl->it_map = (unsigned long *)__get_free_pages(GFP_ATOMIC, get_order(sz)); 433 page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
433 if (!tbl->it_map) 434 if (!page)
434 panic("iommu_init_table: Can't allocate %ld bytes\n", sz); 435 panic("iommu_init_table: Can't allocate %ld bytes\n", sz);
435 436 tbl->it_map = page_address(page);
436 memset(tbl->it_map, 0, sz); 437 memset(tbl->it_map, 0, sz);
437 438
438 tbl->it_hint = 0; 439 tbl->it_hint = 0;
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index e746686d48b8..cdf5867838a6 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -60,9 +60,9 @@ static void __init iommu_vio_init(void)
60 vio_iommu_table = veth_iommu_table; 60 vio_iommu_table = veth_iommu_table;
61 vio_iommu_table.it_offset += veth_iommu_table.it_size; 61 vio_iommu_table.it_offset += veth_iommu_table.it_size;
62 62
63 if (!iommu_init_table(&veth_iommu_table)) 63 if (!iommu_init_table(&veth_iommu_table, -1))
64 printk("Virtual Bus VETH TCE table failed.\n"); 64 printk("Virtual Bus VETH TCE table failed.\n");
65 if (!iommu_init_table(&vio_iommu_table)) 65 if (!iommu_init_table(&vio_iommu_table, -1))
66 printk("Virtual Bus VIO TCE table failed.\n"); 66 printk("Virtual Bus VIO TCE table failed.\n");
67} 67}
68#endif 68#endif
@@ -98,7 +98,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
98 tbl->it_busno = 0; 98 tbl->it_busno = 0;
99 tbl->it_type = TCE_VB; 99 tbl->it_type = TCE_VB;
100 100
101 return iommu_init_table(tbl); 101 return iommu_init_table(tbl, -1);
102 } 102 }
103} 103}
104 104
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index a992f6af249f..e3bd2015f2c9 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -173,7 +173,7 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
173 /* Look for existing tce table */ 173 /* Look for existing tce table */
174 pdn->iommu_table = iommu_table_find(tbl); 174 pdn->iommu_table = iommu_table_find(tbl);
175 if (pdn->iommu_table == NULL) 175 if (pdn->iommu_table == NULL)
176 pdn->iommu_table = iommu_init_table(tbl); 176 pdn->iommu_table = iommu_init_table(tbl, -1);
177 else 177 else
178 kfree(tbl); 178 kfree(tbl);
179} 179}
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 44a507e6fb34..2f66dc6503ff 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -368,10 +368,11 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
368 pci->phb->dma_window_size = 0x8000000ul; 368 pci->phb->dma_window_size = 0x8000000ul;
369 pci->phb->dma_window_base_cur = 0x8000000ul; 369 pci->phb->dma_window_base_cur = 0x8000000ul;
370 370
371 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 371 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
372 pci->phb->node);
372 373
373 iommu_table_setparms(pci->phb, dn, tbl); 374 iommu_table_setparms(pci->phb, dn, tbl);
374 pci->iommu_table = iommu_init_table(tbl); 375 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
375 376
376 /* Divide the rest (1.75GB) among the children */ 377 /* Divide the rest (1.75GB) among the children */
377 pci->phb->dma_window_size = 0x80000000ul; 378 pci->phb->dma_window_size = 0x80000000ul;
@@ -414,12 +415,12 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
414 415
415 ppci->bussubno = bus->number; 416 ppci->bussubno = bus->number;
416 417
417 tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), 418 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
418 GFP_KERNEL); 419 ppci->phb->node);
419 420
420 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); 421 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
421 422
422 ppci->iommu_table = iommu_init_table(tbl); 423 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
423 } 424 }
424 425
425 if (pdn != dn) 426 if (pdn != dn)
@@ -442,9 +443,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
442 */ 443 */
443 if (!dev->bus->self) { 444 if (!dev->bus->self) {
444 DBG(" --> first child, no bridge. Allocating iommu table.\n"); 445 DBG(" --> first child, no bridge. Allocating iommu table.\n");
445 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 446 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
447 PCI_DN(dn)->phb->node);
446 iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); 448 iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
447 PCI_DN(mydn)->iommu_table = iommu_init_table(tbl); 449 PCI_DN(dn)->iommu_table = iommu_init_table(tbl,
450 PCI_DN(dn)->phb->node);
448 451
449 return; 452 return;
450 } 453 }
@@ -526,12 +529,12 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
526 /* iommu_table_setparms_lpar needs bussubno. */ 529 /* iommu_table_setparms_lpar needs bussubno. */
527 pci->bussubno = pci->phb->bus->number; 530 pci->bussubno = pci->phb->bus->number;
528 531
529 tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), 532 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
530 GFP_KERNEL); 533 pci->phb->node);
531 534
532 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); 535 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
533 536
534 pci->iommu_table = iommu_init_table(tbl); 537 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
535 } 538 }
536 539
537 if (pdn != dn) 540 if (pdn != dn)
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 38087bd6e3cf..6232091cc72b 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -246,7 +246,7 @@ static void iommu_table_dart_setup(void)
246 iommu_table_dart.it_base = (unsigned long)dart_vbase; 246 iommu_table_dart.it_base = (unsigned long)dart_vbase;
247 iommu_table_dart.it_index = 0; 247 iommu_table_dart.it_index = 0;
248 iommu_table_dart.it_blocksize = 1; 248 iommu_table_dart.it_blocksize = 1;
249 iommu_init_table(&iommu_table_dart); 249 iommu_init_table(&iommu_table_dart, -1);
250 250
251 /* Reserve the last page of the DART to avoid possible prefetch 251 /* Reserve the last page of the DART to avoid possible prefetch
252 * past the DART mapped area 252 * past the DART mapped area
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 9065f6c972a4..32dac0ac683a 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -67,7 +67,8 @@ extern void iommu_free_table(struct device_node *dn);
67/* Initializes an iommu_table based in values set in the passed-in 67/* Initializes an iommu_table based in values set in the passed-in
68 * structure 68 * structure
69 */ 69 */
70extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); 70extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
71 int nid);
71 72
72extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, 73extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
73 struct scatterlist *sglist, int nelems, unsigned long mask, 74 struct scatterlist *sglist, int nelems, unsigned long mask,