Use one spinlock to access v2 and mmap related data (#20202)
Stelios Fragkakis committed
Apr 29, 2025 at 23:45 UTC
91f2ef1bdb8bceec06565f5501719278cb48bdc0
2 files changed
+21
-42
src/database/engine/journalfile.c
+20
-39
@@ -198,7 +198,7 @@ static void njfv2idx_remove(struct rrdengine_datafile *datafile) {
198
static struct journal_v2_header *journalfile_v2_mounted_data_get(struct rrdengine_journalfile *journalfile, size_t *data_size) {
199
struct journal_v2_header *j2_header = NULL;
200
201
- spinlock_lock(&journalfile->mmap.spinlock);
201
+ spinlock_lock(&journalfile->data_spinlock);
202
203
if(!journalfile->mmap.data) {
204
journalfile->mmap.data = nd_mmap(NULL, journalfile->mmap.size, PROT_READ, MAP_SHARED, journalfile->mmap.fd, 0);
@@ -209,9 +209,7 @@ static struct journal_v2_header *journalfile_v2_mounted_data_get(struct rrdengin
209
journalfile->mmap.data = NULL;
210
journalfile->mmap.size = 0;
211
212
- spinlock_lock(&journalfile->v2.spinlock);
212
journalfile->v2.flags &= ~(JOURNALFILE_FLAG_IS_AVAILABLE | JOURNALFILE_FLAG_IS_MOUNTED);
214
- spinlock_unlock(&journalfile->v2.spinlock);
213
214
ctx_fs_error(datafile_ctx(journalfile->datafile));
215
}
@@ -223,10 +221,8 @@ static struct journal_v2_header *journalfile_v2_mounted_data_get(struct rrdengin
221
// madvise_dontneed(journalfile->mmap.data, journalfile->mmap.size);
222
madvise_random(journalfile->mmap.data, journalfile->mmap.size);
223
226
- spinlock_lock(&journalfile->v2.spinlock);
224
journalfile->v2.flags |= JOURNALFILE_FLAG_IS_AVAILABLE | JOURNALFILE_FLAG_IS_MOUNTED;
225
JOURNALFILE_FLAGS flags = journalfile->v2.flags;
229
- spinlock_unlock(&journalfile->v2.spinlock);
226
227
if(flags & JOURNALFILE_FLAG_MOUNTED_FOR_RETENTION) {
228
// we need the entire metrics directory into memory to process it
@@ -242,7 +238,7 @@ static struct journal_v2_header *journalfile_v2_mounted_data_get(struct rrdengin
238
*data_size = journalfile->mmap.size;
239
}
240
245
- spinlock_unlock(&journalfile->mmap.spinlock);
241
+ spinlock_unlock(&journalfile->data_spinlock);
242
243
return j2_header;
244
}
@@ -252,20 +248,11 @@ static bool journalfile_v2_mounted_data_unmount(struct rrdengine_journalfile *jo
248
249
if(!have_locks) {
250
if(!wait) {
255
- if (!spinlock_trylock(&journalfile->mmap.spinlock))
251
+ if (!spinlock_trylock(&journalfile->data_spinlock))
252
return false;
253
}
254
else
259
- spinlock_lock(&journalfile->mmap.spinlock);
260
-
261
- if(!wait) {
262
- if(!spinlock_trylock(&journalfile->v2.spinlock)) {
263
- spinlock_unlock(&journalfile->mmap.spinlock);
264
- return false;
265
- }
266
- }
267
- else
268
- spinlock_lock(&journalfile->v2.spinlock);
255
+ spinlock_lock(&journalfile->data_spinlock);
256
}
257
258
if(!journalfile->v2.refcount) {
@@ -288,8 +275,7 @@ static bool journalfile_v2_mounted_data_unmount(struct rrdengine_journalfile *jo
275
}
276
277
if(!have_locks) {
291
- spinlock_unlock(&journalfile->v2.spinlock);
292
- spinlock_unlock(&journalfile->mmap.spinlock);
278
+ spinlock_unlock(&journalfile->data_spinlock);
279
}
280
281
return unmounted;
@@ -309,7 +295,7 @@ void journalfile_v2_data_unmount_cleanup(time_t now_s) {
295
for (datafile = ctx->datafiles.first; datafile; datafile = datafile->next) {
296
struct rrdengine_journalfile *journalfile = datafile->journalfile;
297
312
- if(!spinlock_trylock(&journalfile->v2.spinlock))
298
+ if(!spinlock_trylock(&journalfile->data_spinlock))
299
continue;
300
301
bool unmount = false;
@@ -324,7 +310,7 @@ void journalfile_v2_data_unmount_cleanup(time_t now_s) {
310
// enough time has passed since we last needed this journal
311
unmount = true;
312
}
327
- spinlock_unlock(&journalfile->v2.spinlock);
313
+ spinlock_unlock(&journalfile->data_spinlock);
314
315
if (unmount)
316
journalfile_v2_mounted_data_unmount(journalfile, false, false);
@@ -334,7 +320,7 @@ void journalfile_v2_data_unmount_cleanup(time_t now_s) {
320
}
321
322
ALWAYS_INLINE struct journal_v2_header *journalfile_v2_data_acquire(struct rrdengine_journalfile *journalfile, size_t *data_size, time_t wanted_first_time_s, time_t wanted_last_time_s) {
337
- spinlock_lock(&journalfile->v2.spinlock);
323
+ spinlock_lock(&journalfile->data_spinlock);
324
325
bool has_data = (journalfile->v2.flags & JOURNALFILE_FLAG_IS_AVAILABLE);
326
bool is_mounted = (journalfile->v2.flags & JOURNALFILE_FLAG_IS_MOUNTED);
@@ -356,7 +342,7 @@ ALWAYS_INLINE struct journal_v2_header *journalfile_v2_data_acquire(struct rrden
342
343
}
344
}
359
- spinlock_unlock(&journalfile->v2.spinlock);
345
+ spinlock_unlock(&journalfile->data_spinlock);
346
347
if(do_we_need_it)
348
return journalfile_v2_mounted_data_get(journalfile, data_size);
@@ -365,7 +351,7 @@ ALWAYS_INLINE struct journal_v2_header *journalfile_v2_data_acquire(struct rrden
351
}
352
353
ALWAYS_INLINE void journalfile_v2_data_release(struct rrdengine_journalfile *journalfile) {
368
- spinlock_lock(&journalfile->v2.spinlock);
354
+ spinlock_lock(&journalfile->data_spinlock);
355
356
internal_fatal(!journalfile->mmap.data, "trying to release a journalfile without data");
357
internal_fatal(journalfile->v2.refcount < 1, "trying to release a non-acquired journalfile");
@@ -380,7 +366,7 @@ ALWAYS_INLINE void journalfile_v2_data_release(struct rrdengine_journalfile *jou
366
if(journalfile->v2.flags & JOURNALFILE_FLAG_MOUNTED_FOR_RETENTION)
367
unmount = true;
368
}
383
- spinlock_unlock(&journalfile->v2.spinlock);
369
+ spinlock_unlock(&journalfile->data_spinlock);
370
371
if(unmount)
372
journalfile_v2_mounted_data_unmount(journalfile, false, true);
@@ -388,18 +374,18 @@ ALWAYS_INLINE void journalfile_v2_data_release(struct rrdengine_journalfile *jou
374
375
bool journalfile_v2_data_available(struct rrdengine_journalfile *journalfile) {
376
391
- spinlock_lock(&journalfile->v2.spinlock);
377
+ spinlock_lock(&journalfile->data_spinlock);
378
bool has_data = (journalfile->v2.flags & JOURNALFILE_FLAG_IS_AVAILABLE);
393
- spinlock_unlock(&journalfile->v2.spinlock);
379
+ spinlock_unlock(&journalfile->data_spinlock);
380
381
return has_data;
382
}
383
384
size_t journalfile_v2_data_size_get(struct rrdengine_journalfile *journalfile) {
385
400
- spinlock_lock(&journalfile->mmap.spinlock);
386
+ spinlock_lock(&journalfile->data_spinlock);
387
size_t data_size = journalfile->mmap.size;
402
- spinlock_unlock(&journalfile->mmap.spinlock);
388
+ spinlock_unlock(&journalfile->data_spinlock);
389
390
return data_size;
391
}
@@ -411,8 +397,7 @@ void journalfile_v2_data_set(struct rrdengine_journalfile *journalfile, int fd,
397
if(unlikely(!journalfile->datafile))
398
fatal("DBENGINE: JOURNALFILE: trying to set journal data without a datafile");
399
414
- spinlock_lock(&journalfile->mmap.spinlock);
415
- spinlock_lock(&journalfile->v2.spinlock);
400
+ spinlock_lock(&journalfile->data_spinlock);
401
402
internal_fatal(journalfile->mmap.fd != -1, "DBENGINE JOURNALFILE: trying to re-set journal fd");
403
internal_fatal(journalfile->mmap.data, "DBENGINE JOURNALFILE: trying to re-set journal_data");
@@ -431,8 +416,7 @@ void journalfile_v2_data_set(struct rrdengine_journalfile *journalfile, int fd,
416
417
journalfile_v2_mounted_data_unmount(journalfile, true, true);
418
434
- spinlock_unlock(&journalfile->v2.spinlock);
435
- spinlock_unlock(&journalfile->mmap.spinlock);
419
+ spinlock_unlock(&journalfile->data_spinlock);
420
421
njfv2idx_add(journalfile->datafile);
422
}
@@ -446,8 +430,7 @@ static void journalfile_v2_data_unmap_permanently(struct rrdengine_journalfile *
430
if (has_references)
431
sleep_usec(10 * USEC_PER_MS);
432
449
- spinlock_lock(&journalfile->mmap.spinlock);
450
- spinlock_lock(&journalfile->v2.spinlock);
433
+ spinlock_lock(&journalfile->data_spinlock);
434
435
if(journalfile_v2_mounted_data_unmount(journalfile, true, true)) {
436
if(journalfile->mmap.fd != -1)
@@ -465,8 +448,7 @@ static void journalfile_v2_data_unmap_permanently(struct rrdengine_journalfile *
448
internal_error(true, "DBENGINE JOURNALFILE: waiting for journalfile to be available to unmap...");
449
}
450
468
- spinlock_unlock(&journalfile->v2.spinlock);
469
- spinlock_unlock(&journalfile->mmap.spinlock);
451
+ spinlock_unlock(&journalfile->data_spinlock);
452
453
} while(has_references);
454
}
@@ -475,8 +457,7 @@ struct rrdengine_journalfile *journalfile_alloc_and_init(struct rrdengine_datafi
457
{
458
struct rrdengine_journalfile *journalfile = callocz(1, sizeof(struct rrdengine_journalfile));
459
journalfile->datafile = datafile;
478
- spinlock_init(&journalfile->mmap.spinlock);
479
- spinlock_init(&journalfile->v2.spinlock);
460
+ spinlock_init(&journalfile->data_spinlock);
461
spinlock_init(&journalfile->unsafe.spinlock);
462
journalfile->mmap.fd = -1;
463
datafile->journalfile = journalfile;
src/database/engine/journalfile.h
+1
-3
@@ -23,17 +23,15 @@ typedef enum __attribute__ ((__packed__)) {
23
JOURNALFILE_FLAG_METRIC_CRC_CHECK = (1 << 3),
24
} JOURNALFILE_FLAGS;
25
26
-/* only one event loop is supported for now */
26
struct rrdengine_journalfile {
27
+ SPINLOCK data_spinlock;
28
struct {
29
- SPINLOCK spinlock;
29
void *data; // MMAPed file of journal v2
30
uint32_t size; // Total file size mapped
31
int fd;
32
} mmap;
33
34
struct {
36
- SPINLOCK spinlock;
35
JOURNALFILE_FLAGS flags;
36
int32_t refcount;
37
time_t first_time_s;