From 55b09a913f39f8a21e40e265dd1328798407a87b Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 19 Jun 2024 16:26:26 +0100 Subject: [PATCH] nvmap: Implement nvmap_page_mapcount() Upstream commit cdd9a571b7d8 ("fs/proc: move page_mapcount() to fs/proc/internal.h") made page_mapcount() an internal function for Linux v6.11. This function is used by the NVMAP driver and so implement this function in the NVMAP driver directly instead. Note that newer kernels implement folio_entire_mapcount() for compound page counts where as older kernels use compound_mapcount(). Use conftest to detect which of these functions is present in the kernel. Bug 4749580 Change-Id: I6504448727d6b3e9f2caa8581a66aad464ae2426 Signed-off-by: Jon Hunter Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3180097 (cherry picked from commit f327656ea3d17eda61dbe0e96ba030216c522128) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3183926 GVS: buildbot_gerritrpt Reviewed-by: Ketan Patil --- drivers/video/tegra/nvmap/nvmap_dev.c | 26 ++++++++++++++++++++++---- scripts/conftest/Makefile | 1 + scripts/conftest/conftest.sh | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/video/tegra/nvmap/nvmap_dev.c b/drivers/video/tegra/nvmap/nvmap_dev.c index 57feeda4..2d9c9f44 100644 --- a/drivers/video/tegra/nvmap/nvmap_dev.c +++ b/drivers/video/tegra/nvmap/nvmap_dev.c @@ -1,10 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. /* - * Copyright (c) 2011-2023, NVIDIA CORPORATION. All rights reserved. - * * User-space interface to nvmap */ +#include + #include #include #include @@ -768,6 +769,23 @@ static void nvmap_get_client_mss(struct nvmap_client *client, nvmap_ref_unlock(client); } +static int nvmap_page_mapcount(struct page *page) +{ + int mapcount = atomic_read(&page->_mapcount) + 1; + + /* Handle page_has_type() pages */ + if (mapcount < PAGE_MAPCOUNT_RESERVE + 1) + mapcount = 0; + if (unlikely(PageCompound(page))) +#if defined(NV_FOLIO_ENTIRE_MAPCOUNT_PRESENT) /* Linux v5.18 */ + mapcount += folio_entire_mapcount(page_folio(page)); +#else + mapcount += compound_mapcount(page); +#endif + + return mapcount; +} + #define PSS_SHIFT 12 static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type) { @@ -796,7 +814,7 @@ static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type) for (i = 0; i < h->size >> PAGE_SHIFT; i++) { struct page *page = nvmap_to_page(h->pgalloc.pages[i]); - if (page_mapcount(page) > 0) + if (nvmap_page_mapcount(page) > 0) *pss += PAGE_SIZE; } } @@ -1152,7 +1170,7 @@ static int procrank_pte_entry(pte_t *pte, unsigned long addr, unsigned long end, if (!page) return 0; - mapcount = page_mapcount(page); + mapcount = nvmap_page_mapcount(page); if (mapcount >= 2) mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; else diff --git a/scripts/conftest/Makefile b/scripts/conftest/Makefile index 36d545ed..ffb49204 100644 --- a/scripts/conftest/Makefile +++ b/scripts/conftest/Makefile @@ -122,6 +122,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += ethtool_kernel_ethtool_ts_info_struct_pres NV_CONFTEST_FUNCTION_COMPILE_TESTS += ethtool_ops_get_set_coalesce_has_coal_and_extack_args NV_CONFTEST_FUNCTION_COMPILE_TESTS += ethtool_ops_get_set_ringparam_has_ringparam_and_extack_args NV_CONFTEST_FUNCTION_COMPILE_TESTS += ethtool_ops_get_set_rxfh_has_rxfh_param_args +NV_CONFTEST_FUNCTION_COMPILE_TESTS += folio_entire_mapcount NV_CONFTEST_FUNCTION_COMPILE_TESTS += genpd_xlate_t_has_const_of_phandle_args NV_CONFTEST_FUNCTION_COMPILE_TESTS += get_file_rcu_has_double_ptr_file_arg NV_CONFTEST_FUNCTION_COMPILE_TESTS += get_user_pages diff --git a/scripts/conftest/conftest.sh b/scripts/conftest/conftest.sh index e70cf6d8..d7136efd 100755 --- a/scripts/conftest/conftest.sh +++ b/scripts/conftest/conftest.sh @@ -7144,6 +7144,24 @@ compile_test() { "NV_ETHTOOL_OPS_GET_SET_RXFH_HAS_RXFH_PARAM_ARGS" "" "types" ;; + folio_entire_mapcount) + # + # Determine if function folio_entire_mapcount() is present. + # + # Commit 74e8ee4708a8 ("mm: Turn head_compound_mapcount() into + # folio_entire_mapcount()") add folio_entire_mapcount() in Linux + # v5.18. + # + CODE=" + #include + int conftest(void) + { + return folio_entire_mapcount(); + }" + + compile_check_conftest "$CODE" "NV_FOLIO_ENTIRE_MAPCOUNT_PRESENT" "" "functions" + ;; + genpd_xlate_t_has_const_of_phandle_args) # # Determine if genpd_xlate_t function pointer has a