pmemobj_tx_xadd_range ignores flags when merging ranges #1100
Comments
Indeed, this can be a problem for some applications. Fixing this may be challenging though because the tx_[x]add_range[_direct] implementation is quite complex and this new logic must be enabled only for the NO_FLUSH flag, making the implementation even more complex. (On master, we have a new flag which should not trigger this.) If you are going to fix this, please submit the PR against the stable-1.5 branch. From there the fix will be applied automatically to newer branches. |
To me, both NO_FLUSH and the new NO_SNAPSHOT flag seem more like performance optimization hints rather than behaviors which must be followed. Otherwise, what is the desired behavior when there are two tx_xadd_ranges[_direct] to the same address, one with NO_SNAPSHOT, and the other without it? |
NO_SNAPSHOT means "this buffer is not initialized, so do not snapshot it, but I may store to it, so please track it as part of the transaction (e.g. tell Valgrind pmemcheck about it) and flush it on commit". Next tx_add of the same region without NO_SNAPSHOT doesn't have to snapshot it. |
Okay, your explanation makes sense. With regards to merging the NO_FLUSH flag, which of the approaches I mentioned above do you think is appropriate? I believe the most reasonable approach is my first suggestion of still merging the ranges, but setting the range's new flag to be the most conservative of the merged ranges. This would not require a lot of changes to the code, and I feel this scenario shouldn't happen often enough to merit the more intrusive changes needed to split (and maybe re-merge) ranges based on the flag state. |
The more I look at pmemobj_tx_add_common the more I don't like it. Fixing it properly (option 2) would probably mean rewriting this function, so I'm not sure I would like to see such a bug fix in a stable version. So the best course of action would be to make a quick fix (option 1, basically clear no_flush flag in the existing region if new snapshot doesn't have it) with tests, merge it to stable-1.5, stable-1.6 and master and then fix it properly only on master. What do you think? |
Yes, this sounds reasonable to me. I will submit a patch for the quick fix and test cases in the near future. |
Any progress? We are rapidly approaching a new major release and I'd like to have this fix in. |
Sorry for the delay - got caught up in other work. I'll submit a patch by Wednesday. |
I added a pull request with a fix (pull request 3924) |
ISSUE:
pmemobj_tx_xadd_range ignores flags when merging ranges
Environment Information
Please provide a reproduction of the bug:
Slightly modified version of do_tx_xadd_range_commit(PMEMobjpool *pop) in the obj_tx_add_range.c test
This will not flush the field to memory at the end of the transaction. I validated the behavior using pmemcheck.
How often bug is revealed: (always, often, rare):
always
Actual behavior:
The flag associated with the first call to tx_xadd_range(_direct) for merged ranges is always used.
Expected behavior:
While not explicitly covered within the manual, the most intuitive behavior is to have
the flag for a range representing multiple merged calls to tx_xadd_range(_direct) to be merged to its most conservative state.
Details
Currently in pmemobj_tx_add_common when a new range can be merged into an existing range already present within the range AVL tree, the new range's flags are ignored.
This is not intuitive behavior. Reasonable alternatives include:
Additional information about Priority and Help Requested:
Are you willing to submit a pull request with a proposed change? Yes
Requested priority: Low
The text was updated successfully, but these errors were encountered: