This patch fixes a minor issue that could occur during OpenACC shutdown on nvidia devices. The acc_shutdown_1 function freed TLS data before unmapping variables, but the nvptx libgomp plugin uses the lack of TLS data in nvptx_free as an indication that it is running from callback context of the CUDA driver runtime, meaning it must add the block to a list to be freed later (in nvptx_close_device).
With this patch, the data will be freed immediately instead. OK for trunk? Thanks, Julian ChangeLog libgomp/ * oacc-init.c (acc_shutdown_1): Remove variable mappings before TLS data during OpenACC shutdown.
commit bbf990a35ab5a7b5100b03c5c5aca11ef0729e7b Author: Julian Brown <jul...@codesourcery.com> Date: Fri Oct 18 11:47:37 2019 -0700 Remove vars before TLS data during OpenACC shutdown libgomp/ * oacc-init.c (acc_shutdown_1): Remove variable mappings before TLS data during OpenACC shutdown. diff --git a/libgomp/oacc-init.c b/libgomp/oacc-init.c index e0395ef43b2..ba51d09fa82 100644 --- a/libgomp/oacc-init.c +++ b/libgomp/oacc-init.c @@ -334,6 +334,20 @@ acc_shutdown_1 (acc_device_t d) /* Free target-specific TLS data and close all devices. */ for (walk = goacc_threads; walk != NULL; walk = walk->next) { + if (walk->dev) + { + /* Free the splay tree before the TLS data below: the nvptx plugin + uses the lack of TLS data as an indicator that device memory is + being freed from (CUDA) callback context. */ + while (walk->dev->mem_map.root) + { + splay_tree_key k = &walk->dev->mem_map.root->key; + if (k->virtual_refcount == VREFCOUNT_LINK_KEY) + k->u.link_key = NULL; + gomp_remove_var (walk->dev, k); + } + } + if (walk->target_tls) base_dev->openacc.destroy_thread_data_func (walk->target_tls); @@ -354,19 +368,8 @@ acc_shutdown_1 (acc_device_t d) gomp_fatal ("shutdown during host fallback"); } - if (walk->dev) - { - while (walk->dev->mem_map.root) - { - splay_tree_key k = &walk->dev->mem_map.root->key; - if (k->virtual_refcount == VREFCOUNT_LINK_KEY) - k->u.link_key = NULL; - gomp_remove_var (walk->dev, k); - } - - walk->dev = NULL; - walk->base_dev = NULL; - } + walk->dev = NULL; + walk->base_dev = NULL; } gomp_mutex_unlock (&goacc_thread_lock);