[OpenMP][Fix] Track all threads that may delete an entry
authorGuilherme Valarini <guilherme.a.valarini@gmail.com>
Thu, 19 Jan 2023 15:11:20 +0000 (12:11 -0300)
committerGuilherme Valarini <guilherme.a.valarini@gmail.com>
Thu, 19 Jan 2023 15:11:52 +0000 (12:11 -0300)
commite0b3b6cec7cf1c03bde8b65dcd2f9233839ad0a9
tree27ec04c694b7c134c3f783bd567bb900c7bfdd3b
parent03c45f14bf639c7d2346b956cd1ec61a669236e0
[OpenMP][Fix] Track all threads that may delete an entry

The entries inside a "target data end" is processed in three steps:

  1. Query internal data maps for the entries and dispatch any necessary
     device-side operations (i.e., data retrieval);
  2. Synchronize the such operations;
  3. Update the host-side pointers and remove any entry which reference
     counter reached zero.

Such steps may be executed by multiple threads which may even operate on
the same entries. The current implementation (D121058) tries to
synchronize these threads by tracking the "owner" for the deletion of
each entry using their thread ID. Unfortunately it may failed to do so
because of the following reasons:

  1. The owner is always assigned at the first step only if the
     reference count is 0 when the map is queried. This does not work
     when such owner thread is faster than a previous one that is also
     processing the same entry on another "target data end", leading to
     user-after-free problems.
  2. The entry is only added for post-processing (step 3) if its
     reference count was 0 at query time (step 1). This does not allow
     for threads to exchange responsibility for the deletion, leading
     again to user-after-free problems.
  3. An entry may appear multiple times in the arguments array of a
     "target data end", which may lead to deleting the entry
     prematurely, leading, again, to user-after-free problems.

This patch addresses these problems by tracking all the threads that are
using an entry at "target data end" region through a counter, ensuring
only the last one deletes it when needed. It also ensures that all
entries that are successfully found inside the data maps in step 1 are
also processed in step 3, regardless if their reference count was zeroed
or not at query time. This ensures the deletion ownership may be passed
to any thread that is using such entry.

Reviewed By: ye-luo

Differential Revision: https://reviews.llvm.org/D132676
openmp/libomptarget/include/device.h
openmp/libomptarget/src/device.cpp
openmp/libomptarget/src/omptarget.cpp
openmp/libomptarget/test/mapping/map_back_race.cpp