diff options
author | Luke Chen <luke.chen@mongodb.com> | 2023-02-16 14:13:44 +1100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-02-16 04:00:19 +0000 |
commit | 3e35e9121f8d8d47539e115d477a1a684b773381 (patch) | |
tree | f2075937cd03c9ddec7d5da7e157d8b6bcd85e13 | |
parent | e033be9f8cf79152024049885cbd7e492425d03b (diff) | |
download | mongo-3e35e9121f8d8d47539e115d477a1a684b773381.tar.gz |
Import wiredtiger: 772a20a40858ce26e500de46caf4d278d1cd7998 from branch mongodb-6.3
ref: 555e197330..772a20a408
for: 6.3.0-rc1
WT-10584 Add missing read barriers in __cursor_skip_prev
-rw-r--r-- | src/third_party/wiredtiger/import.data | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_curprev.c | 31 |
2 files changed, 28 insertions, 7 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index 794ff627df5..da38d282de8 100644 --- a/src/third_party/wiredtiger/import.data +++ b/src/third_party/wiredtiger/import.data @@ -1,6 +1,6 @@ { "vendor": "wiredtiger", "github": "wiredtiger/wiredtiger.git", - "branch": "mongodb-master", - "commit": "555e19733065fc47d4dc85a68283730744992e40" + "branch": "mongodb-6.3", + "commit": "772a20a40858ce26e500de46caf4d278d1cd7998" } diff --git a/src/third_party/wiredtiger/src/btree/bt_curprev.c b/src/third_party/wiredtiger/src/btree/bt_curprev.c index 8a6e08cadbc..054aeb5f5d3 100644 --- a/src/third_party/wiredtiger/src/btree/bt_curprev.c +++ b/src/third_party/wiredtiger/src/btree/bt_curprev.c @@ -34,7 +34,7 @@ static inline int __cursor_skip_prev(WT_CURSOR_BTREE *cbt) { - WT_INSERT *current, *ins; + WT_INSERT *current, *ins, *next_ins; WT_ITEM key; WT_SESSION_IMPL *session; uint64_t recno; @@ -82,7 +82,13 @@ restart: for (; i >= 0; i--) { cbt->ins_stack[i] = NULL; cbt->next_stack[i] = NULL; - ins = cbt->ins_head->head[i]; + /* + * Compiler may replace the usage of the variable with another read in the following + * code. + * + * Place a read barrier to avoid this issue. + */ + WT_ORDERED_READ(ins, cbt->ins_head->head[i]); if (ins != NULL && ins != current) break; } @@ -98,11 +104,26 @@ restart: cbt->next_stack[0] = NULL; goto restart; } - if (ins->next[i] != current) /* Stay at this level */ - ins = ins->next[i]; + /* + * CPU may reorder the read and return a stale value. This can lead us to wrongly skip a + * value in the lower levels of the skip list. + * + * For example, if we have A -> C initially for both level 0 and level 1 and we concurrently + * insert B into both level 0 and level 1. If B is visible on level 1 to this thread, it + * must also be visible on level 0. Otherwise, we would record an inconsistent stack. + * + * Place a read barrier to avoid this issue. + */ + WT_ORDERED_READ(next_ins, ins->next[i]); + if (next_ins != current) /* Stay at this level */ + ins = next_ins; else { /* Drop down a level */ + /* + * It is possible that we read an old value that is inconsistent to the higher levels of + * the skip list due to CPU read reordering. Add a read barrier to avoid this issue. + */ + WT_ORDERED_READ(cbt->next_stack[i], ins->next[i]); cbt->ins_stack[i] = &ins->next[i]; - cbt->next_stack[i] = ins->next[i]; --i; } } |