Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

obj: handle ENOMEM during vector allocations #5537

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/libpmemobj/memops.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2016-2022, Intel Corporation */
/* Copyright 2016-2023, Intel Corporation */

/*
* memops.c -- aggregated memory operations helper implementation
Expand Down Expand Up @@ -590,7 +590,7 @@ operation_user_buffer_verify_align(struct operation_context *ctx,
/*
* operation_add_user_buffer -- add user buffer to the ulog
*/
void
int
operation_add_user_buffer(struct operation_context *ctx,
struct user_buffer_def *userbuf)
{
Expand All @@ -614,9 +614,11 @@ operation_add_user_buffer(struct operation_context *ctx,
last_log->next = buffer_offset;
pmemops_persist(ctx->p_ops, &last_log->next, next_size);

VEC_PUSH_BACK(&ctx->next, buffer_offset);
if (VEC_PUSH_BACK(&ctx->next, buffer_offset) != 0)
return -1;
ctx->ulog_capacity += capacity;
operation_set_any_user_buffer(ctx, 1);
return 0;
}

/*
Expand Down
4 changes: 2 additions & 2 deletions src/libpmemobj/memops.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* Copyright 2016-2020, Intel Corporation */
/* Copyright 2016-2023, Intel Corporation */

/*
* memops.h -- aggregated memory operations helper definitions
Expand Down Expand Up @@ -63,7 +63,7 @@ int operation_add_typed_entry(struct operation_context *ctx,
ulog_operation_type type, enum operation_log_type log_type);
int operation_user_buffer_verify_align(struct operation_context *ctx,
struct user_buffer_def *userbuf);
void operation_add_user_buffer(struct operation_context *ctx,
int operation_add_user_buffer(struct operation_context *ctx,
struct user_buffer_def *userbuf);
void operation_set_auto_reserve(struct operation_context *ctx,
int auto_reserve);
Expand Down
5 changes: 3 additions & 2 deletions src/libpmemobj/recycler.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2016-2021, Intel Corporation */
/* Copyright 2016-2023, Intel Corporation */

/*
* recycler.c -- implementation of run recycler
Expand Down Expand Up @@ -274,7 +274,8 @@ recycler_recalc(struct recycler *r, int force)
if (VEC_PUSH_BACK(&runs, nm) != 0)
ASSERT(0); /* XXX: fix after refactoring */
} else {
VEC_PUSH_BACK(&r->recalc, e);
if (VEC_PUSH_BACK(&r->recalc, e) != 0)
ASSERT(0); /* XXX: fix after refactoring */
}
} while (found_units < search_limit);

Expand Down
19 changes: 14 additions & 5 deletions src/libpmemobj/tx.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2015-2021, Intel Corporation */
/* Copyright 2015-2023, Intel Corporation */

/*
* tx.c -- transactions implementation
Expand Down Expand Up @@ -194,7 +194,8 @@ tx_action_add(struct tx *tx)
if (tx_action_reserve(tx, 1) != 0)
return NULL;

VEC_INC_BACK(&tx->actions);
if (VEC_INC_BACK(&tx->actions) == -1)
return NULL;

return &VEC_BACK(&tx->actions);
}
Expand Down Expand Up @@ -710,7 +711,8 @@ tx_construct_user_buffer(struct tx *tx, void *addr, size_t size,
tx->redo_userbufs_capacity +=
userbuf.size - TX_INTENT_LOG_BUFFER_OVERHEAD;
} else {
operation_add_user_buffer(ctx, &userbuf);
if (operation_add_user_buffer(ctx, &userbuf) == -1)
goto err;
}

return 0;
Expand Down Expand Up @@ -1013,8 +1015,11 @@ pmemobj_tx_commit(void)
operation_start(tx->lane->external);

struct user_buffer_def *userbuf;
struct operation_context *ctx = tx->lane->external;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like I indicated earlier in the issue, I don't think we need to check for this error here. Instead, we simply need to ensure that the operation_add_user_buffer never fails (like you've already done in tx_construct_user_buffer).

To have the FATAL/ASSERT that you added you can change the operation_add_user_buffer to return an error (-1) if VEC_PUSH_BACK(&ctx->next, buffer_offset); fails. This would let you avoid making all the memops structs public.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure to fully follow your reasoning, but anyway I will try to push a new commit based on what I think I have understood...

VEC_FOREACH_BY_PTR(userbuf, &tx->redo_userbufs)
operation_add_user_buffer(tx->lane->external, userbuf);
if (operation_add_user_buffer(ctx, userbuf) == -1)
FATAL("%s: failed to allocate a next vector",
__func__);

palloc_publish(&pop->heap, VEC_ARR(&tx->actions),
VEC_SIZE(&tx->actions), tx->lane->external);
Expand Down Expand Up @@ -1921,7 +1926,11 @@ pmemobj_tx_xpublish(struct pobj_action *actv, size_t actvcnt, uint64_t flags)
}

for (size_t i = 0; i < actvcnt; ++i) {
VEC_PUSH_BACK(&tx->actions, actv[i]);
if (VEC_PUSH_BACK(&tx->actions, actv[i]) != 0) {
int ret = obj_tx_fail_err(ENOMEM, flags);
PMEMOBJ_API_END();
return ret;
}
}

PMEMOBJ_API_END();
Expand Down
10 changes: 7 additions & 3 deletions src/libpmemobj/ulog.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2015-2021, Intel Corporation */
/* Copyright 2015-2023, Intel Corporation */

/*
* ulog.c -- unified log implementation
Expand Down Expand Up @@ -225,7 +225,9 @@ ulog_rebuild_next_vec(struct ulog *ulog, struct ulog_next *next,
{
do {
if (ulog->next != 0)
VEC_PUSH_BACK(next, ulog->next);
if (VEC_PUSH_BACK(next, ulog->next) != 0)
FATAL("%s: failed to allocate a next vector",
__func__);
} while ((ulog = ulog_next(ulog, p_ops)) != NULL);
}

Expand Down Expand Up @@ -257,7 +259,9 @@ ulog_reserve(struct ulog *ulog,
while (capacity < *new_capacity) {
if (extend(p_ops->base, &ulog->next, gen_num) != 0)
return -1;
VEC_PUSH_BACK(next, ulog->next);
if (VEC_PUSH_BACK(next, ulog->next) != 0)
FATAL("%s: failed to allocate a next vector",
__func__);
ulog = ulog_next(ulog, p_ops);
ASSERTne(ulog, NULL);

Expand Down