|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2005,2009 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_defs.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_txn.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_svc.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_sender.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static ib_api_status_t
|
|
Packit |
13e616 |
__osmv_txnmgr_lookup(IN osmv_txn_mgr_t * p_tx_mgr,
|
|
Packit |
13e616 |
IN uint64_t key, OUT osmv_txn_ctx_t ** pp_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static ib_api_status_t
|
|
Packit |
13e616 |
__osmv_txnmgr_insert_txn(IN osmv_txn_mgr_t * p_tx_mgr,
|
|
Packit |
13e616 |
IN osmv_txn_ctx_t * p_txn, IN uint64_t key);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static ib_api_status_t
|
|
Packit |
13e616 |
__osmv_txnmgr_remove_txn(IN osmv_txn_mgr_t * p_tx_mgr,
|
|
Packit |
13e616 |
IN uint64_t key, OUT osmv_txn_ctx_t ** pp_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void __osmv_txn_all_done(osm_bind_handle_t h_bind);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static uint64_t
|
|
Packit |
13e616 |
__osmv_txn_timeout_cb(IN uint64_t key,
|
|
Packit |
13e616 |
IN uint32_t num_regs, IN void *cb_context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_txn_init(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN uint64_t tid, IN uint64_t key, OUT osmv_txn_ctx_t ** pp_txn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t st;
|
|
Packit |
13e616 |
osmv_txn_ctx_t *p_txn;
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(NULL != h_bind && NULL != pp_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Starting transaction 0x%016" PRIx64
|
|
Packit |
13e616 |
" (key=0x%016" PRIx64 ")\n", tid, key);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_txn = malloc(sizeof(osmv_txn_ctx_t));
|
|
Packit |
13e616 |
if (!p_txn) {
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_txn, 0, sizeof(osmv_txn_ctx_t));
|
|
Packit |
13e616 |
p_txn->p_log = p_bo->txn_mgr.p_log;
|
|
Packit |
13e616 |
p_txn->tid = tid;
|
|
Packit |
13e616 |
p_txn->key = key;
|
|
Packit |
13e616 |
p_txn->p_madw = NULL;
|
|
Packit |
13e616 |
p_txn->rmpp_txfr.rmpp_state = OSMV_TXN_RMPP_NONE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* insert into transaction manager DB */
|
|
Packit |
13e616 |
st = __osmv_txnmgr_insert_txn(&p_bo->txn_mgr, p_txn, key);
|
|
Packit |
13e616 |
if (IB_SUCCESS != st) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osmv_txn_init: ERR 6703: "
|
|
Packit |
13e616 |
"Failed to insert to transaction 0x%016" PRIx64
|
|
Packit |
13e616 |
" (key=0x%016" PRIx64 ") to manager DB\n",
|
|
Packit |
13e616 |
tid, key);
|
|
Packit |
13e616 |
goto insert_txn_failed;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
*pp_txn = p_txn;
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
return IB_SUCCESS;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
insert_txn_failed:
|
|
Packit |
13e616 |
free(p_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
return st;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_txn_init_rmpp_sender(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osmv_txn_ctx_t * p_txn, IN osm_madw_t * p_madw)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t st;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Double-Sided RMPP Direction Switch */
|
|
Packit |
13e616 |
osmv_txn_remove_timeout_ev(h_bind, osmv_txn_get_key(p_txn));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_txn->rmpp_txfr.rmpp_state = OSMV_TXN_RMPP_SENDER;
|
|
Packit |
13e616 |
p_txn->rmpp_txfr.p_rmpp_send_ctx = malloc(sizeof(osmv_rmpp_send_ctx_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_txn->rmpp_txfr.p_rmpp_send_ctx) {
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_txn->rmpp_txfr.p_rmpp_send_ctx, 0,
|
|
Packit |
13e616 |
sizeof(osmv_rmpp_send_ctx_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
st = osmv_rmpp_send_ctx_init(p_txn->rmpp_txfr.p_rmpp_send_ctx,
|
|
Packit |
13e616 |
(void *)p_madw->p_mad,
|
|
Packit |
13e616 |
p_madw->mad_size, p_txn->p_log);
|
|
Packit |
13e616 |
return st;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_txn_init_rmpp_receiver(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osmv_txn_ctx_t * p_txn,
|
|
Packit |
13e616 |
IN boolean_t is_init_by_peer)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t st;
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
uint64_t key = osmv_txn_get_key(p_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Double-Sided RMPP Direction Switch */
|
|
Packit |
13e616 |
osmv_txn_remove_timeout_ev(h_bind, key);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Set the Transaction Timeout value */
|
|
Packit |
13e616 |
st = osmv_txn_set_timeout_ev(h_bind, key,
|
|
Packit |
13e616 |
p_bo->p_vendor->ttime_timeout);
|
|
Packit |
13e616 |
if (IB_SUCCESS != st) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return st;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_txn->rmpp_txfr.rmpp_state = OSMV_TXN_RMPP_RECEIVER;
|
|
Packit |
13e616 |
p_txn->rmpp_txfr.is_rmpp_init_by_peer = is_init_by_peer;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_txn->rmpp_txfr.p_rmpp_recv_ctx = malloc(sizeof(osmv_rmpp_recv_ctx_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_txn->rmpp_txfr.p_rmpp_recv_ctx) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_txn_remove_timeout_ev(h_bind, key);
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_txn->rmpp_txfr.p_rmpp_recv_ctx, 0,
|
|
Packit |
13e616 |
sizeof(osmv_rmpp_recv_ctx_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
st = osmv_rmpp_recv_ctx_init(p_txn->rmpp_txfr.p_rmpp_recv_ctx,
|
|
Packit |
13e616 |
p_txn->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return st;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* osmv_txn_set_timeout_ev
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SEE ALSO
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_txn_set_timeout_ev(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN uint64_t key, IN uint64_t msec)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
cl_event_wheel_t *p_event_wheel = p_bo->txn_mgr.p_event_wheel;
|
|
Packit |
13e616 |
cl_status_t status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = cl_event_wheel_reg(p_event_wheel, key, cl_get_time_stamp() + 1000 * msec, /* TTL */
|
|
Packit |
13e616 |
__osmv_txn_timeout_cb,
|
|
Packit |
13e616 |
p_bo /* The context */ );
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return (ib_api_status_t) status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* osmv_txn_remove_timeout_ev
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
* SEE ALSO
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
void osmv_txn_remove_timeout_ev(IN osm_bind_handle_t h_bind, IN uint64_t key)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_event_wheel_t *p_event_wheel =
|
|
Packit |
13e616 |
((osmv_bind_obj_t *) h_bind)->txn_mgr.p_event_wheel;
|
|
Packit |
13e616 |
cl_event_wheel_unreg(p_event_wheel, key);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void
|
|
Packit |
13e616 |
osmv_txn_done(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN uint64_t key, IN boolean_t is_in_cb)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_txn_ctx_t *p_ctx;
|
|
Packit |
13e616 |
osmv_bind_obj_t *const p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(h_bind);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Cancel the (single) timeout possibly outstanding for this txn
|
|
Packit |
13e616 |
* Don't do this if you are in the callback context, for 2 reasons:
|
|
Packit |
13e616 |
* (1) The event wheel will remove the context itself.
|
|
Packit |
13e616 |
* (2) If we try to, there is a deadlock in the event wheel
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (FALSE == is_in_cb) {
|
|
Packit |
13e616 |
osmv_txn_remove_timeout_ev(h_bind, key);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Remove from DB */
|
|
Packit |
13e616 |
if (IB_NOT_FOUND ==
|
|
Packit |
13e616 |
__osmv_txnmgr_remove_txn(&p_bo->txn_mgr, key, &p_ctx)) {
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Destroy the transaction's RMPP contexts
|
|
Packit |
13e616 |
* (can be more than one in the case of double sided transfer)
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_ctx->rmpp_txfr.p_rmpp_send_ctx) {
|
|
Packit |
13e616 |
osmv_rmpp_send_ctx_done(p_ctx->rmpp_txfr.p_rmpp_send_ctx);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_ctx->rmpp_txfr.p_rmpp_recv_ctx) {
|
|
Packit |
13e616 |
osmv_rmpp_recv_ctx_done(p_ctx->rmpp_txfr.p_rmpp_recv_ctx);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p_ctx);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_txn_lookup(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN uint64_t key, OUT osmv_txn_ctx_t ** pp_txn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
return __osmv_txnmgr_lookup(&(((osmv_bind_obj_t *) h_bind)->txn_mgr),
|
|
Packit |
13e616 |
key, pp_txn);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osmv_txn_abort_rmpp_txns(osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
cl_map_item_t *p_item;
|
|
Packit |
13e616 |
cl_map_obj_t *p_obj;
|
|
Packit |
13e616 |
osmv_txn_ctx_t *p_txn;
|
|
Packit |
13e616 |
osmv_rmpp_send_ctx_t *p_send_ctx;
|
|
Packit |
13e616 |
cl_qmap_t *p_map = p_bo->txn_mgr.p_txn_map;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
while (FALSE == cl_is_qmap_empty(p_map)) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_item = cl_qmap_head(p_map);
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_map_obj_t, item);
|
|
Packit |
13e616 |
p_txn = (osmv_txn_ctx_t *) cl_qmap_obj(p_obj);
|
|
Packit |
13e616 |
p_send_ctx = osmv_txn_get_rmpp_send_ctx(p_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (NULL != p_send_ctx) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_send_ctx->status = IB_INTERRUPTED;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Wake up the sender thread to let it break out */
|
|
Packit |
13e616 |
cl_event_signal(&p_send_ctx->event);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qmap_remove_item(p_map, p_item);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osmv_txnmgr_init(IN osmv_txn_mgr_t * p_tx_mgr,
|
|
Packit |
13e616 |
IN osm_log_t * p_log, IN cl_spinlock_t * p_lock)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_status_t cl_st = CL_SUCCESS;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tx_mgr->p_event_wheel = malloc(sizeof(cl_event_wheel_t));
|
|
Packit |
13e616 |
if (!p_tx_mgr->p_event_wheel) {
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_tx_mgr->p_event_wheel, 0, sizeof(cl_event_wheel_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_event_wheel_construct(p_tx_mgr->p_event_wheel);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* NOTE! We are using an extended constructor.
|
|
Packit |
13e616 |
* We tell the Event Wheel run in a non-protected manner in the reg/unreg calls,
|
|
Packit |
13e616 |
* and acquire an external lock in the asynchronous callback.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
cl_st = cl_event_wheel_init_ex(p_tx_mgr->p_event_wheel, p_lock);
|
|
Packit |
13e616 |
if (cl_st != CL_SUCCESS) {
|
|
Packit |
13e616 |
free(p_tx_mgr->p_event_wheel);
|
|
Packit |
13e616 |
return (ib_api_status_t) cl_st;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tx_mgr->p_txn_map = malloc(sizeof(cl_qmap_t));
|
|
Packit |
13e616 |
if (!p_tx_mgr->p_txn_map) {
|
|
Packit |
13e616 |
cl_event_wheel_destroy(p_tx_mgr->p_event_wheel);
|
|
Packit |
13e616 |
free(p_tx_mgr->p_event_wheel);
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_tx_mgr->p_txn_map, 0, sizeof(cl_qmap_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qmap_init(p_tx_mgr->p_txn_map);
|
|
Packit |
13e616 |
p_tx_mgr->p_log = p_log;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return cl_st;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osmv_txnmgr_done(IN osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
__osmv_txn_all_done(h_bind);
|
|
Packit |
13e616 |
free(p_bo->txn_mgr.p_txn_map);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_event_wheel_destroy(p_bo->txn_mgr.p_event_wheel);
|
|
Packit |
13e616 |
free(p_bo->txn_mgr.p_event_wheel);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
__osmv_txnmgr_lookup(IN osmv_txn_mgr_t * p_tx_mgr,
|
|
Packit |
13e616 |
IN uint64_t key, OUT osmv_txn_ctx_t ** pp_txn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
cl_map_item_t *p_item;
|
|
Packit |
13e616 |
cl_map_obj_t *p_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
uint64_t tmp_key;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_tx_mgr->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_tx_mgr);
|
|
Packit |
13e616 |
CL_ASSERT(pp_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_tx_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osmv_txnmgr_lookup: "
|
|
Packit |
13e616 |
"Looking for key: 0x%016" PRIx64 " in map ptr:%p\n", key,
|
|
Packit |
13e616 |
p_tx_mgr->p_txn_map);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_item = cl_qmap_head(p_tx_mgr->p_txn_map);
|
|
Packit |
13e616 |
while (p_item != cl_qmap_end(p_tx_mgr->p_txn_map)) {
|
|
Packit |
13e616 |
tmp_key = cl_qmap_key(p_item);
|
|
Packit |
13e616 |
osm_log(p_tx_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osmv_txnmgr_lookup: "
|
|
Packit |
13e616 |
"Found key 0x%016" PRIx64 "\n", tmp_key);
|
|
Packit |
13e616 |
p_item = cl_qmap_next(p_item);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_item = cl_qmap_get(p_tx_mgr->p_txn_map, key);
|
|
Packit |
13e616 |
if (cl_qmap_end(p_tx_mgr->p_txn_map) == p_item) {
|
|
Packit |
13e616 |
status = IB_NOT_FOUND;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_map_obj_t, item);
|
|
Packit |
13e616 |
*pp_txn = cl_qmap_obj(p_obj);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_tx_mgr->p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
__osmv_txnmgr_insert_txn(IN osmv_txn_mgr_t * p_tx_mgr,
|
|
Packit |
13e616 |
IN osmv_txn_ctx_t * p_txn, IN uint64_t key)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_map_obj_t *p_obj = NULL;
|
|
Packit |
13e616 |
cl_map_item_t *p_item;
|
|
Packit |
13e616 |
uint64_t tmp_key;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_tx_mgr);
|
|
Packit |
13e616 |
CL_ASSERT(p_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
key = osmv_txn_get_key(p_txn);
|
|
Packit |
13e616 |
p_obj = malloc(sizeof(cl_map_obj_t));
|
|
Packit |
13e616 |
if (NULL == p_obj)
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_tx_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osmv_txnmgr_insert_txn: "
|
|
Packit |
13e616 |
"Inserting key: 0x%016" PRIx64 " to map ptr:%p\n", key,
|
|
Packit |
13e616 |
p_tx_mgr->p_txn_map);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_obj, 0, sizeof(cl_map_obj_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qmap_set_obj(p_obj, p_txn);
|
|
Packit |
13e616 |
/* assuming lookup with this key was made and the result was IB_NOT_FOUND */
|
|
Packit |
13e616 |
cl_qmap_insert(p_tx_mgr->p_txn_map, key, &p_obj->item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_item = cl_qmap_head(p_tx_mgr->p_txn_map);
|
|
Packit |
13e616 |
while (p_item != cl_qmap_end(p_tx_mgr->p_txn_map)) {
|
|
Packit |
13e616 |
tmp_key = cl_qmap_key(p_item);
|
|
Packit |
13e616 |
osm_log(p_tx_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osmv_txnmgr_insert_txn: "
|
|
Packit |
13e616 |
"Found key 0x%016" PRIx64 "\n", tmp_key);
|
|
Packit |
13e616 |
p_item = cl_qmap_next(p_item);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return IB_SUCCESS;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
__osmv_txnmgr_remove_txn(IN osmv_txn_mgr_t * p_tx_mgr,
|
|
Packit |
13e616 |
IN uint64_t key, OUT osmv_txn_ctx_t ** pp_txn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_map_obj_t *p_obj;
|
|
Packit |
13e616 |
cl_map_item_t *p_item;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_tx_mgr->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_tx_mgr);
|
|
Packit |
13e616 |
CL_ASSERT(pp_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_item = cl_qmap_remove(p_tx_mgr->p_txn_map, key);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_item == cl_qmap_end(p_tx_mgr->p_txn_map)) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_tx_mgr->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"__osmv_txnmgr_remove_txn: ERR 6701: "
|
|
Packit |
13e616 |
"Could not remove the transaction 0x%016" PRIx64 " - "
|
|
Packit |
13e616 |
"something is really wrong!\n", key);
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_tx_mgr->p_log);
|
|
Packit |
13e616 |
return IB_NOT_FOUND;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_map_obj_t, item);
|
|
Packit |
13e616 |
*pp_txn = cl_qmap_obj(p_obj);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p_obj);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_tx_mgr->p_log);
|
|
Packit |
13e616 |
return IB_SUCCESS;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void __osmv_txn_all_done(osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
cl_map_item_t *p_item;
|
|
Packit |
13e616 |
cl_map_obj_t *p_obj;
|
|
Packit |
13e616 |
osmv_txn_ctx_t *p_txn;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_item = cl_qmap_head(p_bo->txn_mgr.p_txn_map);
|
|
Packit |
13e616 |
while (p_item != cl_qmap_end(p_bo->txn_mgr.p_txn_map)) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_map_obj_t, item);
|
|
Packit |
13e616 |
p_txn = (osmv_txn_ctx_t *) cl_qmap_obj(p_obj);
|
|
Packit |
13e616 |
osmv_txn_done(h_bind, osmv_txn_get_key(p_txn), FALSE);
|
|
Packit |
13e616 |
free(p_obj);
|
|
Packit |
13e616 |
/* assuming osmv_txn_done has removed the txn from the map */
|
|
Packit |
13e616 |
p_item = cl_qmap_head(p_bo->txn_mgr.p_txn_map);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/******************************************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osmv_txn_lock(IN osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"--> Acquiring lock %p on bind handle %p\n", &p_bo->lock, p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_bo->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"--> Acquired lock %p on bind handle %p\n", &p_bo->lock, p_bo);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osmv_txn_unlock(IN osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
cl_spinlock_t *p_lock = &p_bo->lock;
|
|
Packit |
13e616 |
osm_log_t *p_log = p_bo->p_vendor->p_log;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"<-- Releasing lock %p on bind handle %p\n", p_lock, p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_release(&p_bo->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* We'll use the saved ptrs, since now the p_bo can be destroyed already */
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"<-- Released lock %p on bind handle %p\n", p_lock, p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static uint64_t
|
|
Packit |
13e616 |
__osmv_txn_timeout_cb(IN uint64_t key,
|
|
Packit |
13e616 |
IN uint32_t num_regs, IN void *cb_context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) cb_context;
|
|
Packit |
13e616 |
uint64_t ret = 0;
|
|
Packit |
13e616 |
osmv_txn_ctx_t *p_txn;
|
|
Packit |
13e616 |
osmv_rmpp_send_ctx_t *p_send_ctx;
|
|
Packit |
13e616 |
osm_madw_t *p_madw = NULL;
|
|
Packit |
13e616 |
ib_mad_t *p_mad;
|
|
Packit |
13e616 |
osm_mad_addr_t *p_mad_addr;
|
|
Packit |
13e616 |
boolean_t invoke_err_cb = FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Don't try to acquire a lock on the Bind Object -
|
|
Packit |
13e616 |
* it's taken by the mechanism that drives the timeout based events!
|
|
Packit |
13e616 |
* (Recall the special constructor that the Event Wheel is applied with)
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_bo->is_closing) {
|
|
Packit |
13e616 |
goto txn_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = osmv_txn_lookup(p_bo, key, &p_txn);
|
|
Packit |
13e616 |
if (IB_NOT_FOUND == ret) {
|
|
Packit |
13e616 |
/* Prevent a race - the transaction is already destroyed */
|
|
Packit |
13e616 |
goto txn_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_madw = p_txn->p_madw;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
switch (osmv_txn_get_rmpp_state(p_txn)) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case OSMV_TXN_RMPP_NONE:
|
|
Packit |
13e616 |
if (num_regs <= OSM_DEFAULT_RETRY_COUNT) {
|
|
Packit |
13e616 |
/* We still did not exceed the limit of retransmissions.
|
|
Packit |
13e616 |
* Set the next timeout's value.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osmv_txn_timeout_cb: "
|
|
Packit |
13e616 |
"The transaction request (tid=0x%016" PRIx64 ")"
|
|
Packit |
13e616 |
" timed out %d times. Retrying the send.\n",
|
|
Packit |
13e616 |
osmv_txn_get_tid(p_txn), num_regs);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* resend this mad */
|
|
Packit |
13e616 |
ret = osmv_simple_send_madw((osm_bind_handle_t *) p_bo,
|
|
Packit |
13e616 |
p_madw, p_txn, TRUE);
|
|
Packit |
13e616 |
if (ret != IB_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"__osmv_txn_timeout_cb: "
|
|
Packit |
13e616 |
"Fail to send retry for transaction"
|
|
Packit |
13e616 |
"request (tid=0x%016" PRIx64 ").\n",
|
|
Packit |
13e616 |
osmv_txn_get_tid(p_txn));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_txn_done((osm_bind_handle_t) p_bo, key,
|
|
Packit |
13e616 |
TRUE /*in timeout callback */ );
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* This is a requester. Always apply the callback */
|
|
Packit |
13e616 |
invoke_err_cb = TRUE;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
uint64_t next_timeout_ms;
|
|
Packit |
13e616 |
next_timeout_ms =
|
|
Packit |
13e616 |
p_bo->p_vendor->resp_timeout * (num_regs +
|
|
Packit |
13e616 |
1) *
|
|
Packit |
13e616 |
(num_regs + 1);
|
|
Packit |
13e616 |
/* when do we need to timeout again */
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
cl_get_time_stamp() +
|
|
Packit |
13e616 |
(uint64_t) (1000 * next_timeout_ms);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osmv_txn_timeout_cb: "
|
|
Packit |
13e616 |
"Retry request timout in : %lu [msec].\n",
|
|
Packit |
13e616 |
next_timeout_ms);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"__osmv_txn_timeout_cb: ERR 6702: "
|
|
Packit |
13e616 |
"The transaction request (0x%016" PRIx64 ") "
|
|
Packit |
13e616 |
"timed out (after %d retries). "
|
|
Packit |
13e616 |
"Invoking the error callback.\n",
|
|
Packit |
13e616 |
osmv_txn_get_tid(p_txn), num_regs);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_txn_done((osm_bind_handle_t) p_bo, key,
|
|
Packit |
13e616 |
TRUE /*in timeout callback */ );
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* This is a requester. Always apply the callback */
|
|
Packit |
13e616 |
invoke_err_cb = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case OSMV_TXN_RMPP_SENDER:
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"RMPP sender (tid=0x%016" PRIx64 ") did not receive ACK "
|
|
Packit |
13e616 |
"on every segment in the current send window.\n",
|
|
Packit |
13e616 |
osmv_txn_get_tid(p_txn));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_send_ctx = osmv_txn_get_rmpp_send_ctx(p_txn);
|
|
Packit |
13e616 |
if (num_regs <= OSM_DEFAULT_RETRY_COUNT) {
|
|
Packit |
13e616 |
/* We still did not exceed the limit of retransmissions.
|
|
Packit |
13e616 |
* Set the next timeout's value.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
ret =
|
|
Packit |
13e616 |
cl_get_time_stamp() +
|
|
Packit |
13e616 |
1000 * p_bo->p_vendor->resp_timeout;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
p_send_ctx->status = IB_TIMEOUT;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mad = osm_madw_get_mad_ptr(p_madw);
|
|
Packit |
13e616 |
p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Send an ABORT to the other side */
|
|
Packit |
13e616 |
osmv_rmpp_send_nak((osm_bind_handle_t) p_bo, p_mad,
|
|
Packit |
13e616 |
p_mad_addr, IB_RMPP_TYPE_ABORT,
|
|
Packit |
13e616 |
IB_RMPP_STATUS_T2L);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Wake the RMPP sender thread up */
|
|
Packit |
13e616 |
cl_event_signal(&p_send_ctx->event);
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case OSMV_TXN_RMPP_RECEIVER:
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Transaction timeout on an RMPP receiver "
|
|
Packit |
13e616 |
"(tid=0x%016" PRIx64 "). Dropping the transaction.\n",
|
|
Packit |
13e616 |
osmv_txn_get_tid(p_txn));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_txn_done((osm_bind_handle_t) p_bo, key,
|
|
Packit |
13e616 |
TRUE /*in timeout callback */ );
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (FALSE == osmv_txn_is_rmpp_init_by_peer(p_txn)) {
|
|
Packit |
13e616 |
/* This is a requester, still waiting for the reply. Apply the callback */
|
|
Packit |
13e616 |
invoke_err_cb = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
default:
|
|
Packit |
13e616 |
CL_ASSERT(FALSE);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == invoke_err_cb) {
|
|
Packit |
13e616 |
CL_ASSERT(NULL != p_madw);
|
|
Packit |
13e616 |
/* update the status in the p_madw */
|
|
Packit |
13e616 |
p_madw->status = IB_TIMEOUT;
|
|
Packit |
13e616 |
p_bo->send_err_cb(p_bo->cb_context, p_madw);
|
|
Packit |
13e616 |
/* no re-registration */
|
|
Packit |
13e616 |
ret = 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
txn_done:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|