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 <jonathanh@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3180097
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Jon Hunter
2024-06-19 16:26:26 +01:00
committed by mobile promotions
parent d71b21ebb9
commit f327656ea3
3 changed files with 41 additions and 4 deletions

View File

@@ -1,10 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/* /*
* Copyright (c) 2011-2024, NVIDIA CORPORATION. All rights reserved.
*
* User-space interface to nvmap * User-space interface to nvmap
*/ */
#include <nvidia/conftest.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
@@ -769,6 +770,23 @@ static void nvmap_get_client_mss(struct nvmap_client *client,
nvmap_ref_unlock(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 #define PSS_SHIFT 12
static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id) static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id)
{ {
@@ -802,7 +820,7 @@ static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id
for (i = 0; i < h->size >> PAGE_SHIFT; i++) { for (i = 0; i < h->size >> PAGE_SHIFT; i++) {
struct page *page = nvmap_to_page(h->pgalloc.pages[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; *pss += PAGE_SIZE;
} }
} }
@@ -1180,7 +1198,7 @@ static int procrank_pte_entry(pte_t *pte, unsigned long addr, unsigned long end,
if (!page) if (!page)
return 0; return 0;
mapcount = page_mapcount(page); mapcount = nvmap_page_mapcount(page);
if (mapcount >= 2) if (mapcount >= 2)
mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount;
else else

View File

@@ -123,6 +123,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_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_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 += 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 += 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_file_rcu_has_double_ptr_file_arg
NV_CONFTEST_FUNCTION_COMPILE_TESTS += get_user_pages NV_CONFTEST_FUNCTION_COMPILE_TESTS += get_user_pages

View File

@@ -7193,6 +7193,24 @@ compile_test() {
"NV_ETHTOOL_OPS_GET_SET_RXFH_HAS_RXFH_PARAM_ARGS" "" "types" "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 <linux/mm.h>
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) genpd_xlate_t_has_const_of_phandle_args)
# #
# Determine if genpd_xlate_t function pointer has a # Determine if genpd_xlate_t function pointer has a