Commit ca1588e7 authored by Anton Blanchard's avatar Anton Blanchard Committed by Paul Mackerras

[POWERPC] node local IOMMU tables

Allocate IOMMU tables local to the relevant node.
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Acked-by: default avatarOlof Johansson <olof@lixom.net>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 357518fa
...@@ -418,10 +418,11 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, ...@@ -418,10 +418,11 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
* Build a iommu_table structure. This contains a bit map which * Build a iommu_table structure. This contains a bit map which
* is used to manage allocation of the tce space. * is used to manage allocation of the tce space.
*/ */
struct iommu_table *iommu_init_table(struct iommu_table *tbl) struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
{ {
unsigned long sz; unsigned long sz;
static int welcomed = 0; static int welcomed = 0;
struct page *page;
/* Set aside 1/4 of the table for large allocations. */ /* Set aside 1/4 of the table for large allocations. */
tbl->it_halfpoint = tbl->it_size * 3 / 4; tbl->it_halfpoint = tbl->it_size * 3 / 4;
...@@ -429,10 +430,10 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl) ...@@ -429,10 +430,10 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)
/* number of bytes needed for the bitmap */ /* number of bytes needed for the bitmap */
sz = (tbl->it_size + 7) >> 3; sz = (tbl->it_size + 7) >> 3;
tbl->it_map = (unsigned long *)__get_free_pages(GFP_ATOMIC, get_order(sz)); page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
if (!tbl->it_map) if (!page)
panic("iommu_init_table: Can't allocate %ld bytes\n", sz); panic("iommu_init_table: Can't allocate %ld bytes\n", sz);
tbl->it_map = page_address(page);
memset(tbl->it_map, 0, sz); memset(tbl->it_map, 0, sz);
tbl->it_hint = 0; tbl->it_hint = 0;
......
...@@ -60,9 +60,9 @@ static void __init iommu_vio_init(void) ...@@ -60,9 +60,9 @@ static void __init iommu_vio_init(void)
vio_iommu_table = veth_iommu_table; vio_iommu_table = veth_iommu_table;
vio_iommu_table.it_offset += veth_iommu_table.it_size; vio_iommu_table.it_offset += veth_iommu_table.it_size;
if (!iommu_init_table(&veth_iommu_table)) if (!iommu_init_table(&veth_iommu_table, -1))
printk("Virtual Bus VETH TCE table failed.\n"); printk("Virtual Bus VETH TCE table failed.\n");
if (!iommu_init_table(&vio_iommu_table)) if (!iommu_init_table(&vio_iommu_table, -1))
printk("Virtual Bus VIO TCE table failed.\n"); printk("Virtual Bus VIO TCE table failed.\n");
} }
#endif #endif
...@@ -98,7 +98,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) ...@@ -98,7 +98,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
tbl->it_busno = 0; tbl->it_busno = 0;
tbl->it_type = TCE_VB; tbl->it_type = TCE_VB;
return iommu_init_table(tbl); return iommu_init_table(tbl, -1);
} }
} }
......
...@@ -173,7 +173,7 @@ void iommu_devnode_init_iSeries(struct device_node *dn) ...@@ -173,7 +173,7 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
/* Look for existing tce table */ /* Look for existing tce table */
pdn->iommu_table = iommu_table_find(tbl); pdn->iommu_table = iommu_table_find(tbl);
if (pdn->iommu_table == NULL) if (pdn->iommu_table == NULL)
pdn->iommu_table = iommu_init_table(tbl); pdn->iommu_table = iommu_init_table(tbl, -1);
else else
kfree(tbl); kfree(tbl);
} }
......
...@@ -368,10 +368,11 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) ...@@ -368,10 +368,11 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
pci->phb->dma_window_size = 0x8000000ul; pci->phb->dma_window_size = 0x8000000ul;
pci->phb->dma_window_base_cur = 0x8000000ul; pci->phb->dma_window_base_cur = 0x8000000ul;
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
pci->phb->node);
iommu_table_setparms(pci->phb, dn, tbl); iommu_table_setparms(pci->phb, dn, tbl);
pci->iommu_table = iommu_init_table(tbl); pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
/* Divide the rest (1.75GB) among the children */ /* Divide the rest (1.75GB) among the children */
pci->phb->dma_window_size = 0x80000000ul; pci->phb->dma_window_size = 0x80000000ul;
...@@ -414,12 +415,12 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) ...@@ -414,12 +415,12 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
ppci->bussubno = bus->number; ppci->bussubno = bus->number;
tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
GFP_KERNEL); ppci->phb->node);
iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
ppci->iommu_table = iommu_init_table(tbl); ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
} }
if (pdn != dn) if (pdn != dn)
...@@ -442,9 +443,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) ...@@ -442,9 +443,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
*/ */
if (!dev->bus->self) { if (!dev->bus->self) {
DBG(" --> first child, no bridge. Allocating iommu table.\n"); DBG(" --> first child, no bridge. Allocating iommu table.\n");
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
PCI_DN(dn)->phb->node);
iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
PCI_DN(mydn)->iommu_table = iommu_init_table(tbl); PCI_DN(dn)->iommu_table = iommu_init_table(tbl,
PCI_DN(dn)->phb->node);
return; return;
} }
...@@ -526,12 +529,12 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) ...@@ -526,12 +529,12 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
/* iommu_table_setparms_lpar needs bussubno. */ /* iommu_table_setparms_lpar needs bussubno. */
pci->bussubno = pci->phb->bus->number; pci->bussubno = pci->phb->bus->number;
tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
GFP_KERNEL); pci->phb->node);
iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
pci->iommu_table = iommu_init_table(tbl); pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
} }
if (pdn != dn) if (pdn != dn)
......
...@@ -246,7 +246,7 @@ static void iommu_table_dart_setup(void) ...@@ -246,7 +246,7 @@ static void iommu_table_dart_setup(void)
iommu_table_dart.it_base = (unsigned long)dart_vbase; iommu_table_dart.it_base = (unsigned long)dart_vbase;
iommu_table_dart.it_index = 0; iommu_table_dart.it_index = 0;
iommu_table_dart.it_blocksize = 1; iommu_table_dart.it_blocksize = 1;
iommu_init_table(&iommu_table_dart); iommu_init_table(&iommu_table_dart, -1);
/* Reserve the last page of the DART to avoid possible prefetch /* Reserve the last page of the DART to avoid possible prefetch
* past the DART mapped area * past the DART mapped area
......
...@@ -67,7 +67,8 @@ extern void iommu_free_table(struct device_node *dn); ...@@ -67,7 +67,8 @@ extern void iommu_free_table(struct device_node *dn);
/* Initializes an iommu_table based in values set in the passed-in /* Initializes an iommu_table based in values set in the passed-in
* structure * structure
*/ */
extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
int nid);
extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
struct scatterlist *sglist, int nelems, unsigned long mask, struct scatterlist *sglist, int nelems, unsigned long mask,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment