11/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
22/*
3- * Copyright (c) 2011-2014 Los Alamos National Security, LLC. All rights
3+ * Copyright (c) 2011-2015 Los Alamos National Security, LLC. All rights
44 * reserved.
55 * Copyright (c) 2011 UT-Battelle, LLC. All rights reserved.
66 * Copyright (c) 2014 Research Organization for Information Science
@@ -25,7 +25,6 @@ int mca_btl_ugni_send (struct mca_btl_base_module_t *btl,
2525 mca_btl_ugni_base_frag_t * frag = (mca_btl_ugni_base_frag_t * ) descriptor ;
2626 size_t size = frag -> segments [0 ].seg_len + frag -> segments [1 ].seg_len ;
2727 mca_btl_ugni_module_t * ugni_module = (mca_btl_ugni_module_t * ) btl ;
28- int flags_save = frag -> base .des_flags ;
2928 int rc ;
3029
3130 /* tag and len are at the same location in eager and smsg frag hdrs */
@@ -43,42 +42,48 @@ int mca_btl_ugni_send (struct mca_btl_base_module_t *btl,
4342 BTL_VERBOSE (("btl/ugni sending descriptor %p from %d -> %d. length = %" PRIu64 , (void * )descriptor ,
4443 OPAL_PROC_MY_NAME .vpid , endpoint -> common -> ep_rem_id , size ));
4544
46- /* temporarily disable ownership and callback flags so we can reliably check the complete flag */
47- frag -> base .des_flags &= ~(MCA_BTL_DES_FLAGS_BTL_OWNERSHIP | MCA_BTL_DES_SEND_ALWAYS_CALLBACK );
45+ /* add a reference to prevent the fragment from being returned until after the
46+ * completion flag is checked. */
47+ ++ frag -> ref_cnt ;
4848 frag -> flags &= ~MCA_BTL_UGNI_FRAG_COMPLETE ;
4949
5050 rc = mca_btl_ugni_send_frag (endpoint , frag );
51-
52- if (OPAL_LIKELY (frag -> flags & MCA_BTL_UGNI_FRAG_COMPLETE )) {
51+ if (OPAL_LIKELY (mca_btl_ugni_frag_check_complete (frag ))) {
5352 /* fast path: remote side has received the frag */
54- frag -> base .des_flags = flags_save ;
55- mca_btl_ugni_frag_complete (frag , OPAL_SUCCESS );
53+ (void ) mca_btl_ugni_frag_del_ref (frag , OPAL_SUCCESS );
5654
5755 return 1 ;
5856 }
5957
60- if ((OPAL_SUCCESS == rc ) && (frag -> flags & MCA_BTL_UGNI_FRAG_BUFFERED ) && (flags_save & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP )) {
58+ if ((OPAL_SUCCESS == rc ) && (frag -> flags & MCA_BTL_UGNI_FRAG_BUFFERED ) && (frag -> flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP )) {
6159 /* fast(ish) path: btl owned buffered frag. report send as complete */
62- frag -> base .des_flags = flags_save & ~MCA_BTL_DES_SEND_ALWAYS_CALLBACK ;
60+ bool call_callback = !!(frag -> flags & MCA_BTL_DES_SEND_ALWAYS_CALLBACK );
61+ frag -> flags &= ~MCA_BTL_DES_SEND_ALWAYS_CALLBACK ;
6362
64- if (OPAL_LIKELY ( flags_save & MCA_BTL_DES_SEND_ALWAYS_CALLBACK ) ) {
63+ if (call_callback ) {
6564 frag -> base .des_cbfunc (& frag -> endpoint -> btl -> super , frag -> endpoint , & frag -> base , rc );
6665 }
6766
67+ (void ) mca_btl_ugni_frag_del_ref (frag , OPAL_SUCCESS );
68+
6869 return 1 ;
6970 }
7071
7172 /* slow(ish) path: remote side hasn't received the frag. call the frag's callback when
7273 we get the local smsg/msgq or remote rdma completion */
73- frag -> base .des_flags = flags_save | MCA_BTL_DES_SEND_ALWAYS_CALLBACK ;
74+ frag -> base .des_flags |= MCA_BTL_DES_SEND_ALWAYS_CALLBACK ;
75+
76+ mca_btl_ugni_frag_del_ref (frag , OPAL_SUCCESS );
7477
7578 if (OPAL_UNLIKELY (OPAL_ERR_OUT_OF_RESOURCE == rc )) {
7679 /* queue up request */
7780 if (false == endpoint -> wait_listed ) {
7881 OPAL_THREAD_LOCK (& ugni_module -> ep_wait_list_lock );
79- opal_list_append (& ugni_module -> ep_wait_list , & endpoint -> super );
82+ if (false == endpoint -> wait_listed ) {
83+ opal_list_append (& ugni_module -> ep_wait_list , & endpoint -> super );
84+ endpoint -> wait_listed = true;
85+ }
8086 OPAL_THREAD_UNLOCK (& ugni_module -> ep_wait_list_lock );
81- endpoint -> wait_listed = true;
8287 }
8388
8489 OPAL_THREAD_LOCK (& endpoint -> lock );
0 commit comments