[Tarantool-patches] [PATCH 3/3] small: sanitized rlist, bug in lsregion, and new region API

Cyrill Gorcunov gorcunov at gmail.com
Fri Sep 11 14:24:31 MSK 2020


Backport of commit ffec9e40d8695bffe76109b721b1050db84b384e,
I've to update all region_alloc_array calls to use fuber()->gc
as there was no txn->region yet.

Rlist used a hack to implement offsetof() leading to crash under
undefined behaviour clang sanitizer. It was fixed in this update.

Additionally, region_alloc_object() is changed to return the used
size and a new macro region_alloc_array() is added. This small
API change is supposed to simplify switching lots of region
allocations to aligned versions in scope of #4609.

And finally - there was a bug in lsregion, when allocation was
exactly of slab size. It is fixed in small's master.

Part-of #4609
Part-of #5060

Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
 src/box/memtx_engine.c      |  9 +++++----
 src/box/txn.c               | 23 +++++++++++++----------
 src/box/vy_write_iterator.c |  7 +++++--
 src/lib/small               |  2 +-
 4 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c
index e52397976..cc5bacc28 100644
--- a/src/box/memtx_engine.c
+++ b/src/box/memtx_engine.c
@@ -650,10 +650,10 @@ checkpoint_add_space(struct space *sp, void *data)
 		return 0;
 	struct checkpoint *ckpt = (struct checkpoint *)data;
 	struct checkpoint_entry *entry;
-	entry = region_alloc_object(&fiber()->gc, struct checkpoint_entry);
+	int size;
+	entry = region_alloc_object(&fiber()->gc, struct checkpoint_entry, &size);
 	if (entry == NULL) {
-		diag_set(OutOfMemory, sizeof(*entry),
-			 "region", "struct checkpoint_entry");
+		diag_set(OutOfMemory, sizeof(*entry), "region", "checkpoint_entry");
 		return -1;
 	}
 	rlist_add_tail_entry(&ckpt->entries, entry, link);
@@ -715,7 +715,8 @@ memtx_engine_begin_checkpoint(struct engine *engine)
 	struct memtx_engine *memtx = (struct memtx_engine *)engine;
 
 	assert(memtx->checkpoint == NULL);
-	memtx->checkpoint = region_alloc_object(&fiber()->gc, struct checkpoint);
+	int size;
+	memtx->checkpoint = region_alloc_object(&fiber()->gc, struct checkpoint, &size);
 	if (memtx->checkpoint == NULL) {
 		diag_set(OutOfMemory, sizeof(*memtx->checkpoint),
 			 "region", "struct checkpoint");
diff --git a/src/box/txn.c b/src/box/txn.c
index 4823ec0df..4cf107d45 100644
--- a/src/box/txn.c
+++ b/src/box/txn.c
@@ -48,10 +48,10 @@ txn_add_redo(struct txn_stmt *stmt, struct request *request)
 {
 	/* Create a redo log row for Lua requests */
 	struct xrow_header *row;
-	row = region_alloc_object(&fiber()->gc, struct xrow_header);
+	int size;
+	row = region_alloc_object(&fiber()->gc, struct xrow_header, &size);
 	if (row == NULL) {
-		diag_set(OutOfMemory, sizeof(*row),
-			 "region", "struct xrow_header");
+		diag_set(OutOfMemory, size, "region_alloc_object", "row");
 		return -1;
 	}
 	if (request->header != NULL) {
@@ -85,10 +85,10 @@ static struct txn_stmt *
 txn_stmt_new(struct txn *txn)
 {
 	struct txn_stmt *stmt;
-	stmt = region_alloc_object(&fiber()->gc, struct txn_stmt);
+	int size;
+	stmt = region_alloc_object(&fiber()->gc, struct txn_stmt, &size);
 	if (stmt == NULL) {
-		diag_set(OutOfMemory, sizeof(*stmt),
-			 "region", "struct txn_stmt");
+		diag_set(OutOfMemory, size, "region_alloc_object", "stmt");
 		return NULL;
 	}
 
@@ -141,9 +141,10 @@ txn_begin(bool is_autocommit)
 {
 	static int64_t txn_id = 0;
 	assert(! in_txn());
-	struct txn *txn = region_alloc_object(&fiber()->gc, struct txn);
+	int size;
+	struct txn *txn = region_alloc_object(&fiber()->gc, struct txn, &size);
 	if (txn == NULL) {
-		diag_set(OutOfMemory, sizeof(*txn), "region", "struct txn");
+		diag_set(OutOfMemory, size, "region_alloc_object", "txn");
 		return NULL;
 	}
 	/* Initialize members explicitly to save time on memset() */
@@ -512,12 +513,14 @@ box_txn_savepoint()
 		diag_set(ClientError, ER_SAVEPOINT_NO_TRANSACTION);
 		return NULL;
 	}
+	int size;
 	struct txn_savepoint *svp =
 		(struct txn_savepoint *) region_alloc_object(&fiber()->gc,
-							struct txn_savepoint);
+							struct txn_savepoint,
+							&size);
 	if (svp == NULL) {
 		diag_set(OutOfMemory, sizeof(*svp),
-			 "region", "struct txn_savepoint");
+			 "region_alloc_object", "txn_savepoint");
 		return NULL;
 	}
 	svp->stmt = stailq_last(&txn->stmts);
diff --git a/src/box/vy_write_iterator.c b/src/box/vy_write_iterator.c
index 41ef7d04b..2150b172b 100644
--- a/src/box/vy_write_iterator.c
+++ b/src/box/vy_write_iterator.c
@@ -100,9 +100,12 @@ static inline struct vy_write_history *
 vy_write_history_new(struct tuple *tuple, struct vy_write_history *next)
 {
 	struct vy_write_history *h;
-	h = region_alloc_object(&fiber()->gc, struct vy_write_history);
-	if (h == NULL)
+	int size;
+	h = region_alloc_object(&fiber()->gc, struct vy_write_history, &size);
+	if (h == NULL) {
+		diag_set(OutOfMemory, size, "region_alloc_object", "h");
 		return NULL;
+	}
 	h->tuple = tuple;
 	assert(next == NULL || (next->tuple != NULL &&
 	       vy_stmt_lsn(next->tuple) > vy_stmt_lsn(tuple)));
diff --git a/src/lib/small b/src/lib/small
index 2fb5cf230..fcac155db 160000
--- a/src/lib/small
+++ b/src/lib/small
@@ -1 +1 @@
-Subproject commit 2fb5cf2303956175fd13b738c34d622499efb11b
+Subproject commit fcac155dba18e97b10bc668d1a2fae01184adc13
-- 
2.26.2



More information about the Tarantool-patches mailing list