From f759692d36dbc86dace4f39f02ce433566c09eca Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 23 Jun 2020 23:31:55 -0700 Subject: [PATCH 1/2] iommu: Refactor IOMMU pagetable page accounting into a config option Refactor IOMMU pagetable page accounting code into a config option so that it only includes additional headers in configurations where the page accounting feature is needed. Doing so prevents the definition of certain structures from being expanded, which can affect the CRC value generated for exported symbols in module.symvers. Change-Id: Idd6fc0e1cbb46ace211971ac142be491d0a5ab09 Signed-off-by: Isaac J. Manjarres --- drivers/iommu/Kconfig | 9 ++++++ drivers/iommu/io-pgtable.c | 66 ++++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 0e6a77626aec..83c0b56b57f8 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -172,6 +172,15 @@ config IOMMU_DEBUGFS debug/iommu directory, and then populate a subdirectory with entries as required. +config IO_PGTABLE_PAGE_ACCOUNTING + bool "Export the number of pages allocated for IOMMU pagetables" + depends on IOMMU_DEBUGFS && QGKI + help + Allows exposure of the number of pages allocated for IOMMU + pagetables through DebugFS. This is particularly useful for + generating stats about the amount of memory consumed by IOMMU + page tables in the system. If unsure, say N here. + config IOMMU_DEFAULT_PASSTHROUGH bool "IOMMU passthrough by default" depends on IOMMU_API diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c index 7412921de1c0..f3b31328e166 100644 --- a/drivers/iommu/io-pgtable.c +++ b/drivers/iommu/io-pgtable.c @@ -11,10 +11,12 @@ #include #include #include +#ifdef CONFIG_IO_PGTABLE_PAGE_ACCOUNTING #include #include #include #include +#endif static const struct io_pgtable_init_fns * io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = { @@ -33,8 +35,6 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = { #endif }; -static struct dentry *io_pgtable_top; - struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt, struct io_pgtable_cfg *cfg, void *cookie) @@ -78,8 +78,42 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops) } EXPORT_SYMBOL_GPL(free_io_pgtable_ops); +#ifdef CONFIG_IO_PGTABLE_PAGE_ACCOUNTING +static struct dentry *io_pgtable_top; static atomic_t pages_allocated; +static int io_pgtable_init(void) +{ + io_pgtable_top = debugfs_create_dir("io-pgtable", iommu_debugfs_top); + if (!io_pgtable_top) + return -ENODEV; + + if (!debugfs_create_atomic_t("pages", 0600, io_pgtable_top, + &pages_allocated)) { + debugfs_remove_recursive(io_pgtable_top); + return -ENODEV; + } + + return 0; +} +module_init(io_pgtable_init); + +static void io_pgtable_exit(void) +{ + debugfs_remove_recursive(io_pgtable_top); +} +module_exit(io_pgtable_exit); + +static void mod_pages_allocated(int nr_pages) +{ + atomic_add(nr_pages, &pages_allocated); +} +#else +static void mod_pages_allocated(int nr_pages) +{ +} +#endif + void *io_pgtable_alloc_pages_exact(struct io_pgtable_cfg *cfg, void *cookie, size_t size, gfp_t gfp_mask) { @@ -92,7 +126,7 @@ void *io_pgtable_alloc_pages_exact(struct io_pgtable_cfg *cfg, void *cookie, ret = alloc_pages_exact(size, gfp_mask); if (likely(ret)) - atomic_add(1 << get_order(size), &pages_allocated); + mod_pages_allocated(1 << get_order(size)); return ret; } @@ -107,29 +141,5 @@ void io_pgtable_free_pages_exact(struct io_pgtable_cfg *cfg, void *cookie, else free_pages_exact(virt, size); - atomic_sub(1 << get_order(size), &pages_allocated); + mod_pages_allocated(-(1 << get_order(size))); } - -static int io_pgtable_init(void) -{ - io_pgtable_top = debugfs_create_dir("io-pgtable", iommu_debugfs_top); - - if (!io_pgtable_top) - return -ENODEV; - - if (!debugfs_create_atomic_t("pages", 0600, - io_pgtable_top, &pages_allocated)) { - debugfs_remove_recursive(io_pgtable_top); - return -ENODEV; - } - - return 0; -} - -static void io_pgtable_exit(void) -{ - debugfs_remove_recursive(io_pgtable_top); -} - -module_init(io_pgtable_init); -module_exit(io_pgtable_exit); From af3b847f2011f5c030f98b2f39b07270473894ef Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Thu, 25 Jun 2020 09:38:06 -0700 Subject: [PATCH 2/2] iommu: Remove iommu_debugfs_top iommu_debugfs_top was introduced in earlier kernel versions when IOMMU_DEBUGFS was not present. Now that IOMMU_DEBUGFS is present, and exposes iommu_debugfs_dir, which is logically equivalent to iommu_debugfs_top, there is no point in keeping it around, so remove it. Change-Id: I7032e370ccfd32f9d2b9046fecd98b4c6388450f Signed-off-by: Isaac J. Manjarres --- drivers/iommu/io-pgtable.c | 2 +- drivers/iommu/iommu-debug.c | 3 +-- drivers/iommu/iommu-debugfs.c | 1 - drivers/iommu/iommu.c | 3 --- include/linux/iommu.h | 1 - 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c index f3b31328e166..1010d388c9eb 100644 --- a/drivers/iommu/io-pgtable.c +++ b/drivers/iommu/io-pgtable.c @@ -84,7 +84,7 @@ static atomic_t pages_allocated; static int io_pgtable_init(void) { - io_pgtable_top = debugfs_create_dir("io-pgtable", iommu_debugfs_top); + io_pgtable_top = debugfs_create_dir("io-pgtable", iommu_debugfs_dir); if (!io_pgtable_top) return -ENODEV; diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c index dd1932f530d5..0abd5089f44b 100644 --- a/drivers/iommu/iommu-debug.c +++ b/drivers/iommu/iommu-debug.c @@ -2347,8 +2347,7 @@ err: static int iommu_debug_init_tests(void) { - debugfs_tests_dir = debugfs_create_dir("tests", - iommu_debugfs_top); + debugfs_tests_dir = debugfs_create_dir("tests", iommu_debugfs_dir); if (!debugfs_tests_dir) { pr_err_ratelimited("Couldn't create iommu/tests debugfs directory\n"); return -ENODEV; diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c index 41ced5ab3bed..f03548942096 100644 --- a/drivers/iommu/iommu-debugfs.c +++ b/drivers/iommu/iommu-debugfs.c @@ -32,7 +32,6 @@ void iommu_debugfs_setup(void) { if (!iommu_debugfs_dir) { iommu_debugfs_dir = debugfs_create_dir("iommu", NULL); - iommu_debugfs_top = iommu_debugfs_dir; pr_warn("\n"); pr_warn("*************************************************************\n"); pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 446b84be2f0a..76e14dc52edc 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -2162,8 +2161,6 @@ int report_iommu_fault(struct iommu_domain *domain, struct device *dev, } EXPORT_SYMBOL_GPL(report_iommu_fault); -struct dentry *iommu_debugfs_top; - static int __init iommu_init(void) { iommu_group_kset = kset_create_and_add("iommu_groups", diff --git a/include/linux/iommu.h b/include/linux/iommu.h index adbf54c068f2..6038be82e671 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -227,7 +227,6 @@ struct iommu_resv_region { enum iommu_resv_type type; }; -extern struct dentry *iommu_debugfs_top; /* Per device IOMMU features */ enum iommu_dev_features { IOMMU_DEV_FEAT_AUX, /* Aux-domain feature */