Skip to content

Commit 86ae5cb

Browse files
committed
Make data race in tracking provider far less probable
Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
1 parent 96e7a40 commit 86ae5cb

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

src/critnib/critnib.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ void *critnib_remove(struct critnib *c, word key) {
472472

473473
del_leaf:
474474
value = k->value;
475+
utils_atomic_store_release_ptr(&k->value, NULL);
475476
c->pending_del_leaves[del] = k;
476477

477478
not_found:
@@ -635,7 +636,10 @@ void *critnib_find_le(struct critnib *c, word key) {
635636
struct critnib_node *n; /* avoid a subtle TOCTOU */
636637
utils_atomic_load_acquire_ptr((void **)&c->root, (void **)&n);
637638
struct critnib_leaf *k = n ? find_le(n, key) : NULL;
638-
res = k ? k->value : NULL;
639+
res = NULL;
640+
if (k) {
641+
utils_atomic_load_acquire_ptr(&k->value, &res);
642+
}
639643
utils_atomic_load_acquire_u64(&c->remove_count, &wrs2);
640644
} while (wrs1 + DELETED_LIFE <= wrs2);
641645

src/provider/provider_tracking.c

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,22 @@ static tracker_alloc_info_t *get_most_nested_alloc_segment(
8181
found =
8282
critnib_find(hTracker->alloc_segments_map[level], (uintptr_t)ptr,
8383
FIND_LE, (void *)&rkey, (void **)&rvalue);
84-
if (!found || !rvalue) {
84+
if (!found) {
8585
break;
8686
}
8787

88+
// rvalue == NULL means that the entry was removed
89+
if (rvalue == NULL) {
90+
// restart the search
91+
parent_value = NULL;
92+
parent_key = 0;
93+
rkey = 0;
94+
rsize = 0;
95+
level = 0;
96+
found = 0;
97+
continue;
98+
}
99+
88100
utils_atomic_load_acquire_u64((uint64_t *)&rvalue->size, &rsize);
89101

90102
if (found && (uintptr_t)ptr < rkey + rsize) {
@@ -195,10 +207,22 @@ static umf_result_t umfMemoryTrackerAdd(umf_memory_tracker_handle_t hTracker,
195207
found =
196208
critnib_find(hTracker->alloc_segments_map[level], (uintptr_t)ptr,
197209
FIND_LE, (void *)&rkey, (void **)&rvalue);
198-
if (!found || !rvalue) {
210+
if (!found) {
199211
break;
200212
}
201213

214+
// rvalue == NULL means that the entry was removed
215+
if (rvalue == NULL) {
216+
// restart the search
217+
parent_value = NULL;
218+
parent_key = 0;
219+
rkey = 0;
220+
rsize = 0;
221+
level = 0;
222+
found = 0;
223+
continue;
224+
}
225+
202226
utils_atomic_load_acquire_u64((uint64_t *)&rvalue->size, &rsize);
203227

204228
if ((uintptr_t)ptr < rkey + rsize) {
@@ -383,6 +407,17 @@ umf_result_t umfMemoryTrackerGetAllocInfo(const void *ptr,
383407
assert(level < MAX_LEVELS_OF_ALLOC_SEGMENT_MAP);
384408
found = critnib_find(TRACKER->alloc_segments_map[level], (uintptr_t)ptr,
385409
FIND_LE, (void *)&rkey, (void **)&rvalue);
410+
// rvalue == NULL means that the entry was removed
411+
if (found && (rvalue == NULL)) {
412+
// restart the search
413+
top_most_value = NULL;
414+
top_most_key = 0;
415+
rkey = 0;
416+
level = 0;
417+
found = 0;
418+
continue;
419+
}
420+
386421
if (found && (uintptr_t)ptr < rkey + rvalue->size) {
387422
top_most_key = rkey;
388423
top_most_value = rvalue;
@@ -428,8 +463,14 @@ umf_result_t umfMemoryTrackerGetIpcInfo(const void *ptr,
428463

429464
uintptr_t rkey;
430465
tracker_ipc_info_t *rvalue = NULL;
431-
int found = critnib_find(TRACKER->ipc_segments_map, (uintptr_t)ptr, FIND_LE,
466+
int found = 0;
467+
468+
do {
469+
found = critnib_find(TRACKER->ipc_segments_map, (uintptr_t)ptr, FIND_LE,
432470
(void *)&rkey, (void **)&rvalue);
471+
// rvalue == NULL means that the entry was removed
472+
} while (found && (rvalue == NULL));
473+
433474
if (!found || (uintptr_t)ptr >= rkey + rvalue->size) {
434475
LOG_DEBUG("pointer %p not found in the tracker, TRACKER=%p", ptr,
435476
(void *)TRACKER);
@@ -768,6 +809,11 @@ static void check_if_tracker_is_empty(umf_memory_tracker_handle_t hTracker,
768809

769810
while (1 == critnib_find(hTracker->alloc_segments_map[i], last_key,
770811
FIND_G, &rkey, (void **)&rvalue)) {
812+
// rvalue == NULL means that the entry was removed
813+
if (rvalue == NULL) {
814+
continue;
815+
}
816+
771817
if (rvalue->pool == pool || pool == NULL) {
772818
n_items++;
773819
}

0 commit comments

Comments
 (0)