PostgreSQL Source Code: src/backend/storage/aio/aio_init.c Source File

PostgreSQL Source Code git master
aio_init.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * aio_init.c
4 * AIO - Subsystem Initialization
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * IDENTIFICATION
10 * src/backend/storage/aio/aio_init.c
11 *
12 *-------------------------------------------------------------------------
13 */
14
15#include "postgres.h"
16
17#include "miscadmin.h"
18#include "storage/aio.h"
19#include "storage/aio_internal.h"
20#include "storage/aio_subsys.h"
21#include "storage/bufmgr.h"
22#include "storage/io_worker.h"
23#include "storage/ipc.h"
24#include "storage/proc.h"
25#include "storage/shmem.h"
26#include "utils/guc.h"
27
28
29
30static Size
31 AioCtlShmemSize(void)
32{
33 /* pgaio_ctl itself */
34 return sizeof(PgAioCtl);
35}
36
37static uint32
38 AioProcs(void)
39{
40 /*
41 * While AIO workers don't need their own AIO context, we can't currently
42 * guarantee nothing gets assigned to the a ProcNumber for an IO worker if
43 * we just subtracted MAX_IO_WORKERS.
44 */
45 return MaxBackends + NUM_AUXILIARY_PROCS;
46}
47
48static Size
49 AioBackendShmemSize(void)
50{
51 return mul_size(AioProcs(), sizeof(PgAioBackend));
52}
53
54static Size
55 AioHandleShmemSize(void)
56{
57 Size sz;
58
59 /* verify AioChooseMaxConcurrency() did its thing */
60 Assert(io_max_concurrency > 0);
61
62 /* io handles */
63 sz = mul_size(AioProcs(),
64 mul_size(io_max_concurrency, sizeof(PgAioHandle)));
65
66 return sz;
67}
68
69static Size
70 AioHandleIOVShmemSize(void)
71{
72 /* each IO handle can have up to io_max_combine_limit iovec objects */
73 return mul_size(sizeof(struct iovec),
74 mul_size(mul_size(io_max_combine_limit, AioProcs()),
75 io_max_concurrency));
76}
77
78static Size
79 AioHandleDataShmemSize(void)
80{
81 /* each buffer referenced by an iovec can have associated data */
82 return mul_size(sizeof(uint64),
83 mul_size(mul_size(io_max_combine_limit, AioProcs()),
84 io_max_concurrency));
85}
86
87/*
88 * Choose a suitable value for io_max_concurrency.
89 *
90 * It's unlikely that we could have more IOs in flight than buffers that we
91 * would be allowed to pin.
92 *
93 * On the upper end, apply a cap too - just because shared_buffers is large,
94 * it doesn't make sense have millions of buffers undergo IO concurrently.
95 */
96static int
97 AioChooseMaxConcurrency(void)
98{
99 uint32 max_backends;
100 int max_proportional_pins;
101
102 /* Similar logic to LimitAdditionalPins() */
103 max_backends = MaxBackends + NUM_AUXILIARY_PROCS;
104 max_proportional_pins = NBuffers / max_backends;
105
106 max_proportional_pins = Max(max_proportional_pins, 1);
107
108 /* apply upper limit */
109 return Min(max_proportional_pins, 64);
110}
111
112Size
113 AioShmemSize(void)
114{
115 Size sz = 0;
116
117 /*
118 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
119 * However, if the DBA explicitly set io_max_concurrency = -1 in the
120 * config file, then PGC_S_DYNAMIC_DEFAULT will fail to override that and
121 * we must force the matter with PGC_S_OVERRIDE.
122 */
123 if (io_max_concurrency == -1)
124 {
125 char buf[32];
126
127 snprintf(buf, sizeof(buf), "%d", AioChooseMaxConcurrency());
128 SetConfigOption("io_max_concurrency", buf, PGC_POSTMASTER,
129 PGC_S_DYNAMIC_DEFAULT);
130 if (io_max_concurrency == -1) /* failed to apply it? */
131 SetConfigOption("io_max_concurrency", buf, PGC_POSTMASTER,
132 PGC_S_OVERRIDE);
133 }
134
135 sz = add_size(sz, AioCtlShmemSize());
136 sz = add_size(sz, AioBackendShmemSize());
137 sz = add_size(sz, AioHandleShmemSize());
138 sz = add_size(sz, AioHandleIOVShmemSize());
139 sz = add_size(sz, AioHandleDataShmemSize());
140
141 /* Reserve space for method specific resources. */
142 if (pgaio_method_ops->shmem_size)
143 sz = add_size(sz, pgaio_method_ops->shmem_size());
144
145 return sz;
146}
147
148void
149 AioShmemInit(void)
150{
151 bool found;
152 uint32 io_handle_off = 0;
153 uint32 iovec_off = 0;
154 uint32 per_backend_iovecs = io_max_concurrency * io_max_combine_limit;
155
156 pgaio_ctl = (PgAioCtl *)
157 ShmemInitStruct("AioCtl", AioCtlShmemSize(), &found);
158
159 if (found)
160 goto out;
161
162 memset(pgaio_ctl, 0, AioCtlShmemSize());
163
164 pgaio_ctl->io_handle_count = AioProcs() * io_max_concurrency;
165 pgaio_ctl->iovec_count = AioProcs() * per_backend_iovecs;
166
167 pgaio_ctl->backend_state = (PgAioBackend *)
168 ShmemInitStruct("AioBackend", AioBackendShmemSize(), &found);
169
170 pgaio_ctl->io_handles = (PgAioHandle *)
171 ShmemInitStruct("AioHandle", AioHandleShmemSize(), &found);
172
173 pgaio_ctl->iovecs = (struct iovec *)
174 ShmemInitStruct("AioHandleIOV", AioHandleIOVShmemSize(), &found);
175 pgaio_ctl->handle_data = (uint64 *)
176 ShmemInitStruct("AioHandleData", AioHandleDataShmemSize(), &found);
177
178 for (int procno = 0; procno < AioProcs(); procno++)
179 {
180 PgAioBackend *bs = &pgaio_ctl->backend_state[procno];
181
182 bs->io_handle_off = io_handle_off;
183 io_handle_off += io_max_concurrency;
184
185 dclist_init(&bs->idle_ios);
186 memset(bs->staged_ios, 0, sizeof(PgAioHandle *) * PGAIO_SUBMIT_BATCH_SIZE);
187 dclist_init(&bs->in_flight_ios);
188
189 /* initialize per-backend IOs */
190 for (int i = 0; i < io_max_concurrency; i++)
191 {
192 PgAioHandle *ioh = &pgaio_ctl->io_handles[bs->io_handle_off + i];
193
194 ioh->generation = 1;
195 ioh->owner_procno = procno;
196 ioh->iovec_off = iovec_off;
197 ioh->handle_data_len = 0;
198 ioh->report_return = NULL;
199 ioh->resowner = NULL;
200 ioh->num_callbacks = 0;
201 ioh->distilled_result.status = PGAIO_RS_UNKNOWN;
202 ioh->flags = 0;
203
204 ConditionVariableInit(&ioh->cv);
205
206 dclist_push_tail(&bs->idle_ios, &ioh->node);
207 iovec_off += io_max_combine_limit;
208 }
209 }
210
211out:
212 /* Initialize IO method specific resources. */
213 if (pgaio_method_ops->shmem_init)
214 pgaio_method_ops->shmem_init(!found);
215}
216
217void
218 pgaio_init_backend(void)
219{
220 /* shouldn't be initialized twice */
221 Assert(!pgaio_my_backend);
222
223 if (MyBackendType == B_IO_WORKER)
224 return;
225
226 if (MyProc == NULL || MyProcNumber >= AioProcs())
227 elog(ERROR, "aio requires a normal PGPROC");
228
229 pgaio_my_backend = &pgaio_ctl->backend_state[MyProcNumber];
230
231 if (pgaio_method_ops->init_backend)
232 pgaio_method_ops->init_backend();
233
234 before_shmem_exit(pgaio_shutdown, 0);
235}
PgAioBackend * pgaio_my_backend
Definition: aio.c:81
int io_max_concurrency
Definition: aio.c:75
PgAioCtl * pgaio_ctl
Definition: aio.c:78
const IoMethodOps * pgaio_method_ops
Definition: aio.c:93
void pgaio_shutdown(int code, Datum arg)
Definition: aio.c:1285
static Size AioHandleIOVShmemSize(void)
Definition: aio_init.c:70
void pgaio_init_backend(void)
Definition: aio_init.c:218
static Size AioHandleDataShmemSize(void)
Definition: aio_init.c:79
void AioShmemInit(void)
Definition: aio_init.c:149
static Size AioHandleShmemSize(void)
Definition: aio_init.c:55
Size AioShmemSize(void)
Definition: aio_init.c:113
static Size AioBackendShmemSize(void)
Definition: aio_init.c:49
static int AioChooseMaxConcurrency(void)
Definition: aio_init.c:97
static uint32 AioProcs(void)
Definition: aio_init.c:38
static Size AioCtlShmemSize(void)
Definition: aio_init.c:31
struct PgAioCtl PgAioCtl
#define PGAIO_SUBMIT_BATCH_SIZE
Definition: aio_internal.h:28
@ PGAIO_RS_UNKNOWN
Definition: aio_types.h:80
int io_max_combine_limit
Definition: bufmgr.c:172
#define Min(x, y)
Definition: c.h:1003
#define Max(x, y)
Definition: c.h:997
uint64_t uint64
Definition: c.h:539
uint32_t uint32
Definition: c.h:538
size_t Size
Definition: c.h:610
void ConditionVariableInit(ConditionVariable *cv)
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
int NBuffers
Definition: globals.c:142
ProcNumber MyProcNumber
Definition: globals.c:90
int MaxBackends
Definition: globals.c:146
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:4337
@ PGC_S_DYNAMIC_DEFAULT
Definition: guc.h:114
@ PGC_S_OVERRIDE
Definition: guc.h:123
@ PGC_POSTMASTER
Definition: guc.h:74
Assert(PointerIsAligned(start, uint64))
static void dclist_push_tail(dclist_head *head, dlist_node *node)
Definition: ilist.h:709
static void dclist_init(dclist_head *head)
Definition: ilist.h:671
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:337
i
int i
Definition: isn.c:77
@ B_IO_WORKER
Definition: miscadmin.h:363
BackendType MyBackendType
Definition: miscinit.c:64
static char * buf
Definition: pg_test_fsync.c:72
#define snprintf
Definition: port.h:239
#define NUM_AUXILIARY_PROCS
Definition: proc.h:463
Size add_size(Size s1, Size s2)
Definition: shmem.c:493
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:387
PGPROC * MyProc
Definition: proc.c:66
size_t(* shmem_size)(void)
Definition: aio_internal.h:277
void(* shmem_init)(bool first_time)
Definition: aio_internal.h:283
void(* init_backend)(void)
Definition: aio_internal.h:288
uint32 io_handle_off
Definition: aio_internal.h:194
dclist_head in_flight_ios
Definition: aio_internal.h:225
dclist_head idle_ios
Definition: aio_internal.h:197
PgAioHandle * staged_ios[PGAIO_SUBMIT_BATCH_SIZE]
Definition: aio_internal.h:215
uint32 iovec_count
Definition: aio_internal.h:239
struct iovec * iovecs
Definition: aio_internal.h:240
PgAioHandle * io_handles
Definition: aio_internal.h:252
uint32 io_handle_count
Definition: aio_internal.h:251
uint64 * handle_data
Definition: aio_internal.h:249
PgAioBackend * backend_state
Definition: aio_internal.h:232
struct ResourceOwnerData * resowner
Definition: aio_internal.h:148
int32 owner_procno
Definition: aio_internal.h:131
PgAioResult distilled_result
Definition: aio_internal.h:162
dlist_node node
Definition: aio_internal.h:146
uint8 handle_data_len
Definition: aio_internal.h:128
PgAioReturn * report_return
Definition: aio_internal.h:177
uint32 iovec_off
Definition: aio_internal.h:170
uint64 generation
Definition: aio_internal.h:152
uint8 flags
Definition: aio_internal.h:114
uint8 num_callbacks
Definition: aio_internal.h:116
ConditionVariable cv
Definition: aio_internal.h:159
uint32 status
Definition: aio_types.h:108

AltStyle によって変換されたページ (->オリジナル) /