PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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"
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 "storage/subsystems.h"
27#include "utils/guc.h"
28
29
30static void AioShmemRequest(void *arg);
31static void AioShmemInit(void *arg);
32static void AioShmemAttach(void *arg);
33
36 .init_fn = AioShmemInit,
37 .attach_fn = AioShmemAttach,
38};
39
44
45static uint32
47{
48 /*
49 * While AIO workers don't need their own AIO context, we can't currently
50 * guarantee that nothing gets assigned to an IO worker's ProcNumber if we
51 * just subtracted MAX_IO_WORKERS.
52 */
54}
55
56static Size
58{
59 return mul_size(AioProcs(), sizeof(PgAioBackend));
60}
61
62static Size
64{
65 Size sz;
66
67 /* verify AioChooseMaxConcurrency() did its thing */
69
70 /* io handles */
73
74 return sz;
75}
76
77static Size
79{
80 /* each IO handle can have up to io_max_combine_limit iovec objects */
81 return mul_size(sizeof(struct iovec),
84}
85
86static Size
88{
89 /* each buffer referenced by an iovec can have associated data */
90 return mul_size(sizeof(uint64),
93}
94
95/*
96 * Choose a suitable value for io_max_concurrency.
97 *
98 * It's unlikely that we could have more IOs in flight than buffers that we
99 * would be allowed to pin.
100 *
101 * On the upper end, apply a cap too - just because shared_buffers is large,
102 * it doesn't make sense have millions of buffers undergo IO concurrently.
103 */
104static int
106{
109
110 /* Similar logic to LimitAdditionalPins() */
113
115
116 /* apply upper limit */
117 return Min(max_proportional_pins, 64);
118}
119
120/*
121 * Register AIO subsystem's shared memory needs.
122 */
123static void
125{
126 /*
127 * Resolve io_max_concurrency if not already done
128 *
129 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
130 * However, if the DBA explicitly set io_max_concurrency = -1 in the
131 * config file, then PGC_S_DYNAMIC_DEFAULT will fail to override that and
132 * we must force the matter with PGC_S_OVERRIDE.
133 */
134 if (io_max_concurrency == -1)
135 {
136 char buf[32];
137
138 snprintf(buf, sizeof(buf), "%d", AioChooseMaxConcurrency());
139 SetConfigOption("io_max_concurrency", buf, PGC_POSTMASTER,
141 if (io_max_concurrency == -1) /* failed to apply it? */
142 SetConfigOption("io_max_concurrency", buf, PGC_POSTMASTER,
144 }
145
146 ShmemRequestStruct(.name = "AioCtl",
147 .size = sizeof(PgAioCtl),
148 .ptr = (void **) &pgaio_ctl,
149 );
150
151 ShmemRequestStruct(.name = "AioBackend",
152 .size = AioBackendShmemSize(),
153 .ptr = (void **) &AioBackendShmemPtr,
154 );
155
156 ShmemRequestStruct(.name = "AioHandle",
157 .size = AioHandleShmemSize(),
158 .ptr = (void **) &AioHandleShmemPtr,
159 );
160
161 ShmemRequestStruct(.name = "AioHandleIOV",
162 .size = AioHandleIOVShmemSize(),
163 .ptr = (void **) &AioHandleIOVShmemPtr,
164 );
165
166 ShmemRequestStruct(.name = "AioHandleData",
167 .size = AioHandleDataShmemSize(),
168 .ptr = (void **) &AioHandleDataShmemPtr,
169 );
170
173}
174
175/*
176 * Initialize AIO shared memory during postmaster startup.
177 */
178static void
180{
181 uint32 io_handle_off = 0;
182 uint32 iovec_off = 0;
184
187
192
193 for (int procno = 0; procno < AioProcs(); procno++)
194 {
196
197 bs->io_handle_off = io_handle_off;
198 io_handle_off += io_max_concurrency;
199
200 dclist_init(&bs->idle_ios);
201 memset(bs->staged_ios, 0, sizeof(PgAioHandle *) * PGAIO_SUBMIT_BATCH_SIZE);
202 dclist_init(&bs->in_flight_ios);
203
204 /* initialize per-backend IOs */
205 for (int i = 0; i < io_max_concurrency; i++)
206 {
207 PgAioHandle *ioh = &pgaio_ctl->io_handles[bs->io_handle_off + i];
208
209 ioh->generation = 1;
210 ioh->owner_procno = procno;
211 ioh->iovec_off = iovec_off;
212 ioh->handle_data_len = 0;
213 ioh->report_return = NULL;
214 ioh->resowner = NULL;
215 ioh->num_callbacks = 0;
216 ioh->distilled_result.status = PGAIO_RS_UNKNOWN;
217 ioh->flags = 0;
218
220
221 dclist_push_tail(&bs->idle_ios, &ioh->node);
222 iovec_off += io_max_combine_limit;
223 }
224 }
225
228}
229
230static void
236
237void
239{
240 /* shouldn't be initialized twice */
242
244 return;
245
246 if (MyProc == NULL || MyProcNumber >= AioProcs())
247 elog(ERROR, "aio requires a normal PGPROC");
248
250
253
255}
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:96
void pgaio_shutdown(int code, Datum arg)
Definition aio.c:1298
const ShmemCallbacks AioShmemCallbacks
Definition aio_init.c:34
static PgAioHandle * AioHandleShmemPtr
Definition aio_init.c:41
static Size AioHandleIOVShmemSize(void)
Definition aio_init.c:78
void pgaio_init_backend(void)
Definition aio_init.c:238
static Size AioHandleDataShmemSize(void)
Definition aio_init.c:87
static Size AioHandleShmemSize(void)
Definition aio_init.c:63
static struct iovec * AioHandleIOVShmemPtr
Definition aio_init.c:42
static void AioShmemAttach(void *arg)
Definition aio_init.c:231
static uint64 * AioHandleDataShmemPtr
Definition aio_init.c:43
static Size AioBackendShmemSize(void)
Definition aio_init.c:57
static PgAioBackend * AioBackendShmemPtr
Definition aio_init.c:40
static void AioShmemInit(void *arg)
Definition aio_init.c:179
static int AioChooseMaxConcurrency(void)
Definition aio_init.c:105
static uint32 AioProcs(void)
Definition aio_init.c:46
static void AioShmemRequest(void *arg)
Definition aio_init.c:124
#define PGAIO_SUBMIT_BATCH_SIZE
@ PGAIO_RS_UNKNOWN
Definition aio_types.h:80
int io_max_combine_limit
Definition bufmgr.c:217
#define Min(x, y)
Definition c.h:1091
#define Max(x, y)
Definition c.h:1085
#define Assert(condition)
Definition c.h:943
uint64_t uint64
Definition c.h:625
uint32_t uint32
Definition c.h:624
size_t Size
Definition c.h:689
void ConditionVariableInit(ConditionVariable *cv)
Datum arg
Definition elog.c:1322
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:227
int NBuffers
Definition globals.c:144
ProcNumber MyProcNumber
Definition globals.c:92
int MaxBackends
Definition globals.c:149
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition guc.c:4234
@ PGC_S_DYNAMIC_DEFAULT
Definition guc.h:114
@ PGC_S_OVERRIDE
Definition guc.h:123
@ PGC_POSTMASTER
Definition guc.h:74
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:344
int i
Definition isn.c:77
@ B_IO_WORKER
Definition miscadmin.h:376
BackendType MyBackendType
Definition miscinit.c:65
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define snprintf
Definition port.h:260
static int fb(int x)
#define NUM_AUXILIARY_PROCS
Definition proc.h:527
Size mul_size(Size s1, Size s2)
Definition shmem.c:1063
#define ShmemRequestStruct(...)
Definition shmem.h:176
PGPROC * MyProc
Definition proc.c:71
void(* init_backend)(void)
ShmemCallbacks shmem_callbacks
uint32 io_handle_off
uint32 iovec_count
struct iovec * iovecs
PgAioHandle * io_handles
uint32 io_handle_count
uint64 * handle_data
PgAioBackend * backend_state
uint64 generation
ShmemRequestCallback request_fn
Definition shmem.h:133
ShmemInitCallback init_fn
Definition shmem.h:139
void * opaque_arg
Definition shmem.h:153
ShmemAttachCallback attach_fn
Definition shmem.h:147
const char * name