[openib-general] RE: [PATCH] opensm: make cl_atomic functions atomic
Eitan Zahavi
eitan at mellanox.co.il
Sun Mar 5 04:30:22 PST 2006
Nice catch !
>
> complib's cl_atomic_() functions are not atomic in current
implementation,
> they use static per function locks so race is possible between
different
> functions (for example between _inc() and _dec()). Such races are
pretty
> reproducible in practice - for example it is used to inc/decrement mad
> counters in opensm.
>
> This patch is fast workaround. I think we will need to review usage
and
> implementation of atomic stuff in opensm for better solution.
>
> Sasha.
>
>
> This is workaround for broken cl_atomic_() stuff used in
complib/OpenSM:
> it replaces static per function locks by one globally shared lock.
> In long term we will need better solution.
>
> Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
> ---
>
> osm/complib/cl_complib.c | 44 ++++++++--------------
> osm/complib/libosmcomp.map | 1 +
> osm/include/complib/cl_atomic_osd.h | 69
++++++++++-------------------------
> 3 files changed, 36 insertions(+), 78 deletions(-)
>
> diff --git a/osm/complib/cl_complib.c b/osm/complib/cl_complib.c
> index 9eb475b..e33dfef 100644
> --- a/osm/complib/cl_complib.c
> +++ b/osm/complib/cl_complib.c
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
> + * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
> * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights
reserved.
> * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
> *
> @@ -40,6 +40,7 @@
> #endif /* HAVE_CONFIG_H */
>
> #include <complib/cl_types.h>
> +#include <complib/cl_spinlock.h>
> #include <complib/cl_device.h>
> #include <complib/cl_debug.h>
> #include <complib/cl_syshelper.h>
> @@ -61,14 +62,7 @@ extern
> void
> __cl_timer_prov_destroy( void );
>
> -void
> -complib_exit(void);
> -
> -void
> -complib_fini(void);
> -
> -void
> -complib_init(void);
> +cl_spinlock_t cl_atomic_spinlock;
>
> void
> __attribute (( constructor ))
> @@ -76,28 +70,23 @@ complib_init(void)
> {
> cl_status_t status = CL_SUCCESS;
>
> - /*
> - * System Helper Init.
> - */
> + status = cl_spinlock_init(&cl_atomic_spinlock);
> + if (status != CL_SUCCESS)
> + goto _error;
> +
> status = __cl_user_syshelper_init();
> if( status != CL_SUCCESS )
> - {
> - cl_msg_out( "__init: failed to init syshelper (%s)\n",
> -
CL_STATUS_MSG(
> status ) );
> - exit(1);
> - }
> -
> - /*
> - * Timer Init
> - */
> + goto _error;
>
> status = __cl_timer_prov_create();
> if( status != CL_SUCCESS)
> - {
> - cl_msg_out( "__init: failed to create timer provider
status (%s)\n",
> -
CL_STATUS_MSG(
> status ) );
> - exit(1);
> - }
> + goto _error;
> + return;
> +
> + _error:
> + cl_msg_out( "__init: failed to create complib (%s)\n",
> + CL_STATUS_MSG( status ) );
> + exit(1);
> }
>
> void
> @@ -105,7 +94,6 @@ __attribute (( destructor ))
> complib_fini(void)
> {
> __cl_timer_prov_destroy();
> -
> __cl_user_syshelper_exit();
> }
>
> @@ -113,8 +101,8 @@ void
> complib_exit(void)
> {
> __cl_timer_prov_destroy();
> -
> __cl_user_syshelper_exit();
> + cl_spinlock_destroy(&cl_atomic_spinlock);
> }
>
> boolean_t
> diff --git a/osm/complib/libosmcomp.map b/osm/complib/libosmcomp.map
> index 8d5f38c..e61ee57 100644
> --- a/osm/complib/libosmcomp.map
> +++ b/osm/complib/libosmcomp.map
> @@ -200,6 +200,7 @@ OSMCOMP_1.0 {
> cl_signal_wait_object;
> cl_destroy_wait_object;
> cl_clear_wait_object;
> + cl_atomic_spinlock;
> cl_atomic_dec;
> cl_free;
> cl_malloc;
> diff --git a/osm/include/complib/cl_atomic_osd.h
> b/osm/include/complib/cl_atomic_osd.h
> index a592a8e..ad7ce11 100644
> --- a/osm/include/complib/cl_atomic_osd.h
> +++ b/osm/include/complib/cl_atomic_osd.h
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
> + * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
> * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights
reserved.
> * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
> *
> @@ -64,23 +64,17 @@
>
> BEGIN_C_DECLS
>
> +extern cl_spinlock_t cl_atomic_spinlock;
> +
> static inline int32_t
> cl_atomic_inc(
> IN atomic32_t* const p_value )
> {
> int32_t new_val;
> - static cl_spinlock_t spinlock;
> -
> - if (spinlock.state != CL_INITIALIZED)
> - {
> - cl_spinlock_construct(&spinlock);
> - cl_spinlock_init(&spinlock);
> - }
> -
> - cl_spinlock_acquire(&spinlock);
> - new_val = *p_value + 1;
> - *p_value = new_val;
> - cl_spinlock_release(&spinlock);
> + cl_spinlock_acquire(&cl_atomic_spinlock);
> + new_val = *p_value + 1;
> + *p_value = new_val;
> + cl_spinlock_release(&cl_atomic_spinlock);
> return( new_val );
> }
>
> @@ -89,18 +83,10 @@ cl_atomic_dec(
> IN atomic32_t* const p_value )
> {
> int32_t new_val;
> - static cl_spinlock_t spinlock;
> -
> - if (spinlock.state != CL_INITIALIZED)
> - {
> - cl_spinlock_construct(&spinlock);
> - cl_spinlock_init(&spinlock);
> - }
> -
> - cl_spinlock_acquire(&spinlock);
> - new_val = *p_value - 1;
> - *p_value = new_val;
> - cl_spinlock_release(&spinlock);
> + cl_spinlock_acquire(&cl_atomic_spinlock);
> + new_val = *p_value - 1;
> + *p_value = new_val;
> + cl_spinlock_release(&cl_atomic_spinlock);
> return( new_val );
> }
>
> @@ -110,19 +96,10 @@ cl_atomic_add(
> IN const int32_t increment )
> {
> int32_t new_val;
> -
> - static cl_spinlock_t spinlock;
> -
> - if (spinlock.state != CL_INITIALIZED)
> - {
> - cl_spinlock_construct(&spinlock);
> - cl_spinlock_init(&spinlock);
> - }
> -
> - cl_spinlock_acquire(&spinlock);
> - new_val = *p_value + increment;
> - *p_value = new_val;
> - cl_spinlock_release(&spinlock);
> + cl_spinlock_acquire(&cl_atomic_spinlock);
> + new_val = *p_value + increment;
> + *p_value = new_val;
> + cl_spinlock_release(&cl_atomic_spinlock);
> return( new_val );
> }
>
> @@ -132,18 +109,10 @@ cl_atomic_sub(
> IN const int32_t decrement )
> {
> int32_t new_val;
> - static cl_spinlock_t spinlock;
> -
> - if (spinlock.state != CL_INITIALIZED)
> - {
> - cl_spinlock_construct(&spinlock);
> - cl_spinlock_init(&spinlock);
> - }
> -
> - cl_spinlock_acquire(&spinlock);
> - new_val = *p_value + decrement;
> - *p_value = new_val;
> - cl_spinlock_release(&spinlock);
> + cl_spinlock_acquire(&cl_atomic_spinlock);
> + new_val = *p_value + decrement;
> + *p_value = new_val;
> + cl_spinlock_release(&cl_atomic_spinlock);
> return( new_val );
> }
>
More information about the general
mailing list