Commit 32924c76 authored by Russell King's avatar Russell King Committed by Thierry Reding

iommu/tegra-smmu: Use kcalloc() to allocate counter array

Use kcalloc() to allocate the use-counter array for the page directory
entries/page tables.  Using kcalloc() allows us to be provided with
zero-initialised memory from the allocators, rather than initialising
it ourselves.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 853520fa
...@@ -40,7 +40,7 @@ struct tegra_smmu_as { ...@@ -40,7 +40,7 @@ struct tegra_smmu_as {
struct iommu_domain domain; struct iommu_domain domain;
struct tegra_smmu *smmu; struct tegra_smmu *smmu;
unsigned int use_count; unsigned int use_count;
struct page *count; u32 *count;
struct page **pts; struct page **pts;
struct page *pd; struct page *pd;
unsigned id; unsigned id;
...@@ -265,7 +265,7 @@ static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type) ...@@ -265,7 +265,7 @@ static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
return NULL; return NULL;
} }
as->count = alloc_page(GFP_KERNEL); as->count = kcalloc(SMMU_NUM_PDE, sizeof(u32), GFP_KERNEL);
if (!as->count) { if (!as->count) {
__free_page(as->pd); __free_page(as->pd);
kfree(as); kfree(as);
...@@ -274,7 +274,7 @@ static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type) ...@@ -274,7 +274,7 @@ static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
as->pts = kcalloc(SMMU_NUM_PDE, sizeof(*as->pts), GFP_KERNEL); as->pts = kcalloc(SMMU_NUM_PDE, sizeof(*as->pts), GFP_KERNEL);
if (!as->pts) { if (!as->pts) {
__free_page(as->count); kfree(as->count);
__free_page(as->pd); __free_page(as->pd);
kfree(as); kfree(as);
return NULL; return NULL;
...@@ -284,13 +284,6 @@ static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type) ...@@ -284,13 +284,6 @@ static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
pd = page_address(as->pd); pd = page_address(as->pd);
SetPageReserved(as->pd); SetPageReserved(as->pd);
for (i = 0; i < SMMU_NUM_PDE; i++)
pd[i] = 0;
/* clear PDE usage counters */
pd = page_address(as->count);
SetPageReserved(as->count);
for (i = 0; i < SMMU_NUM_PDE; i++) for (i = 0; i < SMMU_NUM_PDE; i++)
pd[i] = 0; pd[i] = 0;
...@@ -509,7 +502,7 @@ static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova, ...@@ -509,7 +502,7 @@ static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova,
static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova,
struct page **pagep) struct page **pagep)
{ {
u32 *pd = page_address(as->pd), *pt, *count; u32 *pd = page_address(as->pd), *pt;
unsigned int pde = iova_pd_index(iova); unsigned int pde = iova_pd_index(iova);
struct tegra_smmu *smmu = as->smmu; struct tegra_smmu *smmu = as->smmu;
struct page *page; struct page *page;
...@@ -545,9 +538,8 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, ...@@ -545,9 +538,8 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova,
pt = page_address(page); pt = page_address(page);
/* Keep track of entries in this page table. */ /* Keep track of entries in this page table. */
count = page_address(as->count);
if (pt[iova_pt_index(iova)] == 0) if (pt[iova_pt_index(iova)] == 0)
count[pde]++; as->count[pde]++;
return tegra_smmu_pte_offset(page, iova); return tegra_smmu_pte_offset(page, iova);
} }
...@@ -556,7 +548,6 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova) ...@@ -556,7 +548,6 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova)
{ {
struct tegra_smmu *smmu = as->smmu; struct tegra_smmu *smmu = as->smmu;
unsigned int pde = iova_pd_index(iova); unsigned int pde = iova_pd_index(iova);
u32 *count = page_address(as->count);
u32 *pd = page_address(as->pd); u32 *pd = page_address(as->pd);
struct page *page = as->pts[pde]; struct page *page = as->pts[pde];
...@@ -564,7 +555,7 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova) ...@@ -564,7 +555,7 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova)
* When no entries in this page table are used anymore, return the * When no entries in this page table are used anymore, return the
* memory page to the system. * memory page to the system.
*/ */
if (--count[pde] == 0) { if (--as->count[pde] == 0) {
unsigned int offset = pde * sizeof(*pd); unsigned int offset = pde * sizeof(*pd);
/* Clear the page directory entry first */ /* Clear the page directory entry first */
......
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