Add "fsync disabled" mode

blocking-uring-test
Vitaliy Filippov 2019-11-30 23:55:30 +03:00
parent 76655929c4
commit 00eeedae90
7 changed files with 77 additions and 44 deletions

View File

@ -38,7 +38,6 @@
#define ST_D_SUBMITTED 16 #define ST_D_SUBMITTED 16
#define ST_D_WRITTEN 17 #define ST_D_WRITTEN 17
#define ST_D_SYNCED 18
#define ST_D_META_WRITTEN 19 #define ST_D_META_WRITTEN 19
#define ST_D_META_SYNCED 20 #define ST_D_META_SYNCED 20
#define ST_D_STABLE 21 #define ST_D_STABLE 21
@ -271,6 +270,7 @@ class blockstore
uint64_t data_offset, data_size, data_len; uint64_t data_offset, data_size, data_len;
bool readonly = false; bool readonly = false;
bool disable_fsync = false;
struct journal_t journal; struct journal_t journal;
journal_flusher_t *flusher; journal_flusher_t *flusher;

View File

@ -6,7 +6,6 @@ journal_flusher_t::journal_flusher_t(int flusher_count, blockstore *bs)
this->flusher_count = flusher_count; this->flusher_count = flusher_count;
active_flushers = 0; active_flushers = 0;
active_until_sync = 0; active_until_sync = 0;
sync_required = true;
sync_threshold = flusher_count == 1 ? 1 : flusher_count/2; sync_threshold = flusher_count == 1 ? 1 : flusher_count/2;
journal_trim_interval = sync_threshold; journal_trim_interval = sync_threshold;
journal_trim_counter = 0; journal_trim_counter = 0;
@ -378,7 +377,7 @@ resume_0:
} }
v.clear(); v.clear();
flusher->active_until_sync--; flusher->active_until_sync--;
if (flusher->sync_required) if (!bs->disable_fsync)
{ {
// And sync everything (in batches - not per each operation!) // And sync everything (in batches - not per each operation!)
cur_sync = flusher->syncs.end(); cur_sync = flusher->syncs.end();

View File

@ -50,7 +50,6 @@ class journal_flusher_t
{ {
int flusher_count; int flusher_count;
int sync_threshold; int sync_threshold;
bool sync_required;
journal_flusher_co *co; journal_flusher_co *co;
blockstore *bs; blockstore *bs;
friend class journal_flusher_co; friend class journal_flusher_co;

View File

@ -232,11 +232,14 @@ resume_1:
data->callback = simple_callback; data->callback = simple_callback;
my_uring_prep_writev(sqe, bs->journal.fd, &data->iov, 1, bs->journal.offset); my_uring_prep_writev(sqe, bs->journal.fd, &data->iov, 1, bs->journal.offset);
wait_count++; wait_count++;
GET_SQE(); if (!bs->disable_fsync)
my_uring_prep_fsync(sqe, bs->journal.fd, IORING_FSYNC_DATASYNC); {
data->iov = { 0 }; GET_SQE();
data->callback = simple_callback; my_uring_prep_fsync(sqe, bs->journal.fd, IORING_FSYNC_DATASYNC);
wait_count++; data->iov = { 0 };
data->callback = simple_callback;
wait_count++;
}
printf("Resetting journal\n"); printf("Resetting journal\n");
bs->ringloop->submit(); bs->ringloop->submit();
resume_4: resume_4:
@ -309,11 +312,14 @@ resume_1:
data->callback = simple_callback; data->callback = simple_callback;
wait_count++; wait_count++;
my_uring_prep_writev(sqe, bs->journal.fd, &data->iov, 1, bs->journal.offset + init_write_sector); my_uring_prep_writev(sqe, bs->journal.fd, &data->iov, 1, bs->journal.offset + init_write_sector);
GET_SQE(); if (!bs->disable_fsync)
data->iov = { 0 }; {
data->callback = simple_callback; GET_SQE();
wait_count++; data->iov = { 0 };
my_uring_prep_fsync(sqe, bs->journal.fd, IORING_FSYNC_DATASYNC); data->callback = simple_callback;
wait_count++;
my_uring_prep_fsync(sqe, bs->journal.fd, IORING_FSYNC_DATASYNC);
}
bs->ringloop->submit(); bs->ringloop->submit();
resume_5: resume_5:
if (wait_count > 0) if (wait_count > 0)

View File

@ -6,6 +6,10 @@ void blockstore::calc_lengths(blockstore_config_t & config)
{ {
readonly = true; readonly = true;
} }
if (config["disable_fsync"] == "true" || config["disable_fsync"] == "1" || config["disable_fsync"] == "yes")
{
disable_fsync = true;
}
// data // data
data_len = data_size - data_offset; data_len = data_size - data_offset;
if (data_fd == meta_fd && data_offset < meta_offset) if (data_fd == meta_fd && data_offset < meta_offset)

View File

@ -39,28 +39,40 @@ int blockstore::continue_sync(blockstore_operation *op)
if (op->sync_state == SYNC_HAS_SMALL) if (op->sync_state == SYNC_HAS_SMALL)
{ {
// No big writes, just fsync the journal // No big writes, just fsync the journal
// FIXME: Add no-fsync mode if (!disable_fsync)
BS_SUBMIT_GET_SQE(sqe, data); {
my_uring_prep_fsync(sqe, journal.fd, IORING_FSYNC_DATASYNC); BS_SUBMIT_GET_SQE(sqe, data);
data->iov = { 0 }; my_uring_prep_fsync(sqe, journal.fd, IORING_FSYNC_DATASYNC);
data->callback = cb; data->iov = { 0 };
op->min_used_journal_sector = op->max_used_journal_sector = 0; data->callback = cb;
op->pending_ops = 1; op->min_used_journal_sector = op->max_used_journal_sector = 0;
op->sync_state = SYNC_JOURNAL_SYNC_SENT; op->pending_ops = 1;
op->sync_state = SYNC_JOURNAL_SYNC_SENT;
}
else
{
op->sync_state = SYNC_DONE;
}
} }
else if (op->sync_state == SYNC_HAS_BIG) else if (op->sync_state == SYNC_HAS_BIG)
{ {
// 1st step: fsync data // 1st step: fsync data
// FIXME: Add no-fsync mode if (!disable_fsync)
BS_SUBMIT_GET_SQE(sqe, data); {
my_uring_prep_fsync(sqe, data_fd, IORING_FSYNC_DATASYNC); BS_SUBMIT_GET_SQE(sqe, data);
data->iov = { 0 }; my_uring_prep_fsync(sqe, data_fd, IORING_FSYNC_DATASYNC);
data->callback = cb; data->iov = { 0 };
op->min_used_journal_sector = op->max_used_journal_sector = 0; data->callback = cb;
op->pending_ops = 1; op->min_used_journal_sector = op->max_used_journal_sector = 0;
op->sync_state = SYNC_DATA_SYNC_SENT; op->pending_ops = 1;
op->sync_state = SYNC_DATA_SYNC_SENT;
}
else
{
op->sync_state = SYNC_DATA_SYNC_DONE;
}
} }
else if (op->sync_state == SYNC_DATA_SYNC_DONE) if (op->sync_state == SYNC_DATA_SYNC_DONE)
{ {
// 2nd step: Data device is synced, prepare & write journal entries // 2nd step: Data device is synced, prepare & write journal entries
// Check space in the journal and journal memory buffers // Check space in the journal and journal memory buffers
@ -70,8 +82,8 @@ int blockstore::continue_sync(blockstore_operation *op)
return 0; return 0;
} }
// Get SQEs. Don't bother about merging, submit each journal sector as a separate request // Get SQEs. Don't bother about merging, submit each journal sector as a separate request
struct io_uring_sqe *sqe[space_check.sectors_required+1]; struct io_uring_sqe *sqe[space_check.sectors_required + (disable_fsync ? 0 : 1)];
for (int i = 0; i < space_check.sectors_required+1; i++) for (int i = 0; i < space_check.sectors_required + (disable_fsync ? 0 : 1); i++)
{ {
BS_SUBMIT_GET_SQE_DECL(sqe[i]); BS_SUBMIT_GET_SQE_DECL(sqe[i]);
} }
@ -103,11 +115,16 @@ int blockstore::continue_sync(blockstore_operation *op)
} }
op->max_used_journal_sector = 1 + journal.cur_sector; op->max_used_journal_sector = 1 + journal.cur_sector;
// ... And a journal fsync // ... And a journal fsync
my_uring_prep_fsync(sqe[s], journal.fd, IORING_FSYNC_DATASYNC); if (!disable_fsync)
struct ring_data_t *data = ((ring_data_t*)sqe[s]->user_data); {
data->iov = { 0 }; my_uring_prep_fsync(sqe[s], journal.fd, IORING_FSYNC_DATASYNC);
data->callback = cb; struct ring_data_t *data = ((ring_data_t*)sqe[s]->user_data);
op->pending_ops = 1 + s; data->iov = { 0 };
data->callback = cb;
op->pending_ops = 1 + s;
}
else
op->pending_ops = s;
op->sync_state = SYNC_JOURNAL_SYNC_SENT; op->sync_state = SYNC_JOURNAL_SYNC_SENT;
ringloop->submit(); ringloop->submit();
} }
@ -143,11 +160,6 @@ void blockstore::handle_sync_event(ring_data_t *data, blockstore_operation *op)
if (op->sync_state == SYNC_DATA_SYNC_SENT) if (op->sync_state == SYNC_DATA_SYNC_SENT)
{ {
op->sync_state = SYNC_DATA_SYNC_DONE; op->sync_state = SYNC_DATA_SYNC_DONE;
// FIXME: This is not needed, in fact
for (auto it = op->sync_big_writes.begin(); it != op->sync_big_writes.end(); it++)
{
dirty_db[*it].state = ST_D_SYNCED;
}
} }
else if (op->sync_state == SYNC_JOURNAL_SYNC_SENT) else if (op->sync_state == SYNC_JOURNAL_SYNC_SENT)
{ {

View File

@ -34,7 +34,7 @@ struct bs_data
struct bs_options struct bs_options
{ {
int __pad; int __pad;
char *data_device, *meta_device, *journal_device; char *data_device = NULL, *meta_device = NULL, *journal_device = NULL, *disable_fsync = NULL;
}; };
static struct fio_option options[] = { static struct fio_option options[] = {
@ -65,6 +65,15 @@ static struct fio_option options[] = {
.category = FIO_OPT_C_ENGINE, .category = FIO_OPT_C_ENGINE,
.group = FIO_OPT_G_FILENAME, .group = FIO_OPT_G_FILENAME,
}, },
{
.name = "disable_fsync",
.lname = "Disable fsync",
.type = FIO_OPT_STR_STORE,
.off1 = offsetof(struct bs_options, disable_fsync),
.help = "Disable fsyncs for blockstore (unsafe if your disk has cache)",
.category = FIO_OPT_C_ENGINE,
.group = FIO_OPT_G_FILENAME,
},
{ {
.name = NULL, .name = NULL,
}, },
@ -130,6 +139,10 @@ static int bs_init(struct thread_data *td)
config["journal_device"] = o->journal_device; config["journal_device"] = o->journal_device;
config["meta_device"] = o->meta_device; config["meta_device"] = o->meta_device;
config["data_device"] = o->data_device; config["data_device"] = o->data_device;
if (o->disable_fsync)
config["disable_fsync"] = o->disable_fsync;
if (read_only)
config["readonly"] = "true";
bsd->ringloop = new ring_loop_t(512); bsd->ringloop = new ring_loop_t(512);
bsd->bs = new blockstore(config, bsd->ringloop); bsd->bs = new blockstore(config, bsd->ringloop);
while (1) while (1)