Attached is an old gomp4 patch that allegedly fixes an shutdown runtime issue involving OpenACC accelerators. Unfortunately, the original patch didn't include a test case, nor did it generate any regressions in the libgomp testsuite when I reverted it in og8.
With that said, I like how this patch eliminates the redundant use of gomp_mutex_lock to unmap variables (because gomp_unmap_vars already acquires a lock). However, the trade-off is that it does increase tgt->list_count to num_funcs + num_vars. Does anyone have any strong opinion on this patch and is it OK for trunk? I bootstrapped and regtested it for x86_64 Linux with nvptx offloading and I didn't encounter any regressions. Thanks, Cesar
[OpenACC] Fix acc_shutdown issue 2018-XX-YY James Norris <jnor...@codesourcery.com> Cesar Philippidis <ce...@codesourcery.com> libgomp/ * oacc-init.c (acc_shutdown_1): Replace use of gomp_free_memmap with gomp_unmap_vars. * target.c (gomp_load_image_to_device): Fix initialization. (gomp_free_memmap): Remove. (cherry picked from gomp-4_0-branch r226045) --- libgomp/libgomp.h | 1 - libgomp/oacc-init.c | 9 ++++++--- libgomp/target.c | 27 +++++++++------------------ 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h index 3a8cc2bd7d6..5c11e97616d 100644 --- a/libgomp/libgomp.h +++ b/libgomp/libgomp.h @@ -1003,7 +1003,6 @@ extern struct target_mem_desc *gomp_map_vars (struct gomp_device_descr *, enum gomp_map_vars_kind); extern void gomp_unmap_vars (struct target_mem_desc *, bool); extern void gomp_init_device (struct gomp_device_descr *); -extern void gomp_free_memmap (struct splay_tree_s *); extern void gomp_unload_device (struct gomp_device_descr *); extern bool gomp_remove_var (struct gomp_device_descr *, splay_tree_key); diff --git a/libgomp/oacc-init.c b/libgomp/oacc-init.c index 8842e7218cb..957bb9f31f9 100644 --- a/libgomp/oacc-init.c +++ b/libgomp/oacc-init.c @@ -303,9 +303,12 @@ acc_shutdown_1 (acc_device_t d) if (walk->dev) { - gomp_mutex_lock (&walk->dev->lock); - gomp_free_memmap (&walk->dev->mem_map); - gomp_mutex_unlock (&walk->dev->lock); + while (walk->dev->mem_map.root) + { + struct target_mem_desc *tgt = walk->dev->mem_map.root->key.tgt; + + gomp_unmap_vars (tgt, false); + } walk->dev = NULL; walk->base_dev = NULL; diff --git a/libgomp/target.c b/libgomp/target.c index dda041cdbef..9ddc8d6c038 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -1184,14 +1184,17 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version, } /* Insert host-target address mapping into splay tree. */ - struct target_mem_desc *tgt = gomp_malloc (sizeof (*tgt)); + struct target_mem_desc *tgt = + gomp_malloc (sizeof (*tgt) + + sizeof (tgt->list[0]) + * (num_funcs + num_vars) * sizeof (*tgt->array)); tgt->array = gomp_malloc ((num_funcs + num_vars) * sizeof (*tgt->array)); tgt->refcount = REFCOUNT_INFINITY; tgt->tgt_start = 0; tgt->tgt_end = 0; tgt->to_free = NULL; tgt->prev = NULL; - tgt->list_count = 0; + tgt->list_count = num_funcs + num_vars; tgt->device_descr = devicep; splay_tree_node array = tgt->array; @@ -1204,6 +1207,8 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version, k->tgt_offset = target_table[i].start; k->refcount = REFCOUNT_INFINITY; k->link_key = NULL; + tgt->list[i].key = k; + tgt->refcount++; array->left = NULL; array->right = NULL; splay_tree_insert (&devicep->mem_map, array); @@ -1236,6 +1241,8 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version, k->tgt_offset = target_var->start; k->refcount = target_size & link_bit ? REFCOUNT_LINK : REFCOUNT_INFINITY; k->link_key = NULL; + tgt->list[i].key = k; + tgt->refcount++; array->left = NULL; array->right = NULL; splay_tree_insert (&devicep->mem_map, array); @@ -1454,22 +1461,6 @@ gomp_unload_device (struct gomp_device_descr *devicep) } } -/* Free address mapping tables. MM must be locked on entry, and remains locked - on return. */ - -attribute_hidden void -gomp_free_memmap (struct splay_tree_s *mem_map) -{ - while (mem_map->root) - { - struct target_mem_desc *tgt = mem_map->root->key.tgt; - - splay_tree_remove (mem_map, &mem_map->root->key); - free (tgt->array); - free (tgt); - } -} - /* Host fallback for GOMP_target{,_ext} routines. */ static void -- 2.17.1