Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * ipci.c
4 : : * POSTGRES inter-process communication initialization code.
5 : : *
6 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : *
10 : : * IDENTIFICATION
11 : : * src/backend/storage/ipc/ipci.c
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "miscadmin.h"
18 : : #include "pgstat.h"
19 : : #include "storage/dsm.h"
20 : : #include "storage/ipc.h"
21 : : #include "storage/lock.h"
22 : : #include "storage/pg_shmem.h"
23 : : #include "storage/proc.h"
24 : : #include "storage/shmem_internal.h"
25 : : #include "storage/subsystems.h"
26 : : #include "utils/guc.h"
27 : :
28 : : /* GUCs */
29 : : int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
30 : :
31 : : shmem_startup_hook_type shmem_startup_hook = NULL;
32 : :
33 : : static Size total_addin_request = 0;
34 : :
35 : : /*
36 : : * RequestAddinShmemSpace
37 : : * Request that extra shmem space be allocated for use by
38 : : * a loadable module.
39 : : *
40 : : * This may only be called via the shmem_request_hook of a library that is
41 : : * loaded into the postmaster via shared_preload_libraries. Calls from
42 : : * elsewhere will fail.
43 : : */
44 : : void
7142 tgl@sss.pgh.pa.us 45 :LBC (18) : RequestAddinShmemSpace(Size size)
46 : : {
1453 rhaas@postgresql.org 47 [ # # ]: (18) : if (!process_shmem_requests_in_progress)
1453 rhaas@postgresql.org 48 [ # # ]:UBC 0 : elog(FATAL, "cannot request additional shared memory outside shmem_request_hook");
7142 tgl@sss.pgh.pa.us 49 :LBC (18) : total_addin_request = add_size(total_addin_request, size);
50 : (18) : }
51 : :
52 : : /*
53 : : * CalculateShmemSize
54 : : * Calculates the amount of shared memory needed.
55 : : */
56 : : Size
180 heikki.linnakangas@i 57 :GNC 2311 : CalculateShmemSize(void)
58 : : {
59 : : Size size;
60 : :
61 : : /*
62 : : * Size of the Postgres shared-memory block is estimated via moderately-
63 : : * accurate estimates for the big hogs, plus 100K for the stuff that's too
64 : : * small to bother with estimating.
65 : : *
66 : : * We take some care to ensure that the total size request doesn't
67 : : * overflow size_t. If this gets through, we don't need to be so careful
68 : : * during the actual allocation phase.
69 : : */
1702 michael@paquier.xyz 70 :CBC 2311 : size = 100000;
29 heikki.linnakangas@i 71 :GNC 2311 : size = add_size(size, ShmemGetRequestedSize());
72 : :
73 : : /* include additional requested shmem from preload libraries */
1702 michael@paquier.xyz 74 :CBC 2311 : size = add_size(size, total_addin_request);
75 : :
76 : : /* might as well round it off to a multiple of a typical page size */
77 : 2311 : size = add_size(size, 8192 - (size % 8192));
78 : :
79 : 2311 : return size;
80 : : }
81 : :
82 : : #ifdef EXEC_BACKEND
83 : : /*
84 : : * AttachSharedMemoryStructs
85 : : * Initialize a postmaster child process's access to shared memory
86 : : * structures.
87 : : *
88 : : * In !EXEC_BACKEND mode, we inherit everything through the fork, and this
89 : : * isn't needed.
90 : : */
91 : : void
92 : : AttachSharedMemoryStructs(void)
93 : : {
94 : : /* InitProcess must've been called already */
95 : : Assert(MyProc != NULL);
96 : : Assert(IsUnderPostmaster);
97 : :
98 : : /*
99 : : * In EXEC_BACKEND mode, backends don't inherit the number of fast-path
100 : : * groups we calculated before setting the shmem up, so recalculate it.
101 : : */
102 : : InitializeFastPathLocks();
103 : :
104 : : /* Establish pointers to all shared memory areas in this backend */
105 : : ShmemAttachRequested();
106 : :
107 : : /*
108 : : * Now give loadable modules a chance to set up their shmem allocations
109 : : */
110 : : if (shmem_startup_hook)
111 : : shmem_startup_hook();
112 : : }
113 : : #endif
114 : :
115 : : /*
116 : : * CreateSharedMemoryAndSemaphores
117 : : * Creates and initializes shared memory and semaphores.
118 : : */
119 : : void
884 heikki.linnakangas@i 120 : 1243 : CreateSharedMemoryAndSemaphores(void)
121 : : {
122 : : PGShmemHeader *shim;
123 : : PGShmemHeader *seghdr;
124 : : Size size;
125 : :
126 [ - + ]: 1243 : Assert(!IsUnderPostmaster);
127 : :
128 : : /* Compute the size of the shared-memory block */
180 heikki.linnakangas@i 129 :GNC 1243 : size = CalculateShmemSize();
884 heikki.linnakangas@i 130 [ + + ]:CBC 1243 : elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
131 : :
132 : : /*
133 : : * Create the shmem segment
134 : : */
135 : 1243 : seghdr = PGSharedMemoryCreate(size, &shim);
136 : :
137 : : /*
138 : : * Make sure that huge pages are never reported as "unknown" while the
139 : : * server is running.
140 : : */
141 [ - + ]: 1241 : Assert(strcmp("unknown",
142 : : GetConfigOption("huge_pages_status", false, false)) != 0);
143 : :
144 : : /*
145 : : * Set up shared memory allocation mechanism
146 : : */
95 heikki.linnakangas@i 147 :GNC 1241 : InitShmemAllocator(seghdr);
148 : :
149 : : /* Initialize all shmem areas */
29 150 : 1241 : ShmemInitRequested();
151 : :
152 : : /* Initialize dynamic shared memory facilities. */
884 heikki.linnakangas@i 153 :CBC 1241 : dsm_postmaster_startup(shim);
154 : :
155 : : /*
156 : : * Now give loadable modules a chance to set up their shmem allocations
157 : : */
158 [ - + ]: 1241 : if (shmem_startup_hook)
884 heikki.linnakangas@i 159 :LBC (16) : shmem_startup_hook();
884 heikki.linnakangas@i 160 :CBC 1241 : }
161 : :
162 : : /*
163 : : * Early initialization of various subsystems, giving them a chance to
164 : : * register their shared memory needs before the shared memory segment is
165 : : * allocated.
166 : : */
167 : : void
29 heikki.linnakangas@i 168 :GNC 1252 : RegisterBuiltinShmemCallbacks(void)
169 : : {
170 : : /*
171 : : * Call RegisterShmemCallbacks(...) on each subsystem listed in
172 : : * subsystemlist.h
173 : : */
174 : : #define PG_SHMEM_SUBSYSTEM(subsystem_callbacks) \
175 : : RegisterShmemCallbacks(&(subsystem_callbacks));
176 : :
177 : : #include "storage/subsystemlist.h"
178 : :
179 : : #undef PG_SHMEM_SUBSYSTEM
29 heikki.linnakangas@i 180 :CBC 1252 : }
181 : :
182 : : /*
183 : : * InitializeShmemGUCs
184 : : *
185 : : * This function initializes runtime-computed GUCs related to the amount of
186 : : * shared memory required for the current configuration.
187 : : */
188 : : void
1700 michael@paquier.xyz 189 : 1068 : InitializeShmemGUCs(void)
190 : : {
191 : : char buf[64];
192 : : Size size_b;
193 : : Size size_mb;
194 : : Size hp_size;
195 : :
196 : : /*
197 : : * Calculate the shared memory size and round up to the nearest megabyte.
198 : : */
180 heikki.linnakangas@i 199 :GNC 1068 : size_b = CalculateShmemSize();
1700 michael@paquier.xyz 200 :CBC 1068 : size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024);
201 : 1068 : sprintf(buf, "%zu", size_mb);
1427 tgl@sss.pgh.pa.us 202 : 1068 : SetConfigOption("shared_memory_size", buf,
203 : : PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
204 : :
205 : : /*
206 : : * Calculate the number of huge pages required.
207 : : */
1687 michael@paquier.xyz 208 : 1068 : GetHugePageSize(&hp_size, NULL);
209 [ + - ]: 1068 : if (hp_size != 0)
210 : : {
211 : : Size hp_required;
212 : :
102 nathan@postgresql.or 213 :GNC 1068 : hp_required = size_b / hp_size;
214 [ + - ]: 1068 : if (size_b % hp_size != 0)
215 : 1068 : hp_required = add_size(hp_required, 1);
1687 michael@paquier.xyz 216 :CBC 1068 : sprintf(buf, "%zu", hp_required);
1427 tgl@sss.pgh.pa.us 217 : 1068 : SetConfigOption("shared_memory_size_in_huge_pages", buf,
218 : : PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
219 : : }
220 : :
180 heikki.linnakangas@i 221 :GNC 1068 : sprintf(buf, "%d", ProcGlobalSemas());
648 nathan@postgresql.or 222 :CBC 1068 : SetConfigOption("num_os_semaphores", buf, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
1700 michael@paquier.xyz 223 : 1068 : }
|