From a982fd9491c914c67d674a21e4ba0ac746807811 Mon Sep 17 00:00:00 2001 From: Ashutosh Bapat Date: Mon, 6 Apr 2026 10:43:18 +0530 Subject: [PATCH v20260406 2/6] Use smaps instead of status in resizable_shmem_used() /proc/self/status gives memory usages across all the VMAs of a process. /proc/self/smaps gives memory usages for each VMA separately. Hence use smaps to accurately estimate the memory allocated in the main shared memory segment. --- .../resizable_shmem/resizable_shmem--1.0.sql | 6 +- .../modules/resizable_shmem/resizable_shmem.c | 86 ++++++++----------- .../resizable_shmem/t/001_resizable_shmem.pl | 2 +- 3 files changed, 41 insertions(+), 53 deletions(-) diff --git a/src/test/modules/resizable_shmem/resizable_shmem--1.0.sql b/src/test/modules/resizable_shmem/resizable_shmem--1.0.sql index c1bcb6117b6..b4b07336dc3 100644 --- a/src/test/modules/resizable_shmem/resizable_shmem--1.0.sql +++ b/src/test/modules/resizable_shmem/resizable_shmem--1.0.sql @@ -25,8 +25,10 @@ RETURNS boolean AS 'MODULE_PATHNAME' LANGUAGE C STRICT; --- Function to report memory usage statistics of the calling backend -CREATE FUNCTION resizable_shmem_usage(OUT rss_anon bigint, OUT rss_file bigint, OUT rss_shmem bigint, OUT vm_size bigint) +-- Function to report memory mapped against the main shared memory segment in +-- the backend where this function runs. +CREATE FUNCTION resizable_shmem_usage() +RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C STRICT; diff --git a/src/test/modules/resizable_shmem/resizable_shmem.c b/src/test/modules/resizable_shmem/resizable_shmem.c index 5ae2d2e2d1d..2063d05053f 100644 --- a/src/test/modules/resizable_shmem/resizable_shmem.c +++ b/src/test/modules/resizable_shmem/resizable_shmem.c @@ -10,19 +10,17 @@ */ #include "postgres.h" +#include +#include + #include "commands/extension.h" #include "fmgr.h" -#include "funcapi.h" #include "miscadmin.h" #include "storage/shmem.h" #include "storage/spin.h" #include "utils/builtins.h" #include "utils/guc.h" #include "utils/memutils.h" -#include "utils/timestamp.h" -#include "access/htup_details.h" - -#include PG_MODULE_MAGIC; @@ -252,68 +250,56 @@ resizable_shmem_read(PG_FUNCTION_ARGS) } /* - * Report multiple memory usage statistics of the calling backend process - * as reported by the kernel. - * Returns RssAnon, RssFile, RssShmem, VmSize from /proc/self/status as a record. + * Return the memory mapped against the main shared memory segment in this + * backend. * - * The function assumes that these values will be available in - * /proc/self/status, any system which also support madvise with MADV_REMOVE and - * MADV_POPULATE_WRITE. + * The VMA containing our resizable_shmem pointer is used to determine the main + * memory segment. RSS + Swap (in bytes) for that VMS from /proc/self/smaps is + * returned. */ Datum resizable_shmem_usage(PG_FUNCTION_ARGS) { FILE *f; char line[256]; - int64 rss_anon_kb = -1; - int64 rss_file_kb = -1; - int64 rss_shmem_kb = -1; - int64 vm_size_kb = -1; - int found = 0; - TupleDesc tupdesc; - Datum values[4]; - bool nulls[4]; - HeapTuple tuple; - - /* Open /proc/self/status to read memory information */ - f = fopen("/proc/self/status", "r"); + int64 rss_kb = -1; + int64 swap_kb = -1; + uintptr_t target = (uintptr_t) resizable_shmem; + bool in_target_vma = false; + size_t result; + + f = fopen("/proc/self/smaps", "r"); if (f == NULL) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not open /proc/self/status: %m"))); + errmsg("could not open /proc/self/smaps: %m"))); - /* Look for the memory usage lines */ - while (fgets(line, sizeof(line), f) != NULL && found < 4) + while (fgets(line, sizeof(line), f) != NULL) { - if (rss_anon_kb == -1 && sscanf(line, "RssAnon: %ld kB", &rss_anon_kb) == 1) - found++; - else if (rss_file_kb == -1 && sscanf(line, "RssFile: %ld kB", &rss_file_kb) == 1) - found++; - else if (rss_shmem_kb == -1 && sscanf(line, "RssShmem: %ld kB", &rss_shmem_kb) == 1) - found++; - else if (vm_size_kb == -1 && sscanf(line, "VmSize: %ld kB", &vm_size_kb) == 1) - found++; + unsigned long start; + unsigned long end; + + if (sscanf(line, "%lx-%lx", &start, &end) == 2) + { + in_target_vma = (target >= start && target < end); + } + else if (in_target_vma) + { + if (rss_kb == -1) + sscanf(line, "Rss: %ld kB", &rss_kb); + if (swap_kb == -1) + sscanf(line, "Swap: %ld kB", &swap_kb); + if (rss_kb >= 0 && swap_kb >= 0) + break; + } } fclose(f); - /* Build tuple descriptor for our result type */ - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context " - "that cannot accept a record"))); - - /* Build the result tuple */ - values[0] = Int64GetDatum(rss_anon_kb >= 0 ? rss_anon_kb * 1024 : 0); - values[1] = Int64GetDatum(rss_file_kb >= 0 ? rss_file_kb * 1024 : 0); - values[2] = Int64GetDatum(rss_shmem_kb >= 0 ? rss_shmem_kb * 1024 : 0); - values[3] = Int64GetDatum(vm_size_kb >= 0 ? vm_size_kb * 1024 : 0); - - nulls[0] = nulls[1] = nulls[2] = nulls[3] = false; + result = rss_kb >= 0 ? mul_size(rss_kb, 1024) : 0; + result = add_size(result, swap_kb >= 0 ? mul_size(swap_kb, 1024) : 0); - tuple = heap_form_tuple(tupdesc, values, nulls); - PG_RETURN_DATUM(HeapTupleGetDatum(tuple)); + PG_RETURN_INT64(result); } /* diff --git a/src/test/modules/resizable_shmem/t/001_resizable_shmem.pl b/src/test/modules/resizable_shmem/t/001_resizable_shmem.pl index 6d45b1eccdc..a172cd0fd19 100644 --- a/src/test/modules/resizable_shmem/t/001_resizable_shmem.pl +++ b/src/test/modules/resizable_shmem/t/001_resizable_shmem.pl @@ -19,7 +19,7 @@ sub check_shmem_usage { my ($session, $label, $node) = @_; - my $rss_shmem = $session->query_safe('SELECT rss_shmem FROM resizable_shmem_usage();', + my $rss_shmem = $session->query_safe('SELECT resizable_shmem_usage();', verbose => 0); my $total_alloc = $node->safe_psql('postgres', "SELECT sum(allocated_size) FROM pg_shmem_allocations;"); -- 2.34.1