Skip to content

CDRIVER-2813 remove BSON_EXTRA_ALIGNMENT option #1942

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

Merged
merged 12 commits into from
Mar 21, 2025

Conversation

kevinAlbs
Copy link
Collaborator

@kevinAlbs kevinAlbs commented Mar 20, 2025

Summary

  • Remove CMake option ENABLE_EXTRA_ALIGNMENT.
  • Align bson_t and bson_iter_t to the size of a pointer.

Verified with this patch build: https://spruce.mongodb.com/version/67dc0db1caab950007b0f764

Motivation

Addresses long-standing ask to remove default over-alignment: CDRIVER-2813.

Removing alignment specifiers entirely was considered. However, removing the alignment specifier on bson_t resulted in a runtime error in calls to BSON_ALIGNED_ALLOC (bson_t):

Failure to allocate memory in bson_aligned_alloc()

I expect this is due to bson_t having alignment of 4. bson_t does not contain a pointer.

From man aligned_alloc (emphasis mine):

In addition, aligned_alloc() returns a NULL pointer and sets errno to EINVAL if size is not an integral multiple of alignment, or if alignment is not a power of 2 at least as large as sizeof(void *).

To limit the risk of causing runtime errors in user upgrades, this PR proposes keeping existing alignment specifiers. Only the over-alignment of bson_t and bson_iter_t is changed.

Alignment changes

The following were printed on my 64-bit machine to compare alignment changes.

Prior to this PR. With ENABLE_EXTRA_ALIGNMENT=ON:

alignof(bson_t):           128
alignof(bson_iter_t):      128
alignof(bson_visitor_t):   8
alignof(bson_reader_t):    8
alignof(bson_value_t):     8
alignof(bson_error_t):     8

With all alignment specifiers removed (not done in this PR):

alignof(bson_t):           4
alignof(bson_iter_t):      8
alignof(bson_visitor_t):   8
alignof(bson_reader_t):    4
alignof(bson_value_t):     8
alignof(bson_error_t):     4

With this PR:

alignof(bson_t):           8
alignof(bson_iter_t):      8
alignof(bson_visitor_t):   8
alignof(bson_reader_t):    8
alignof(bson_value_t):     8
alignof(bson_error_t):     8

@kevinAlbs kevinAlbs marked this pull request as ready for review March 20, 2025 15:42
@@ -120,11 +120,11 @@ typedef struct _bson_json_opts_t bson_json_opts_t;
*
* This structure is meant to fit in two sequential 64-byte cachelines.
*/
BSON_ALIGNED_BEGIN (128) typedef struct _bson_t {
BSON_ALIGNED_BEGIN (BSON_ALIGN_OF_PTR) typedef struct _bson_t {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we instead fix bson_aligned_alloc to increase the alignment size if it is below pointer alignment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am concerned removing the alignment specifier could break existing code allocating without libbson functions. Example:

bson_t *b = aligned_alloc (alignof(bson_t), sizeof(bson_t));

Upgrading to 2.0 may make this a runtime error. Maybe (hopefully) it is unlikely. I see no usage on GitHub code search for align.*bson_t. Though there is use of malloc.*bson_t.

AFAIK types being aligned to a pointer size (or 8) is less of an issue. If there is little observed benefit, it might not be worth the risk (even if small).

Copy link
Contributor

Choose a reason for hiding this comment

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

Polymorphic types such as bson_t and bson_reader_t require a pointer alignment specifier in their "base" type due to pointer data members in their "derived" types (bson_impl_alloc_t and bson_reader_handle_t respectively). The alignment specifier is probably preferable to awkwardly inserting a stub pointer data member in the "base" type.

Copy link
Contributor

@eramongodb eramongodb left a comment

Choose a reason for hiding this comment

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

Suggest also removing the debug-compile-no-align tasks from the legacy config.

kevinAlbs and others added 7 commits March 20, 2025 15:20
Co-authored-by: Ezra Chung <88335979+eramongodb@users.noreply.github.com>
Not needed. Type aleady contains pointers.
Add a static assert to ensure that `bson_t` and the implementations have matching alignment.
Already has a pointer type.
Copy link
Contributor

@vector-of-bool vector-of-bool left a comment

Choose a reason for hiding this comment

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

LGTM

@eramongodb
Copy link
Contributor

Note: partially reverting mongodb/mongo-cxx-driver#1329 (reverting only the addition and use of bsoncxx::aligned_storage<T>) reveals a single benign warning when compiled with MSVC and /W4 (analogous to -Wpadded warnings for GCC and Clang):

warning C4324: 'bsoncxx::v_noabi::builder::core::impl::frame': structure was padded due to alignment specifier

Runtime alignment errors are not observed when running C++ Driver UBSan tasks with the partial revert using the changes in this PR branch. 👍

@kevinAlbs kevinAlbs merged commit f1e2b54 into mongodb:master Mar 21, 2025
40 of 42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants