On Thu, Nov 27, 2025 at 01:51:39PM +0530, Rahila Syed wrote:
> Thank you for this improvement. I think it will be very helpful to have
> the ability to report dsa and dshash memory sizes.

Thanks for reviewing!

> 1. As a result of this change, the following comment in
> pg_get_dsm_registry_allocations is incorrect.

Fixed.

> +       LWLockAcquire(&control->lock, LW_SHARED);
> 
> The dsa_get_total_size function takes LW_EXCLUSIVE lock for the same
> purpose. I wonder why that is the case and whether both should be
> consistent.

That function was added by commit ee1b30f, which AFAICT used an exclusive
lock just to stay consistent with the rest of dsa.c [0].  I don't see any
discussion about this in the original DSA thread [1].  Perhaps we could go
through dsa.c and switch to LW_SHARED where appropriate, although I doubt
it makes much difference.

> +size_t
> +dsa_get_total_size_from_handle(dsa_handle handle)
> 
> I believe this function will report the size as long as the dsa control
> structure is created within a dsm segment, since all dsm segments are
> tracked by the global list - dsm_segment_list, regardless of whether the
> dsa is created with dsa_create or dsa_create_in_place. In that case,
> perhaps we should update the comment above to reflect this.

Sorry, I'm not following what you think we should update the comment to
say.

> 4. Since, with this change, the size column will show memory allocation
> regardless of whether it is currently mapped in the local process, I
> think it would be helpful to add a boolean column to display the mapped
> status as a future enhancement.

Maybe, although I'm struggling to think of a scenario where that
information would be useful.

[0] 
https://postgr.es/m/CAD21AoDoWrbNf%2BK2Fwg2n%3DCZDHigjkndwqy_86BGgXBp9Kbq4Q%40mail.gmail.com
[1] 
https://postgr.es/m/CAEepm%3D1z5WLuNoJ80PaCvz6EtG9dN0j-KuHcHtU6QEfcPP5-qA%40mail.gmail.com

-- 
nathan
>From df18d34c52f0f744995c4f01b3b05205ed01b535 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <[email protected]>
Date: Wed, 26 Nov 2025 16:48:13 -0600
Subject: [PATCH v2 1/1] rework DSM registry view

---
 doc/src/sgml/system-views.sgml                |  4 +--
 src/backend/storage/ipc/dsm_registry.c        | 22 ++++--------
 src/backend/utils/mmgr/dsa.c                  | 35 +++++++++++++++++++
 src/include/utils/dsa.h                       |  1 +
 .../expected/test_dsm_registry.out            |  4 +--
 .../sql/test_dsm_registry.sql                 |  4 +--
 6 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 7db8f73eba2..162c76b729a 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -1150,8 +1150,8 @@ AND c1.path[c2.level] = c2.path[c2.level];
        <structfield>size</structfield> <type>int8</type>
       </para>
       <para>
-       Size of the allocation in bytes.  NULL for entries of type
-       <literal>area</literal> and <literal>hash</literal>.
+       Size of the allocation in bytes.  NULL for entries that failed
+       initialization.
       </para></entry>
      </row>
     </tbody>
diff --git a/src/backend/storage/ipc/dsm_registry.c 
b/src/backend/storage/ipc/dsm_registry.c
index ef6533b1100..0f3e08c44d8 100644
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -463,26 +463,18 @@ pg_get_dsm_registry_allocations(PG_FUNCTION_ARGS)
                Datum           vals[3];
                bool            nulls[3] = {0};
 
-               /* Do not show partially-initialized entries. */
-               if (entry->type == DSMR_ENTRY_TYPE_DSM &&
-                       entry->dsm.handle == DSM_HANDLE_INVALID)
-                       continue;
-               if (entry->type == DSMR_ENTRY_TYPE_DSA &&
-                       entry->dsa.handle == DSA_HANDLE_INVALID)
-                       continue;
-               if (entry->type == DSMR_ENTRY_TYPE_DSH &&
-                       entry->dsh.dsa_handle == DSA_HANDLE_INVALID)
-                       continue;
-
                vals[0] = CStringGetTextDatum(entry->name);
                vals[1] = CStringGetTextDatum(DSMREntryTypeNames[entry->type]);
 
-               /*
-                * Since we can't know the size of DSA/dshash entries without 
first
-                * attaching to them, return NULL for those.
-                */
+               /* Be careful to only return the sizes of initialized entries. 
*/
                if (entry->type == DSMR_ENTRY_TYPE_DSM)
                        vals[2] = Int64GetDatum(entry->dsm.size);
+               else if (entry->type == DSMR_ENTRY_TYPE_DSA &&
+                                entry->dsa.handle != DSA_HANDLE_INVALID)
+                       vals[2] = 
Int64GetDatum(dsa_get_total_size_from_handle(entry->dsa.handle));
+               else if (entry->type == DSMR_ENTRY_TYPE_DSH &&
+                                entry->dsh.dsa_handle !=DSA_HANDLE_INVALID)
+                       vals[2] = 
Int64GetDatum(dsa_get_total_size_from_handle(entry->dsh.dsa_handle));
                else
                        nulls[2] = true;
 
diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c
index be43e9351c3..030f9463712 100644
--- a/src/backend/utils/mmgr/dsa.c
+++ b/src/backend/utils/mmgr/dsa.c
@@ -1050,6 +1050,41 @@ dsa_get_total_size(dsa_area *area)
        return size;
 }
 
+/*
+ * Same as dsa_get_total_size(), but accepts a DSA handle.  The area must have
+ * been created with dsa_create (not dsa_create_in_place).
+ */
+size_t
+dsa_get_total_size_from_handle(dsa_handle handle)
+{
+       size_t          size;
+       bool            already_attached;
+       dsm_segment *segment;
+       dsa_area_control *control;
+
+       already_attached = dsa_is_attached(handle);
+       if (already_attached)
+               segment = dsm_find_mapping(handle);
+       else
+               segment = dsm_attach(handle);
+
+       if (segment == NULL)
+               ereport(ERROR,
+                               
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+                                errmsg("could not attach to dynamic shared 
area")));
+
+       control = (dsa_area_control *) dsm_segment_address(segment);
+
+       LWLockAcquire(&control->lock, LW_SHARED);
+       size = control->total_segment_size;
+       LWLockRelease(&control->lock);
+
+       if (!already_attached)
+               dsm_detach(segment);
+
+       return size;
+}
+
 /*
  * Aggressively free all spare memory in the hope of returning DSM segments to
  * the operating system.
diff --git a/src/include/utils/dsa.h b/src/include/utils/dsa.h
index f2104dacbfc..42449ff22de 100644
--- a/src/include/utils/dsa.h
+++ b/src/include/utils/dsa.h
@@ -161,6 +161,7 @@ extern dsa_pointer dsa_allocate_extended(dsa_area *area, 
size_t size, int flags)
 extern void dsa_free(dsa_area *area, dsa_pointer dp);
 extern void *dsa_get_address(dsa_area *area, dsa_pointer dp);
 extern size_t dsa_get_total_size(dsa_area *area);
+extern size_t dsa_get_total_size_from_handle(dsa_handle handle);
 extern void dsa_trim(dsa_area *area);
 extern void dsa_dump(dsa_area *area);
 
diff --git a/src/test/modules/test_dsm_registry/expected/test_dsm_registry.out 
b/src/test/modules/test_dsm_registry/expected/test_dsm_registry.out
index ca8abbb377e..75d9eda0756 100644
--- a/src/test/modules/test_dsm_registry/expected/test_dsm_registry.out
+++ b/src/test/modules/test_dsm_registry/expected/test_dsm_registry.out
@@ -1,4 +1,4 @@
-SELECT name, type, size IS DISTINCT FROM 0 AS size
+SELECT name, type, size > 0 AS size
 FROM pg_dsm_registry_allocations
 WHERE name like 'test_dsm_registry%' ORDER BY name;
  name | type | size 
@@ -32,7 +32,7 @@ SELECT get_val_in_hash('test');
 (1 row)
 
 \c
-SELECT name, type, size IS DISTINCT FROM 0 AS size
+SELECT name, type, size > 0 AS size
 FROM pg_dsm_registry_allocations
 WHERE name like 'test_dsm_registry%' ORDER BY name;
           name          |  type   | size 
diff --git a/src/test/modules/test_dsm_registry/sql/test_dsm_registry.sql 
b/src/test/modules/test_dsm_registry/sql/test_dsm_registry.sql
index 965a3f1ebb6..1b9ee3ebf18 100644
--- a/src/test/modules/test_dsm_registry/sql/test_dsm_registry.sql
+++ b/src/test/modules/test_dsm_registry/sql/test_dsm_registry.sql
@@ -1,4 +1,4 @@
-SELECT name, type, size IS DISTINCT FROM 0 AS size
+SELECT name, type, size > 0 AS size
 FROM pg_dsm_registry_allocations
 WHERE name like 'test_dsm_registry%' ORDER BY name;
 CREATE EXTENSION test_dsm_registry;
@@ -8,6 +8,6 @@ SELECT set_val_in_hash('test', '1414');
 SELECT get_val_in_shmem();
 SELECT get_val_in_hash('test');
 \c
-SELECT name, type, size IS DISTINCT FROM 0 AS size
+SELECT name, type, size > 0 AS size
 FROM pg_dsm_registry_allocations
 WHERE name like 'test_dsm_registry%' ORDER BY name;
-- 
2.39.5 (Apple Git-154)

Reply via email to