From 7788fea203b6ca8d791e7f13979d68e9aa8fb57b Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Wed, 15 Jul 2026 14:13:53 +0800 Subject: [PATCH] DAOS-18690 vos: fix engine crash when extend committed DTX table PR#18141 (b36dd7b0691) introduced some regression: When the pool is physically full (ENOSPC), extending committed DTX table for punch/update commit may crash the whole engine with SIGABRT. That is because the backend TX logic (such as PMDK) will abort the TX by default if hit failure when allocation. Then subsequent operation (such as tx_add_ptr that is triggered by vos_dtx_extend_cmt_table()) against such aborted backend TX will trigger assertion inside backend TX logic. The patch replaces umem_zalloc() with umem_alloc_verb() for extending committed DTX table with new UMEM_FLAG_NO_ABORT flag that will notify backend TX logic to return ENOSPC without aborted related TX. Similar enhancement is also added for tx_add_ptr related logic. New unit tests (UMEM010/BMEM016/BMEM024) for that. Signed-off-by: Fan Yong Co-authored-by: hgichon --- src/common/mem.c | 85 +++++++++++-------------------- src/common/tests/btree.c | 5 +- src/common/tests/btree_direct.c | 5 +- src/common/tests/umem_test.c | 16 +++++- src/common/tests/umem_test_bmem.c | 17 ++++++- src/common/tests/utest_common.c | 60 ++++++++++++++++++++++ src/common/tests/utest_common.h | 9 ++++ src/dtx/tests/dts_aggregate.c | 9 ++++ src/include/daos/mem.h | 34 +++---------- src/vos/tests/evt_ctl.c | 4 +- src/vos/vos_dtx.c | 61 +++++++++------------- src/vos/vos_gc.c | 2 +- src/vos/vos_internal.h | 4 +- 13 files changed, 179 insertions(+), 132 deletions(-) diff --git a/src/common/mem.c b/src/common/mem.c index f64d744be72..8dd7254bca3 100644 --- a/src/common/mem.c +++ b/src/common/mem.c @@ -806,6 +806,8 @@ pmem_tx_alloc(struct umem_instance *umm, size_t size, uint64_t flags, unsigned i pflags |= POBJ_FLAG_ZERO; if (flags & UMEM_FLAG_NO_FLUSH) pflags |= POBJ_FLAG_NO_FLUSH; + if (flags & UMEM_FLAG_NO_ABORT) + pflags |= POBJ_FLAG_TX_NO_ABORT; return umem_id2off(umm, pmemobj_tx_xalloc(size, type_num, pflags)); } @@ -828,6 +830,8 @@ pmem_tx_xadd(struct umem_instance *umm, umem_off_t umoff, uint64_t offset, if (flags & UMEM_XADD_NO_SNAPSHOT) pflags |= POBJ_XADD_NO_SNAPSHOT; + if (flags & UMEM_FLAG_NO_ABORT) + pflags |= POBJ_FLAG_TX_NO_ABORT; rc = pmemobj_tx_xadd_range(umem_off2id(umm, umoff), offset, size, pflags); @@ -997,39 +1001,6 @@ pmem_defer_free(struct umem_instance *umm, umem_off_t off, void *act) pmemobj_defer_free(pop, id, (struct pobj_action *)act); } -static void -pmem_tx_set_failure_behavior(enum umem_tx_failure_behavior behavior) -{ - switch (behavior) { - case TX_FAILURE_ABORT: - pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_ABORT); - break; - case TX_FAILURE_RETURN: - pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN); - break; - default: - D_ASSERTF(0, "Unknown TX failure behavior %d\n", behavior); - } -} - -static int -pmem_tx_get_failure_behavior(void) -{ - enum pobj_tx_failure_behavior behavior; - - behavior = pmemobj_tx_get_failure_behavior(); - - switch (behavior) { - case POBJ_TX_FAILURE_ABORT: - return TX_FAILURE_ABORT; - case POBJ_TX_FAILURE_RETURN: - return TX_FAILURE_RETURN; - default: - D_ASSERTF(0, "Unknown TX failure behavior %d\n", behavior); - return -DER_INVAL; - } -} - static int pmem_tx_set_snapbuf(struct umem_instance *umm, umem_off_t snapbuf, size_t size) { @@ -1179,27 +1150,25 @@ umem_tx_add_cb(struct umem_instance *umm, struct umem_tx_stage_data *txd, } static umem_ops_t pmem_ops = { - .mo_tx_free = pmem_tx_free, - .mo_tx_alloc = pmem_tx_alloc, - .mo_tx_add = pmem_tx_add, - .mo_tx_xadd = pmem_tx_xadd, - .mo_tx_add_ptr = pmem_tx_add_ptr, - .mo_tx_abort = pmem_tx_abort, - .mo_tx_begin = pmem_tx_begin, - .mo_tx_commit = pmem_tx_commit, - .mo_tx_set_failure_behavior = pmem_tx_set_failure_behavior, - .mo_tx_get_failure_behavior = pmem_tx_get_failure_behavior, - .mo_tx_set_snapbuf = pmem_tx_set_snapbuf, - .mo_tx_stage = pmem_tx_stage, - .mo_reserve = pmem_reserve, - .mo_defer_free = pmem_defer_free, - .mo_cancel = pmem_cancel, - .mo_tx_publish = pmem_tx_publish, - .mo_atomic_copy = pmem_atomic_copy, - .mo_atomic_alloc = pmem_atomic_alloc, - .mo_atomic_free = pmem_atomic_free, - .mo_atomic_flush = pmem_atomic_flush, - .mo_tx_add_callback = umem_tx_add_cb, + .mo_tx_free = pmem_tx_free, + .mo_tx_alloc = pmem_tx_alloc, + .mo_tx_add = pmem_tx_add, + .mo_tx_xadd = pmem_tx_xadd, + .mo_tx_add_ptr = pmem_tx_add_ptr, + .mo_tx_abort = pmem_tx_abort, + .mo_tx_begin = pmem_tx_begin, + .mo_tx_commit = pmem_tx_commit, + .mo_tx_set_snapbuf = pmem_tx_set_snapbuf, + .mo_tx_stage = pmem_tx_stage, + .mo_reserve = pmem_reserve, + .mo_defer_free = pmem_defer_free, + .mo_cancel = pmem_cancel, + .mo_tx_publish = pmem_tx_publish, + .mo_atomic_copy = pmem_atomic_copy, + .mo_atomic_alloc = pmem_atomic_alloc, + .mo_atomic_free = pmem_atomic_free, + .mo_atomic_flush = pmem_atomic_flush, + .mo_tx_add_callback = umem_tx_add_cb, }; /** BMEM operations (depends on dav) */ @@ -1244,6 +1213,8 @@ bmem_tx_alloc(struct umem_instance *umm, size_t size, uint64_t flags, unsigned i pflags |= DAV_FLAG_ZERO; if (flags & UMEM_FLAG_NO_FLUSH) pflags |= DAV_FLAG_NO_FLUSH; + if (flags & UMEM_FLAG_NO_ABORT) + pflags |= DAV_FLAG_TX_NO_ABORT; return dav_tx_xalloc(size, type_num, pflags); } @@ -1266,6 +1237,8 @@ bmem_tx_xadd(struct umem_instance *umm, umem_off_t umoff, uint64_t offset, if (flags & UMEM_XADD_NO_SNAPSHOT) pflags |= DAV_XADD_NO_SNAPSHOT; + if (flags & UMEM_FLAG_NO_ABORT) + pflags |= DAV_FLAG_TX_NO_ABORT; rc = dav_tx_xadd_range(umem_off2offset(umoff), size, pflags); return rc ? umem_tx_errno(rc) : 0; @@ -1483,6 +1456,8 @@ bmem_tx_alloc_v2(struct umem_instance *umm, size_t size, uint64_t flags, unsigne pflags |= DAV_FLAG_ZERO; if (flags & UMEM_FLAG_NO_FLUSH) pflags |= DAV_FLAG_NO_FLUSH; + if (flags & UMEM_FLAG_NO_ABORT) + pflags |= DAV_FLAG_TX_NO_ABORT; if (mbkt_id != 0) pflags |= DAV_EZONE_ID(mbkt_id); return dav_tx_alloc_v2(size, type_num, pflags); @@ -1507,6 +1482,8 @@ bmem_tx_xadd_v2(struct umem_instance *umm, umem_off_t umoff, uint64_t offset, if (flags & UMEM_XADD_NO_SNAPSHOT) pflags |= DAV_XADD_NO_SNAPSHOT; + if (flags & UMEM_FLAG_NO_ABORT) + pflags |= DAV_FLAG_TX_NO_ABORT; rc = dav_tx_xadd_range_v2(umem_off2offset(umoff), size, pflags); return rc ? umem_tx_errno(rc) : 0; diff --git a/src/common/tests/btree.c b/src/common/tests/btree.c index c60c0bdebc8..05eddec9fe1 100644 --- a/src/common/tests/btree.c +++ b/src/common/tests/btree.c @@ -1,6 +1,6 @@ /** * (C) Copyright 2016-2022 Intel Corporation. - * (C) Copyright 2025 Hewlett Packard Enterprise Development LP + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -69,8 +69,7 @@ struct btr_test_state { }; #define IK_TREE_CLASS 100 -#define POOL_NAME "/mnt/daos/btree-test" -#define POOL_SIZE ((1024 * 1024 * 1024ULL)) +#define POOL_NAME "/mnt/daos/btree-test" /** customized functions for btree */ static int diff --git a/src/common/tests/btree_direct.c b/src/common/tests/btree_direct.c index d399bbd1681..bf24c83d272 100644 --- a/src/common/tests/btree_direct.c +++ b/src/common/tests/btree_direct.c @@ -1,6 +1,6 @@ /** * (C) Copyright 2018-2022 Intel Corporation. - * (C) Copyright 2025 Hewlett Packard Enterprise Development LP + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -55,8 +55,7 @@ struct btr_test_state { }; #define SK_TREE_CLASS 100 -#define POOL_NAME "/mnt/daos/btree-direct-test" -#define POOL_SIZE ((1024 * 1024 * 1024ULL)) +#define POOL_NAME "/mnt/daos/btree-direct-test" #define SK_ORDER_DEF 16 diff --git a/src/common/tests/umem_test.c b/src/common/tests/umem_test.c index 6080843f51c..b916c96a9f9 100644 --- a/src/common/tests/umem_test.c +++ b/src/common/tests/umem_test.c @@ -1,5 +1,6 @@ /** * (C) Copyright 2019-2024 Intel Corporation. + * (C) Copyright 2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -27,7 +28,6 @@ #include #include "utest_common.h" -#define POOL_SIZE ((1024 * 1024 * 1024ULL)) #define MAX_CHUNKS 8192 struct chunk { @@ -207,7 +207,7 @@ teardown_pmem(void **state) return rc; } -int +static int setup_pmem(void **state) { struct test_arg *arg = *state; @@ -749,6 +749,16 @@ test_p2_evict(void **state) umem_cache_free(&arg->ta_store); } +static void +test_tx_fail_no_abort(void **state) +{ + struct test_arg *arg = *state; + int rc; + + rc = utest_tx_fail_no_abort(arg->ta_utx); + assert_int_equal(rc, 0); +} + int main(int argc, char **argv) { @@ -762,6 +772,8 @@ main(int argc, char **argv) {"UMEM007: Test page cache many writes", test_many_writes, NULL, NULL}, {"UMEM008: Test phase2 APIs", test_p2_basic, NULL, NULL}, {"UMEM009: Test phase2 eviction", test_p2_evict, NULL, NULL}, + {"UMEM010: Test TX failure with NO_ABORT on pmem", test_tx_fail_no_abort, setup_pmem, + teardown_pmem}, {NULL, NULL, NULL, NULL}}; d_register_alt_assert(mock_assert); diff --git a/src/common/tests/umem_test_bmem.c b/src/common/tests/umem_test_bmem.c index a62fe3814a4..7d6442c6c28 100644 --- a/src/common/tests/umem_test_bmem.c +++ b/src/common/tests/umem_test_bmem.c @@ -1,6 +1,6 @@ /** * (C) Copyright 2019-2024 Intel Corporation. - * (C) Copyright 2023-2025 Hewlett Packard Enterprise Development LP. + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -28,7 +28,6 @@ #include #include "utest_common.h" -#define POOL_SIZE ((256 * 1024 * 1024ULL)) #define NEMB_RATIO (0.8) #define MB_SIZE (16 * 1024 * 1024) @@ -2669,6 +2668,16 @@ test_umempobj_heap_mb_stats(void **state) D_FREE(name); } +static void +test_tx_fail_no_abort(void **state) +{ + struct test_arg *arg = *state; + int rc; + + rc = utest_tx_fail_no_abort(arg->ta_utx); + assert_int_equal(rc, 0); +} + int main(int argc, char **argv) { @@ -2702,6 +2711,8 @@ main(int argc, char **argv) teardown_pmem}, {"BMEM015a: Test tx defer free publish/cancel", test_tx_bucket_dfree_publish_cancel, setup_pmem, teardown_pmem}, + {"BMEM016: Test TX failure with NO_ABORT on bmem", test_tx_fail_no_abort, setup_pmem, + teardown_pmem}, {NULL, NULL, NULL, NULL}}; static const struct CMUnitTest v2_tests[] = { @@ -2747,6 +2758,8 @@ main(int argc, char **argv) NULL}, {"BMEM022: Test umempobj non_evictable MB usage", test_umempobj_nemb_usage, NULL, NULL}, {"BMEM023: Test umempobj get MB stats", test_umempobj_heap_mb_stats, NULL, NULL}, + {"BMEM024: Test TX failure with NO_ABORT on bmem_v2", test_tx_fail_no_abort, + setup_pmem_v2, teardown_pmem}, {NULL, NULL, NULL, NULL}}; rc = daos_debug_init(DAOS_LOG_DEFAULT); diff --git a/src/common/tests/utest_common.c b/src/common/tests/utest_common.c index 472039c74a8..1c9d52d0c6a 100644 --- a/src/common/tests/utest_common.c +++ b/src/common/tests/utest_common.c @@ -1,5 +1,6 @@ /** * (C) Copyright 2019-2023 Intel Corporation. + * (C) Copyright 2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -375,3 +376,62 @@ utest_check_mem_initial_status(struct utest_context *utx) } return 0; } + +/* + * A failed allocation with UMEM_FLAG_NO_ABORT must leave the transaction + * alive so in-tx fallbacks (e.g. vos_dtx_reuse_cmt_blob) keep working; + * if without the flag, the failure aborts the TX and any further tx_add + * is a fatal usage error in the allocator. + */ +int +utest_tx_fail_no_abort(struct utest_context *utx) +{ + struct umem_instance *umm = utest_utx2umm(utx); + int *value; + umem_off_t umoff = UMOFF_NULL; + umem_off_t huge; + int rc; + + rc = utest_tx_begin(utx); + if (rc != 0) + goto done; + + /* Larger than the pool: must fail, but must NOT abort the TX */ + huge = umem_alloc_verb(umm, UMEM_FLAG_ZERO | UMEM_FLAG_NO_ABORT, POOL_SIZE, + UMEM_DEFAULT_MBKT_ID); + if (!UMOFF_IS_NULL(huge)) { + D_ERROR("huge allocation unexpectedly succeeded\n"); + D_GOTO(end, rc = 1); + } + + /* TX still alive: alloc + snapshot + write must all work */ + umoff = umem_zalloc(umm, 4); + if (UMOFF_IS_NULL(umoff)) { + D_ERROR("small alloc failed after NO_ABORT failure\n"); + D_GOTO(end, rc = 2); + } + + value = umem_off2ptr(umm, umoff); + + rc = umem_tx_xadd_ptr(umm, value, (uint64_t)(-2), UMEM_FLAG_NO_ABORT); + if (rc == 0) { + D_ERROR("large sized add_ptr() should fail\n"); + D_GOTO(end, rc = 3); + } + + rc = umem_tx_add_ptr(umm, value, 4); + if (rc != 0) { + D_ERROR("tx_add_ptr failed after NO_ABORT failure\n"); + D_GOTO(end, rc = 4); + } + + *value = 42; + + rc = umem_free(umm, umoff); + +end: + rc = utest_tx_end(utx, rc); + +done: + return rc; +} diff --git a/src/common/tests/utest_common.h b/src/common/tests/utest_common.h index 2fd3328234e..71e7826e768 100644 --- a/src/common/tests/utest_common.h +++ b/src/common/tests/utest_common.h @@ -1,11 +1,13 @@ /** * (C) Copyright 2019-2021 Intel Corporation. + * (C) Copyright 2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ #include #define UTEST_POOL_NAME_MAX 255 +#define POOL_SIZE (1024 * 1024 * 1024ULL) struct utest_context; @@ -174,3 +176,10 @@ int utest_check_mem_increase(struct utest_context *utx); */ int utest_check_mem_initial_status(struct utest_context *utx); +/** Check transaction failure with NO_ABROT flag + * \param utx[IN] utest_context + * + * \return 0 on success + */ +int +utest_tx_fail_no_abort(struct utest_context *utx); diff --git a/src/dtx/tests/dts_aggregate.c b/src/dtx/tests/dts_aggregate.c index 89a8db7bacf..4eebd13a321 100644 --- a/src/dtx/tests/dts_aggregate.c +++ b/src/dtx/tests/dts_aggregate.c @@ -156,6 +156,14 @@ tx_add_ptr(struct umem_instance *umm, void *ptr, size_t ptr_size) return mock_type(int); } +static int +tx_xadd(struct umem_instance *umm, umem_off_t umoff, uint64_t offset, size_t size, uint64_t flags) +{ + void *ptr = umem_off2ptr(umm, umoff); + + return tx_add_ptr(umm, ptr, size); +} + static int tx_free(struct umem_instance *umm, umem_off_t umoff) { @@ -227,6 +235,7 @@ static umem_ops_t umm_ops = {.mo_tx_begin = tx_begin, .mo_tx_commit = tx_commit, .mo_tx_abort = tx_abort, .mo_tx_add_ptr = tx_add_ptr, + .mo_tx_xadd = tx_xadd, .mo_tx_free = tx_free}; static int diff --git a/src/include/daos/mem.h b/src/include/daos/mem.h index eb4bdbf3552..2f798dc0327 100644 --- a/src/include/daos/mem.h +++ b/src/include/daos/mem.h @@ -190,11 +190,6 @@ struct umem_pool { struct umem_slab_desc up_slabs[0]; }; -enum umem_tx_failure_behavior { - TX_FAILURE_ABORT, - TX_FAILURE_RETURN, -}; - #ifdef DAOS_PMEM_BUILD #define UMEM_CACHE_PAGE_SZ_SHIFT 24 /* 16MB */ #define UMEM_CACHE_PAGE_SZ (1 << UMEM_CACHE_PAGE_SZ_SHIFT) @@ -682,6 +677,13 @@ struct umem_instance; #define UMEM_FLAG_NO_FLUSH (((uint64_t)1) << 1) #define UMEM_XADD_NO_SNAPSHOT (((uint64_t)1) << 2) +/* + * Do NOT abort current TX if failed to operate (such as allocation) something under current + * transaction context, instead, return some errno# to the caller who can handle the failure + * and further use such TX. + */ +#define UMEM_FLAG_NO_ABORT (((uint64_t)1) << 3) + /* Macros associated with Memory buckets */ #define UMEM_DEFAULT_MBKT_ID 0 @@ -755,11 +757,6 @@ typedef struct { /** commit memory transaction */ int (*mo_tx_commit)(struct umem_instance *umm, void *data); - /** set TX_FAILURE_ABORT or TX_FAILURE_RETURN when hit failure during TX. */ - void (*mo_tx_set_failure_behavior)(enum umem_tx_failure_behavior behavior); - - /** query the failure behavior for current TX. */ - int (*mo_tx_get_failure_behavior)(void); #ifdef DAOS_PMEM_BUILD /** Set emergency buffer for transaction snapshot */ int (*mo_tx_set_snapbuf)(struct umem_instance *umm, umem_off_t snap_buf, size_t size); @@ -1086,23 +1083,6 @@ umem_tx_end(struct umem_instance *umm, int err) return umem_tx_end_ex(umm, err, NULL); } -static inline void -umem_tx_set_failure_behavior(struct umem_instance *umm, enum umem_tx_failure_behavior behavior) -{ - if (umm->umm_ops->mo_tx_set_failure_behavior) - umm->umm_ops->mo_tx_set_failure_behavior(behavior); -} - -static inline int -umem_tx_get_failure_behavior(struct umem_instance *umm) -{ - if (umm->umm_ops->mo_tx_get_failure_behavior) - return umm->umm_ops->mo_tx_get_failure_behavior(); - else - /* Abort TX on failure by default. */ - return TX_FAILURE_ABORT; -} - #ifdef DAOS_PMEM_BUILD bool umem_tx_inprogress(struct umem_instance *umm); bool umem_tx_none(struct umem_instance *umm); diff --git a/src/vos/tests/evt_ctl.c b/src/vos/tests/evt_ctl.c index 6fc061aba6f..14e27866f65 100644 --- a/src/vos/tests/evt_ctl.c +++ b/src/vos/tests/evt_ctl.c @@ -1,6 +1,7 @@ /** * (C) Copyright 2017-2023 Intel Corporation. * (C) Copyright 2026 Google LLC + * (C) Copyright 2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -76,8 +77,7 @@ static daos_handle_t ts_toh; #define D_1M_SIZE (1024 * 1024) #define D_256M_SIZE (256 * 1024 * 1024) -#define POOL_NAME "/mnt/daos/evtree-utest" -#define POOL_SIZE ((1024 * 1024 * 1024ULL)) +#define POOL_NAME "/mnt/daos/evtree-utest" struct test_arg { struct utest_context *ta_utx; diff --git a/src/vos/vos_dtx.c b/src/vos/vos_dtx.c index a7e830bff7a..24223a51eae 100644 --- a/src/vos/vos_dtx.c +++ b/src/vos/vos_dtx.c @@ -434,14 +434,12 @@ vos_dtx_add_ptr(struct vos_pool *pool, void *ptr, size_t size) struct umem_instance *umm = &pool->vp_umm; int rc; - rc = umem_tx_add_ptr(umm, ptr, size); + rc = umem_tx_xadd_ptr(umm, ptr, size, UMEM_FLAG_NO_ABORT); #ifdef DAOS_PMEM_BUILD if (unlikely(rc == -DER_NOSPACE)) { - struct vos_pool_ext_df *ext_df = umem_off2ptr(umm, pool->vp_pool_df->pd_ext); - int behavior = umem_tx_get_failure_behavior(umm); + struct vos_pool_ext_df *ext_df = umem_off2ptr(umm, pool->vp_pool_df->pd_ext); - if (ext_df != NULL && !UMOFF_IS_NULL(ext_df->ped_emerg_buf) && - behavior == TX_FAILURE_RETURN) { + if (ext_df != NULL && !UMOFF_IS_NULL(ext_df->ped_emerg_buf)) { rc = umem_tx_set_snapbuf(umm, ext_df->ped_emerg_buf, VOS_SNAPBUF_EMERG_SIZE); if (rc == 0) @@ -474,18 +472,19 @@ vos_dtx_table_register(void) } int -vos_dtx_table_destroy(struct umem_instance *umm, struct vos_cont_df *cont_df) +vos_dtx_table_destroy(struct vos_pool *pool, struct vos_cont_df *cont_df) { - struct vos_dtx_blob_df *dbd; - struct vos_dtx_act_ent_df *dae_df; - umem_off_t dbd_off; - int i; - int rc; + struct umem_instance *umm = &pool->vp_umm; + struct vos_dtx_blob_df *dbd; + struct vos_dtx_act_ent_df *dae_df; + umem_off_t dbd_off; + int i; + int rc; /* cd_dtx_committed_tail is next to cd_dtx_committed_head */ - rc = umem_tx_add_ptr(umm, &cont_df->cd_dtx_committed_head, + rc = vos_dtx_add_ptr(pool, &cont_df->cd_dtx_committed_head, sizeof(cont_df->cd_dtx_committed_head) + - sizeof(cont_df->cd_dtx_committed_tail)); + sizeof(cont_df->cd_dtx_committed_tail)); if (rc != 0) return rc; @@ -505,7 +504,7 @@ vos_dtx_table_destroy(struct umem_instance *umm, struct vos_cont_df *cont_df) cont_df->cd_dtx_committed_tail = UMOFF_NULL; /* cd_dtx_active_tail is next to cd_dtx_active_head */ - rc = umem_tx_add_ptr(umm, &cont_df->cd_dtx_active_head, + rc = vos_dtx_add_ptr(pool, &cont_df->cd_dtx_active_head, sizeof(cont_df->cd_dtx_active_head) + sizeof(cont_df->cd_dtx_active_tail)); if (rc != 0) @@ -1018,7 +1017,7 @@ vos_dtx_extend_act_table(struct vos_container *cont) D_ASSERT(UMOFF_IS_NULL(cont_df->cd_dtx_active_head)); /* cd_dtx_active_tail is next to cd_dtx_active_head */ - rc = vos_dtx_add_ptr(cont->vc_pool, &cont_df->cd_dtx_active_head, + rc = umem_tx_add_ptr(umm, &cont_df->cd_dtx_active_head, sizeof(cont_df->cd_dtx_active_head) + sizeof(cont_df->cd_dtx_active_tail)); if (rc != 0) @@ -1026,14 +1025,14 @@ vos_dtx_extend_act_table(struct vos_container *cont) cont_df->cd_dtx_active_head = dbd_off; } else { - rc = vos_dtx_add_ptr(cont->vc_pool, &tmp->dbd_next, sizeof(tmp->dbd_next)); + rc = umem_tx_add_ptr(umm, &tmp->dbd_next, sizeof(tmp->dbd_next)); if (rc != 0) goto out; tmp->dbd_next = dbd_off; dbd->dbd_prev = cont_df->cd_dtx_active_tail; - rc = vos_dtx_add_ptr(cont->vc_pool, &cont_df->cd_dtx_active_tail, + rc = umem_tx_add_ptr(umm, &cont_df->cd_dtx_active_tail, sizeof(cont_df->cd_dtx_active_tail)); if (rc != 0) goto out; @@ -1294,7 +1293,8 @@ vos_dtx_extend_cmt_table(struct vos_container *cont) int rc; if (!DAOS_FAIL_CHECK(DAOS_DTX_NOSPACE_NOREFRESH)) - dbd_off = umem_zalloc(umm, DTX_CMT_BLOB_SIZE); + dbd_off = umem_alloc_verb(umm, UMEM_FLAG_ZERO | UMEM_FLAG_NO_ABORT, + DTX_CMT_BLOB_SIZE, UMEM_DEFAULT_MBKT_ID); if (UMOFF_IS_NULL(dbd_off)) return vos_dtx_reuse_cmt_blob(cont); @@ -2598,7 +2598,8 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id dtis[], if (!allocated) { rc = umem_tx_xadd_ptr(umm, &dbd->dbd_committed_data[dbd->dbd_count], sizeof(struct vos_dtx_cmt_ent_df) * - (j - dbd->dbd_count), UMEM_XADD_NO_SNAPSHOT); + (j - dbd->dbd_count), + UMEM_XADD_NO_SNAPSHOT | UMEM_FLAG_NO_ABORT); if (rc != 0) goto out; @@ -2903,18 +2904,6 @@ dtx_commit_pin(struct vos_container *cont, struct dtx_id dtis[], int count, int return rc; } -static inline int -vos_dtx_begin_with_behavior(struct umem_instance *umm) -{ - int rc; - - rc = umem_tx_begin(umm, NULL); - if (rc == 0) - umem_tx_set_failure_behavior(umm, TX_FAILURE_RETURN); - - return rc; -} - int vos_dtx_commit(daos_handle_t coh, struct dtx_id dtis[], int count, bool keep_act, bool rm_cos[]) { @@ -2949,7 +2938,7 @@ vos_dtx_commit(daos_handle_t coh, struct dtx_id dtis[], int count, bool keep_act count -= pinned; /* Commit multiple DTXs via single local transaction. */ - rc = vos_dtx_begin_with_behavior(vos_cont2umm(cont)); + rc = umem_tx_begin(vos_cont2umm(cont), NULL); if (rc == 0) { committed = vos_dtx_commit_internal(cont, &dtis[idx], pinned, 0, keep_act, rm_cos != NULL ? &rm_cos[idx] : NULL, @@ -3020,7 +3009,7 @@ vos_dtx_abort_internal(struct vos_container *cont, struct vos_dtx_act_ent *dae, goto out; umm = vos_cont2umm(cont); - rc = vos_dtx_begin_with_behavior(umm); + rc = umem_tx_begin(umm, NULL); if (rc != 0) goto out; @@ -3313,7 +3302,7 @@ vos_dtx_set_flags_one(struct vos_container *cont, struct dtx_id *dti, uint32_t f dae_df = umem_off2ptr(umm, dae->dae_df_off); D_ASSERT(dae_df != NULL); - rc = vos_dtx_add_ptr(cont->vc_pool, &dae_df->dae_flags, sizeof(dae_df->dae_flags)); + rc = umem_tx_add_ptr(umm, &dae_df->dae_flags, sizeof(dae_df->dae_flags)); if (rc == 0) { dae_df->dae_flags |= flags; DAE_FLAGS(dae) |= flags; @@ -3348,7 +3337,7 @@ vos_dtx_set_flags(daos_handle_t coh, struct dtx_id dtis[], int count, uint32_t f } umm = vos_cont2umm(cont); - rc = vos_dtx_begin_with_behavior(umm); + rc = umem_tx_begin(umm, NULL); if (rc != 0) goto out; @@ -3383,7 +3372,7 @@ dtx_blob_aggregate(struct umem_instance *umm, struct vos_tls *tls, struct vos_co goto out; } - rc = vos_dtx_begin_with_behavior(umm); + rc = umem_tx_begin(umm, NULL); if (unlikely(rc != 0)) { D_ERROR("Failed to TX begin for DTX aggregation " UMOFF_PF ": " DF_RC "\n", UMOFF_P(dbd_off), DP_RC(rc)); diff --git a/src/vos/vos_gc.c b/src/vos/vos_gc.c index 8e1cb8790d0..2c4e54e11bb 100644 --- a/src/vos/vos_gc.c +++ b/src/vos/vos_gc.c @@ -307,7 +307,7 @@ gc_drain_cont(struct vos_gc *gc, struct vos_pool *pool, daos_handle_t coh, * Then destroy DTX table firstly to avoid dangling DXT records during drain * the container (that may yield). */ - rc = vos_dtx_table_destroy(&pool->vp_umm, cont); + rc = vos_dtx_table_destroy(pool, cont); if (rc != 0) { DL_ERROR(rc, "Failed to destroy DTX table."); return rc; diff --git a/src/vos/vos_internal.h b/src/vos/vos_internal.h index 9959b429361..6832f9a2334 100644 --- a/src/vos/vos_internal.h +++ b/src/vos/vos_internal.h @@ -725,13 +725,13 @@ vos_obj_tab_register(); * DTX table destroy * Called from vos_cont_destroy * - * \param umm [IN] Instance of an unified memory class. + * \param pool [IN] The pool that holds the container. * \param cont_df [IN] Pointer to the on-disk VOS container. * * \return 0 on success and negative on failure. */ int -vos_dtx_table_destroy(struct umem_instance *umm, struct vos_cont_df *cont_df); +vos_dtx_table_destroy(struct vos_pool *pool, struct vos_cont_df *cont_df); /** * Register dbtree class for DTX table.