1
1

ompi/errhandler: make set/get actually thread safe

The current versions of these functions have a fatal flaw. If a
errhandler set and free call is made by another thread while the
thread calling get is between the cmpset and retain then we will
retain an invalid object. Fixing this by just using locking. This is
not a critical path so this should be ok.

Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
Этот коммит содержится в:
Nathan Hjelm 2017-11-08 14:25:53 -07:00
родитель 86bb6f8bac
Коммит 6b68d1cfc8
6 изменённых файлов: 30 добавлений и 45 удалений

Просмотреть файл

@ -13,7 +13,7 @@
* Copyright (c) 2007-2009 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2016 Los Alamos National Security, LLC. All rights
* Copyright (c) 2016-2017 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
@ -43,8 +43,6 @@ static const char FUNC_NAME[] = "MPI_Comm_get_errhandler";
int MPI_Comm_get_errhandler(MPI_Comm comm, MPI_Errhandler *errhandler)
{
MPI_Errhandler tmp;
/* Error checking */
MEMCHECKER(
memchecker_comm(comm);
@ -65,16 +63,12 @@ int MPI_Comm_get_errhandler(MPI_Comm comm, MPI_Errhandler *errhandler)
}
}
/* On 64 bits environments we have to make sure the reading of the
error_handler became atomic. */
do {
tmp = comm->error_handler;
} while (!OPAL_ATOMIC_BOOL_CMPSET_PTR(&(comm->error_handler), tmp, tmp));
opal_mutex_lock (&comm->c_lock);
/* Retain the errhandler, corresponding to object refcount decrease
in errhandler_free.c. */
*errhandler = tmp;
OBJ_RETAIN(tmp);
OBJ_RETAIN(comm->error_handler);
*errhandler = comm->error_handler;
opal_mutex_unlock (&comm->c_lock);
/* All done */

Просмотреть файл

@ -12,7 +12,7 @@
* All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2016 Los Alamos National Security, LLC. All rights
* Copyright (c) 2016-2017 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
@ -69,11 +69,12 @@ int MPI_Comm_set_errhandler(MPI_Comm comm, MPI_Errhandler errhandler)
/* Prepare the new error handler */
OBJ_RETAIN(errhandler);
/* Ditch the old errhandler, and decrement its refcount. On 64
bits environments we have to make sure the reading of the
error_handler became atomic. */
tmp = OPAL_ATOMIC_SWAP_PTR(&comm->error_handler, errhandler);
opal_mutex_lock (&comm->c_lock);
/* Ditch the old errhandler, and decrement its refcount. */
tmp = comm->error_handler;
comm->error_handler = errhandler;
OBJ_RELEASE(tmp);
opal_mutex_unlock (&comm->c_lock);
/* All done */
return MPI_SUCCESS;

Просмотреть файл

@ -13,7 +13,7 @@
* Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2016 Los Alamos National Security, LLC. All rights
* Copyright (c) 2016-2017 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
@ -42,8 +42,6 @@ static const char FUNC_NAME[] = "MPI_File_get_errhandler";
int MPI_File_get_errhandler( MPI_File file, MPI_Errhandler *errhandler)
{
MPI_Errhandler tmp;
OPAL_CR_NOOP_PROGRESS();
/* Error checking */
@ -64,16 +62,12 @@ int MPI_File_get_errhandler( MPI_File file, MPI_Errhandler *errhandler)
}
}
/* On 64 bits environments we have to make sure the reading of the
error_handler became atomic. */
do {
tmp = file->error_handler;
} while (!OPAL_ATOMIC_BOOL_CMPSET_PTR(&(file->error_handler), tmp, tmp));
opal_mutex_lock (&file->f_mutex);
/* Retain the errhandler, corresponding to object refcount
decrease in errhandler_free.c. */
*errhandler = tmp;
OBJ_RETAIN(tmp);
*errhandler = file->error_handler;
OBJ_RETAIN(file->error_handler);
opal_mutex_unlock (&file->f_mutex);
/* All done */

Просмотреть файл

@ -13,7 +13,7 @@
* Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2016 Los Alamos National Security, LLC. All rights
* Copyright (c) 2016-2017 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
@ -68,11 +68,12 @@ int MPI_File_set_errhandler( MPI_File file, MPI_Errhandler errhandler)
/* Prepare the new error handler */
OBJ_RETAIN(errhandler);
/* Ditch the old errhandler, and decrement its refcount. On 64
bits environments we have to make sure the reading of the
error_handler became atomic. */
tmp = OPAL_ATOMIC_SWAP_PTR (&file->error_handler, errhandler);
opal_mutex_lock (&file->f_mutex);
/* Ditch the old errhandler, and decrement its refcount. */
tmp = file->error_handler;
file->error_handler = errhandler;
OBJ_RELEASE(tmp);
opal_mutex_unlock (&file->f_mutex);
/* All done */
return MPI_SUCCESS;

Просмотреть файл

@ -42,8 +42,6 @@ static const char FUNC_NAME[] = "MPI_Win_get_errhandler";
int MPI_Win_get_errhandler(MPI_Win win, MPI_Errhandler *errhandler)
{
MPI_Errhandler tmp;
OPAL_CR_NOOP_PROGRESS();
if (MPI_PARAM_CHECK) {
@ -57,16 +55,12 @@ int MPI_Win_get_errhandler(MPI_Win win, MPI_Errhandler *errhandler)
}
}
/* On 64 bits environments we have to make sure the reading of the
error_handler became atomic. */
do {
tmp = win->error_handler;
} while (!OPAL_ATOMIC_BOOL_CMPSET_PTR(&(win->error_handler), tmp, tmp));
opal_mutex_lock (&win->w_lock);
/* Retain the errhandler, corresponding to object refcount
decrease in errhandler_free.c. */
OBJ_RETAIN(win->error_handler);
*errhandler = win->error_handler;
opal_mutex_unlock (&win->w_lock);
/* All done */
return MPI_SUCCESS;

Просмотреть файл

@ -13,7 +13,7 @@
* Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2016 Los Alamos National Security, LLC. All rights
* Copyright (c) 2016-2017 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
@ -63,11 +63,12 @@ int MPI_Win_set_errhandler(MPI_Win win, MPI_Errhandler errhandler)
/* Prepare the new error handler */
OBJ_RETAIN(errhandler);
/* Ditch the old errhandler, and decrement its refcount. On 64
bits environments we have to make sure the reading of the
error_handler became atomic. */
tmp = OPAL_ATOMIC_SWAP_PTR(&win->error_handler, errhandler);
opal_mutex_lock (&win->w_lock);
/* Ditch the old errhandler, and decrement its refcount. */
tmp = win->error_handler;
win->error_handler = errhandler;
OBJ_RELEASE(tmp);
opal_mutex_unlock (&win->w_lock);
/* All done */
return MPI_SUCCESS;