Commit 3ba3a73e authored by Alexey Kardashevskiy's avatar Alexey Kardashevskiy Committed by Michael Ellerman

powerpc/powernv/ioda2: Fix calculation for memory allocated for TCE table

The existing code stores the amount of memory allocated for a TCE table.
At the moment it uses @offset which is a virtual offset in the TCE table
which is only correct for a one level tables and it does not include
memory allocated for intermediate levels. When multilevel TCE table is
requested, WARN_ON in tce_iommu_create_table() prints a warning.

This adds an additional counter to pnv_pci_ioda2_table_do_alloc_pages()
to count actually allocated memory.
Signed-off-by: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent c5dfd654
...@@ -2220,7 +2220,7 @@ static void pnv_pci_ioda_setup_opal_tce_kill(struct pnv_phb *phb) ...@@ -2220,7 +2220,7 @@ static void pnv_pci_ioda_setup_opal_tce_kill(struct pnv_phb *phb)
static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift, static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,
unsigned levels, unsigned long limit, unsigned levels, unsigned long limit,
unsigned long *current_offset) unsigned long *current_offset, unsigned long *total_allocated)
{ {
struct page *tce_mem = NULL; struct page *tce_mem = NULL;
__be64 *addr, *tmp; __be64 *addr, *tmp;
...@@ -2236,6 +2236,7 @@ static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift, ...@@ -2236,6 +2236,7 @@ static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,
} }
addr = page_address(tce_mem); addr = page_address(tce_mem);
memset(addr, 0, allocated); memset(addr, 0, allocated);
*total_allocated += allocated;
--levels; --levels;
if (!levels) { if (!levels) {
...@@ -2245,7 +2246,7 @@ static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift, ...@@ -2245,7 +2246,7 @@ static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,
for (i = 0; i < entries; ++i) { for (i = 0; i < entries; ++i) {
tmp = pnv_pci_ioda2_table_do_alloc_pages(nid, shift, tmp = pnv_pci_ioda2_table_do_alloc_pages(nid, shift,
levels, limit, current_offset); levels, limit, current_offset, total_allocated);
if (!tmp) if (!tmp)
break; break;
...@@ -2267,7 +2268,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset, ...@@ -2267,7 +2268,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
struct iommu_table *tbl) struct iommu_table *tbl)
{ {
void *addr; void *addr;
unsigned long offset = 0, level_shift; unsigned long offset = 0, level_shift, total_allocated = 0;
const unsigned window_shift = ilog2(window_size); const unsigned window_shift = ilog2(window_size);
unsigned entries_shift = window_shift - page_shift; unsigned entries_shift = window_shift - page_shift;
unsigned table_shift = max_t(unsigned, entries_shift + 3, PAGE_SHIFT); unsigned table_shift = max_t(unsigned, entries_shift + 3, PAGE_SHIFT);
...@@ -2286,7 +2287,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset, ...@@ -2286,7 +2287,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
/* Allocate TCE table */ /* Allocate TCE table */
addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift, addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift,
levels, tce_table_size, &offset); levels, tce_table_size, &offset, &total_allocated);
/* addr==NULL means that the first level allocation failed */ /* addr==NULL means that the first level allocation failed */
if (!addr) if (!addr)
...@@ -2308,7 +2309,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset, ...@@ -2308,7 +2309,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
page_shift); page_shift);
tbl->it_level_size = 1ULL << (level_shift - 3); tbl->it_level_size = 1ULL << (level_shift - 3);
tbl->it_indirect_levels = levels - 1; tbl->it_indirect_levels = levels - 1;
tbl->it_allocated_size = offset; tbl->it_allocated_size = total_allocated;
pr_devel("Created TCE table: ws=%08llx ts=%lx @%08llx\n", pr_devel("Created TCE table: ws=%08llx ts=%lx @%08llx\n",
window_size, tce_table_size, bus_offset); window_size, tce_table_size, bus_offset);
......
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