diff options
author | Anton Blanchard <anton@samba.org> | 2006-06-10 06:58:08 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-06-15 05:31:26 -0400 |
commit | ca1588e71b70534e18368a46a3aad9b25dff941d (patch) | |
tree | 5bee264d69ba4cbd8b5f5ffaf7f981cab161a52b | |
parent | 357518fa34d9dceda42bfc09642356a58370050d (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.c | 9 | ||||
-rw-r--r-- | arch/powerpc/kernel/vio.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 23 | ||||
-rw-r--r-- | arch/powerpc/sysdev/dart_iommu.c | 2 | ||||
-rw-r--r-- | include/asm-powerpc/iommu.h | 3 |
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 | */ |
421 | struct iommu_table *iommu_init_table(struct iommu_table *tbl) | 421 | struct 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 | */ |
70 | extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); | 70 | extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, |
71 | int nid); | ||
71 | 72 | ||
72 | extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | 73 | extern 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, |