[<prev] [next>] [day] [month] [year] [list]
Message-id: <003301cdd78f$e71a7b60$b54f7220$%cho@samsung.com>
Date: Tue, 11 Dec 2012 20:08:51 +0900
From: Cho KyongHo <pullip.cho@...sung.com>
To: 'Linux ARM Kernel' <linux-arm-kernel@...ts.infradead.org>,
'Linux IOMMU' <iommu@...ts.linux-foundation.org>,
'Linux Kernel' <linux-kernel@...r.kernel.org>,
'Linux Samsung SOC' <linux-samsung-soc@...r.kernel.org>
Cc: 'Dae Inki' <inki.dae@...sung.com>,
'Joerg Roedel' <joro@...tes.org>,
'Kukjin Kim' <kgene.kim@...sung.com>,
'Prathyush' <prathyush.k@...sung.com>,
'Rahun Sharma' <rahul.sharma@...sung.com>,
'Sanghyun Lee' <sanghyun75.lee@...sung.com>,
'Subash Patel' <subash.ramaswamy@...aro.org>,
'SWKim' <sw0312.kim@...sung.com>
Subject: [PATCH v5 03/14] iommu/exynos: allocate lv2 page table from own slab
Since kmalloc() does not guarantee the alignment of 1KB when it
allocates 1KB, it is required to allocate lv2 page table from
own slab that guarantees alignment of 1KB.
Signed-off-by: KyongHo Cho <pullip.cho@...sung.com>
---
drivers/iommu/exynos-iommu.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index ef7dbd1..58d2a24 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -101,6 +101,8 @@
#define REG_PB1_SADDR 0x054
#define REG_PB1_EADDR 0x058
+static struct kmem_cache *lv2table_kmem_cache;
+
static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova)
{
return pgtable + lv1ent_offset(iova);
@@ -739,7 +741,8 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
for (i = 0; i < NUM_LV1ENTRIES; i++)
if (lv1ent_page(priv->pgtable + i))
- kfree(__va(lv2table_base(priv->pgtable + i)));
+ kmem_cache_free(lv2table_kmem_cache,
+ __va(lv2table_base(priv->pgtable + i)));
free_pages((unsigned long)priv->pgtable, 2);
free_pages((unsigned long)priv->lv2entcnt, 1);
@@ -833,7 +836,7 @@ static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova,
if (lv1ent_fault(sent)) {
unsigned long *pent;
- pent = kzalloc(LV2TABLE_SIZE, GFP_ATOMIC);
+ pent = kmem_cache_zalloc(lv2table_kmem_cache, GFP_ATOMIC);
BUG_ON((unsigned long)pent & (LV2TABLE_SIZE - 1));
if (!pent)
return NULL;
@@ -856,7 +859,7 @@ static int lv1set_section(unsigned long *sent, phys_addr_t paddr, short *pgcnt)
if (*pgcnt != NUM_LV2ENTRIES)
return -EADDRINUSE;
- kfree(page_entry(sent, 0));
+ kmem_cache_free(lv2table_kmem_cache, page_entry(sent, 0));
*pgcnt = 0;
}
@@ -1044,10 +1047,23 @@ static int __init exynos_iommu_init(void)
{
int ret;
+ lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
+ LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
+ if (!lv2table_kmem_cache) {
+ pr_err("%s: failed to create kmem cache\n", __func__);
+ return -ENOMEM;
+ }
+
ret = platform_driver_register(&exynos_sysmmu_driver);
if (ret == 0)
- bus_set_iommu(&platform_bus_type, &exynos_iommu_ops);
+ ret = bus_set_iommu(&platform_bus_type, &exynos_iommu_ops);
+
+ if (ret) {
+ pr_err("%s: Failed to register exynos-iommu driver.\n",
+ __func__);
+ kmem_cache_destroy(lv2table_kmem_cache);
+ }
return ret;
}
--
1.8.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists