|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2005 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 <math.h>
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <opensm/osm_helper.h>
|
|
Packit |
13e616 |
#include <opensm/osm_log.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_api.h>
|
|
Packit |
13e616 |
#include <opensm/osm_mad_pool.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if defined(OSM_VENDOR_INTF_MTL) | defined(OSM_VENDOR_INTF_TS)
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mtl_transaction_mgr.h>
|
|
Packit |
13e616 |
#ifdef OSM_VENDOR_INTF_MTL
|
|
Packit |
13e616 |
#include <vendor/osm_mtl_bind.h>
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* this is the callback function of the timer */
|
|
Packit |
13e616 |
void __osm_transaction_mgr_callback(IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_transaction_mgr_t *trans_mgr_p;
|
|
Packit |
13e616 |
osm_vendor_t *p_vend = (osm_vendor_t *) context;
|
|
Packit |
13e616 |
cl_list_item_t *p_list_item;
|
|
Packit |
13e616 |
cl_list_item_t *p_list_next_item;
|
|
Packit |
13e616 |
osm_madw_req_t *osm_madw_req_p;
|
|
Packit |
13e616 |
uint64_t current_time; /* [usec] */
|
|
Packit |
13e616 |
uint32_t new_timeout; /* [msec] */
|
|
Packit |
13e616 |
cl_status_t cl_status;
|
|
Packit |
13e616 |
ib_mad_t *p_mad;
|
|
Packit |
13e616 |
#ifdef OSM_VENDOR_INTF_MTL
|
|
Packit |
13e616 |
osm_mtl_bind_info_t *p_bind;
|
|
Packit |
13e616 |
#else
|
|
Packit |
13e616 |
osm_ts_bind_info_t *p_bind;
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
cl_list_t tmp_madw_p_list; /* this list will include all the madw_p that should be removed. */
|
|
Packit |
13e616 |
cl_list_t retry_madw_p_list; /* this list will include all the madw_p that were retried and need to be removed. */
|
|
Packit |
13e616 |
osm_madw_t *madw_p;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* initialize the tmp_madw_p_list */
|
|
Packit |
13e616 |
cl_list_construct(&tmp_madw_p_list);
|
|
Packit |
13e616 |
cl_status = cl_list_init(&tmp_madw_p_list, 50);
|
|
Packit |
13e616 |
if (cl_status != CL_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"__osm_transaction_mgr_callback : ERROR 1000: "
|
|
Packit |
13e616 |
"Failed to create tmp_madw_p_list\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_construct(&retry_madw_p_list);
|
|
Packit |
13e616 |
cl_status = cl_list_init(&retry_madw_p_list, 50);
|
|
Packit |
13e616 |
if (cl_status != CL_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"__osm_transaction_mgr_callback : ERROR 1000: "
|
|
Packit |
13e616 |
"Failed to create retry_madw_p_list\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
current_time = cl_get_time_stamp();
|
|
Packit |
13e616 |
cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock));
|
|
Packit |
13e616 |
p_list_item = cl_qlist_head(trans_mgr_p->madw_reqs_list_p);
|
|
Packit |
13e616 |
if (p_list_item == cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) {
|
|
Packit |
13e616 |
/* the list is empty - nothing to do */
|
|
Packit |
13e616 |
cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock);
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_transaction_mgr_callback : Nothing to do\n");
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* non empty list: */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* get the osm_madw_req_p */
|
|
Packit |
13e616 |
osm_madw_req_p = PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
while (osm_madw_req_p->waking_time <= current_time) {
|
|
Packit |
13e616 |
/* this object was supposed to have gotten a response */
|
|
Packit |
13e616 |
/* we need to decide if we need to retry or done with it. */
|
|
Packit |
13e616 |
if (osm_madw_req_p->retry_cnt > 0) {
|
|
Packit |
13e616 |
/* add to the list of the retrys : */
|
|
Packit |
13e616 |
cl_list_insert_tail(&retry_madw_p_list, osm_madw_req_p);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* update wakeup time and retry count */
|
|
Packit |
13e616 |
osm_madw_req_p->waking_time =
|
|
Packit |
13e616 |
p_vend->timeout * 1000 + cl_get_time_stamp();
|
|
Packit |
13e616 |
osm_madw_req_p->retry_cnt--;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* make sure we will get some timer call if not earlier */
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_transaction_mgr_callback : Timer restart:%u\n",
|
|
Packit |
13e616 |
p_vend->timeout);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_status =
|
|
Packit |
13e616 |
cl_timer_start(&trans_mgr_p->madw_list_timer,
|
|
Packit |
13e616 |
p_vend->timeout);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* go to the next object and check if it also needs to be removed - didn't receive response */
|
|
Packit |
13e616 |
/* we need to do it before we move current item to the end of the list */
|
|
Packit |
13e616 |
p_list_next_item = cl_qlist_next(p_list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* remove from the head */
|
|
Packit |
13e616 |
cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p,
|
|
Packit |
13e616 |
&(osm_madw_req_p->list_item));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* insert the object to the qlist and the qmap */
|
|
Packit |
13e616 |
cl_qlist_insert_tail(trans_mgr_p->madw_reqs_list_p,
|
|
Packit |
13e616 |
&(osm_madw_req_p->list_item));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* go to the next object and check if it also needs to be removed - didn't receive response */
|
|
Packit |
13e616 |
p_list_next_item = cl_qlist_next(p_list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* remove from the head */
|
|
Packit |
13e616 |
cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p,
|
|
Packit |
13e616 |
&(osm_madw_req_p->list_item));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* add it to the tmp_madw_p_list to be removed */
|
|
Packit |
13e616 |
cl_list_insert_tail(&tmp_madw_p_list,
|
|
Packit |
13e616 |
osm_madw_req_p->p_madw);
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_transaction_mgr_callback : Found failed transaction madw: %p\n",
|
|
Packit |
13e616 |
osm_madw_req_p->p_madw);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Advance */
|
|
Packit |
13e616 |
p_list_item = p_list_next_item;
|
|
Packit |
13e616 |
if (p_list_item == cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) {
|
|
Packit |
13e616 |
/* the list is empty - nothing to do */
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* get the osm_madw_req_p */
|
|
Packit |
13e616 |
osm_madw_req_p =
|
|
Packit |
13e616 |
PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* look at the current p_list_item. If it is not the end item - then we need to */
|
|
Packit |
13e616 |
/* re-start the timer */
|
|
Packit |
13e616 |
if (p_list_item != cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) {
|
|
Packit |
13e616 |
/* get the osm_madw_req_p */
|
|
Packit |
13e616 |
osm_madw_req_p =
|
|
Packit |
13e616 |
PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* we have the object that still didn't get response - re-start the timer */
|
|
Packit |
13e616 |
/* start the timer to the timeout (in miliseconds) */
|
|
Packit |
13e616 |
new_timeout =
|
|
Packit |
13e616 |
(osm_madw_req_p->waking_time - cl_get_time_stamp()) / 1000 +
|
|
Packit |
13e616 |
1;
|
|
Packit |
13e616 |
cl_status =
|
|
Packit |
13e616 |
cl_timer_start(&trans_mgr_p->madw_list_timer, new_timeout);
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_transaction_mgr_callback : Timer restart:%u\n",
|
|
Packit |
13e616 |
new_timeout);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_status != CL_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"__osm_transaction_mgr_callback : ERROR 1000: "
|
|
Packit |
13e616 |
"Failed to start timer\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* if not empty - retry on retry list: */
|
|
Packit |
13e616 |
if (!cl_is_list_empty(&retry_madw_p_list)) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* remove all elements that were retried: */
|
|
Packit |
13e616 |
osm_madw_req_p =
|
|
Packit |
13e616 |
(osm_madw_req_t
|
|
Packit |
13e616 |
*) (cl_list_remove_head(&retry_madw_p_list));
|
|
Packit |
13e616 |
while (osm_madw_req_p != NULL) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* resend: */
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_transaction_mgr_callback : "
|
|
Packit |
13e616 |
"Retry %d of madw %p\n",
|
|
Packit |
13e616 |
OSM_DEFAULT_RETRY_COUNT -
|
|
Packit |
13e616 |
osm_madw_req_p->retry_cnt,
|
|
Packit |
13e616 |
osm_madw_req_p->p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* actually send it */
|
|
Packit |
13e616 |
#ifdef OSM_VENDOR_INTF_MTL
|
|
Packit |
13e616 |
osm_mtl_send_mad((osm_mtl_bind_info_t *)
|
|
Packit |
13e616 |
osm_madw_req_p->p_bind,
|
|
Packit |
13e616 |
osm_madw_req_p->p_madw);
|
|
Packit |
13e616 |
#else
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_ts_send_mad(osm_ts_bind_info_t * p_bind,
|
|
Packit |
13e616 |
osm_madw_t * const p_madw);
|
|
Packit |
13e616 |
osm_ts_send_mad((osm_ts_bind_info_t *) osm_madw_req_p->
|
|
Packit |
13e616 |
p_bind, osm_madw_req_p->p_madw);
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
/* next one */
|
|
Packit |
13e616 |
osm_madw_req_p =
|
|
Packit |
13e616 |
(osm_madw_req_t
|
|
Packit |
13e616 |
*) (cl_list_remove_head(&retry_madw_p_list));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* if the tmp_madw_p_list has elements - need to call the send_err_callback */
|
|
Packit |
13e616 |
madw_p = (osm_madw_t *) (cl_list_remove_head(&tmp_madw_p_list));
|
|
Packit |
13e616 |
while (madw_p != NULL) {
|
|
Packit |
13e616 |
/* need to remove it from pool */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* obtain the madw_p stored as the wrid in the send call */
|
|
Packit |
13e616 |
p_mad = osm_madw_get_mad_ptr(madw_p);
|
|
Packit |
13e616 |
p_bind = madw_p->h_bind;
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Return any wrappers to the pool that may have been
|
|
Packit |
13e616 |
pre-emptively allocated to handle a receive.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (madw_p->vend_wrap.p_resp_madw) {
|
|
Packit |
13e616 |
#ifdef OSM_VENDOR_INTF_MTL
|
|
Packit |
13e616 |
osm_mad_pool_put(p_bind->p_osm_pool,
|
|
Packit |
13e616 |
madw_p->vend_wrap.p_resp_madw);
|
|
Packit |
13e616 |
#else
|
|
Packit |
13e616 |
osm_mad_pool_put(p_bind->p_osm_pool,
|
|
Packit |
13e616 |
madw_p->vend_wrap.p_resp_madw);
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
madw_p->vend_wrap.p_resp_madw = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* invoke the CB */
|
|
Packit |
13e616 |
(*(osm_vend_mad_send_err_callback_t)
|
|
Packit |
13e616 |
(p_bind->send_err_callback)) (p_bind->client_context, madw_p);
|
|
Packit |
13e616 |
madw_p = (osm_madw_t *) (cl_list_remove_head(&tmp_madw_p_list));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Construct and Initialize
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_transaction_mgr_init(IN osm_vendor_t * const p_vend)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_status_t cl_status;
|
|
Packit |
13e616 |
osm_transaction_mgr_t *trans_mgr_p;
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_vend->p_transaction_mgr == NULL);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
(osm_transaction_mgr_t *) p_vend->p_transaction_mgr =
|
|
Packit |
13e616 |
(osm_transaction_mgr_t *) malloc(sizeof(osm_transaction_mgr_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* construct lock object */
|
|
Packit |
13e616 |
cl_spinlock_construct(&(trans_mgr_p->transaction_mgr_lock));
|
|
Packit |
13e616 |
CL_ASSERT(cl_spinlock_init(&(trans_mgr_p->transaction_mgr_lock)) ==
|
|
Packit |
13e616 |
CL_SUCCESS);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* initialize the qlist */
|
|
Packit |
13e616 |
trans_mgr_p->madw_reqs_list_p =
|
|
Packit |
13e616 |
(cl_qlist_t *) malloc(sizeof(cl_qlist_t));
|
|
Packit |
13e616 |
cl_qlist_init(trans_mgr_p->madw_reqs_list_p);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* initialize the qmap */
|
|
Packit |
13e616 |
trans_mgr_p->madw_by_tid_map_p =
|
|
Packit |
13e616 |
(cl_qmap_t *) malloc(sizeof(cl_qmap_t));
|
|
Packit |
13e616 |
cl_qmap_init(trans_mgr_p->madw_by_tid_map_p);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* create the timer used by the madw_req_list */
|
|
Packit |
13e616 |
cl_timer_construct(&(trans_mgr_p->madw_list_timer));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* init the timer with timeout. */
|
|
Packit |
13e616 |
cl_status = cl_timer_init(&trans_mgr_p->madw_list_timer,
|
|
Packit |
13e616 |
__osm_transaction_mgr_callback, p_vend);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_status != CL_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_transaction_mgr_init : ERROR 1000: "
|
|
Packit |
13e616 |
"Failed to initialize madw_reqs_list timer\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_transaction_mgr_destroy(IN osm_vendor_t * const p_vend)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_transaction_mgr_t *trans_mgr_p;
|
|
Packit |
13e616 |
cl_list_item_t *p_list_item;
|
|
Packit |
13e616 |
cl_map_item_t *p_map_item;
|
|
Packit |
13e616 |
osm_madw_req_t *osm_madw_req_p;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_vend->p_transaction_mgr != NULL) {
|
|
Packit |
13e616 |
/* we need to get a lock */
|
|
Packit |
13e616 |
cl_spinlock_acquire(&trans_mgr_p->transaction_mgr_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* go over all the items in the list and remove them */
|
|
Packit |
13e616 |
p_list_item =
|
|
Packit |
13e616 |
cl_qlist_remove_head(trans_mgr_p->madw_reqs_list_p);
|
|
Packit |
13e616 |
while (p_list_item !=
|
|
Packit |
13e616 |
cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) {
|
|
Packit |
13e616 |
osm_madw_req_p = (osm_madw_req_t *) p_list_item;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (osm_madw_req_p->p_madw->p_mad)
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_destroy: "
|
|
Packit |
13e616 |
"Found outstanding MADW:%p TID:<0x%"
|
|
Packit |
13e616 |
PRIx64 ">.\n", osm_madw_req_p->p_madw,
|
|
Packit |
13e616 |
osm_madw_req_p->p_madw->p_mad->
|
|
Packit |
13e616 |
trans_id);
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_destroy: "
|
|
Packit |
13e616 |
"Found outstanding MADW:%p TID:UNDEFINED.\n",
|
|
Packit |
13e616 |
osm_madw_req_p->p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* each item - remove it from the map */
|
|
Packit |
13e616 |
p_map_item = &(osm_madw_req_p->map_item);
|
|
Packit |
13e616 |
cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p,
|
|
Packit |
13e616 |
p_map_item);
|
|
Packit |
13e616 |
/* free the item */
|
|
Packit |
13e616 |
free(osm_madw_req_p);
|
|
Packit |
13e616 |
p_list_item =
|
|
Packit |
13e616 |
cl_qlist_remove_head(trans_mgr_p->madw_reqs_list_p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* free the qlist and qmap */
|
|
Packit |
13e616 |
free(trans_mgr_p->madw_reqs_list_p);
|
|
Packit |
13e616 |
free(trans_mgr_p->madw_by_tid_map_p);
|
|
Packit |
13e616 |
/* reliease and destroy the lock */
|
|
Packit |
13e616 |
cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock);
|
|
Packit |
13e616 |
cl_spinlock_destroy(&(trans_mgr_p->transaction_mgr_lock));
|
|
Packit |
13e616 |
/* destroy the timer */
|
|
Packit |
13e616 |
cl_timer_trim(&trans_mgr_p->madw_list_timer, 1);
|
|
Packit |
13e616 |
cl_timer_destroy(&trans_mgr_p->madw_list_timer);
|
|
Packit |
13e616 |
/* free the transaction_manager object */
|
|
Packit |
13e616 |
free(trans_mgr_p);
|
|
Packit |
13e616 |
trans_mgr_p = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_transaction_mgr_insert_madw(IN osm_bind_handle_t * const p_bind,
|
|
Packit |
13e616 |
IN osm_madw_t * p_madw)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
#ifdef OSM_VENDOR_INTF_MTL
|
|
Packit |
13e616 |
osm_vendor_t *const p_vend = ((osm_mtl_bind_info_t *) p_bind)->p_vend;
|
|
Packit |
13e616 |
#else
|
|
Packit |
13e616 |
osm_vendor_t *const p_vend = ((osm_ts_bind_info_t *) p_bind)->p_vend;
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
osm_transaction_mgr_t *trans_mgr_p;
|
|
Packit |
13e616 |
osm_madw_req_t *osm_madw_req_p;
|
|
Packit |
13e616 |
uint64_t timeout;
|
|
Packit |
13e616 |
uint64_t waking_time;
|
|
Packit |
13e616 |
cl_status_t cl_status;
|
|
Packit |
13e616 |
uint64_t key;
|
|
Packit |
13e616 |
const ib_mad_t *mad_p = p_madw->p_mad;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(mad_p);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
timeout = (uint64_t) (p_vend->timeout) * 1000; /* change the miliseconds value of timeout to microseconds. */
|
|
Packit |
13e616 |
waking_time = timeout + cl_get_time_stamp();
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_madw_req_p = (osm_madw_req_t *) malloc(sizeof(osm_madw_req_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_madw_req_p->p_madw = p_madw;
|
|
Packit |
13e616 |
osm_madw_req_p->waking_time = waking_time;
|
|
Packit |
13e616 |
osm_madw_req_p->retry_cnt = OSM_DEFAULT_RETRY_COUNT;
|
|
Packit |
13e616 |
osm_madw_req_p->p_bind = p_bind;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_insert_madw: "
|
|
Packit |
13e616 |
"Inserting MADW:%p with waking_time: <0x%" PRIx64 "> TID:<0x%"
|
|
Packit |
13e616 |
PRIx64 ">.\n", p_madw, waking_time, p_madw->p_mad->trans_id);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Get the lock on the manager */
|
|
Packit |
13e616 |
cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock));
|
|
Packit |
13e616 |
/* If the list is empty - need to start the timer with timer of timeout (in miliseconds) */
|
|
Packit |
13e616 |
if (cl_is_qlist_empty(trans_mgr_p->madw_reqs_list_p)) {
|
|
Packit |
13e616 |
/* stop the timer if it is running */
|
|
Packit |
13e616 |
cl_timer_stop(&trans_mgr_p->madw_list_timer);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* start the timer to the timeout (in miliseconds) */
|
|
Packit |
13e616 |
cl_status = cl_timer_start(&trans_mgr_p->madw_list_timer,
|
|
Packit |
13e616 |
p_vend->timeout);
|
|
Packit |
13e616 |
if (cl_status != CL_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_transaction_mgr_insert_madw : ERROR 1000: "
|
|
Packit |
13e616 |
"Failed to start timer\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* insert the object to the qlist and the qmap */
|
|
Packit |
13e616 |
cl_qlist_insert_tail(trans_mgr_p->madw_reqs_list_p,
|
|
Packit |
13e616 |
&(osm_madw_req_p->list_item));
|
|
Packit |
13e616 |
/* get the key */
|
|
Packit |
13e616 |
key = (uint64_t) mad_p->trans_id;
|
|
Packit |
13e616 |
cl_qmap_insert(trans_mgr_p->madw_by_tid_map_p, key,
|
|
Packit |
13e616 |
&(osm_madw_req_p->map_item));
|
|
Packit |
13e616 |
cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return (IB_SUCCESS);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_transaction_mgr_erase_madw(IN osm_vendor_t * const p_vend,
|
|
Packit |
13e616 |
IN ib_mad_t * p_mad)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_transaction_mgr_t *trans_mgr_p;
|
|
Packit |
13e616 |
osm_madw_req_t *osm_madw_req_p;
|
|
Packit |
13e616 |
uint64_t key;
|
|
Packit |
13e616 |
cl_map_item_t *p_map_item;
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
key = (uint64_t) p_mad->trans_id;
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_erase_madw: "
|
|
Packit |
13e616 |
"Removing TID:<0x%" PRIx64 ">.\n", p_mad->trans_id);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&trans_mgr_p->transaction_mgr_lock);
|
|
Packit |
13e616 |
p_map_item = cl_qmap_get(trans_mgr_p->madw_by_tid_map_p, key);
|
|
Packit |
13e616 |
if (p_map_item != cl_qmap_end(trans_mgr_p->madw_by_tid_map_p)) {
|
|
Packit |
13e616 |
/* we found such an item. */
|
|
Packit |
13e616 |
/* get the osm_madw_req_p */
|
|
Packit |
13e616 |
osm_madw_req_p =
|
|
Packit |
13e616 |
PARENT_STRUCT(p_map_item, osm_madw_req_t, map_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* remove the item from the qlist */
|
|
Packit |
13e616 |
cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p,
|
|
Packit |
13e616 |
&(osm_madw_req_p->list_item));
|
|
Packit |
13e616 |
/* remove the item from the qmap */
|
|
Packit |
13e616 |
cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p,
|
|
Packit |
13e616 |
&(osm_madw_req_p->map_item));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_erase_madw: "
|
|
Packit |
13e616 |
"Removed TID:<0x%" PRIx64 ">.\n", p_mad->trans_id);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* free the item */
|
|
Packit |
13e616 |
free(osm_madw_req_p);
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_erase_madw: "
|
|
Packit |
13e616 |
"osm_transaction_mgr_erase_madw:<0x%" PRIx64
|
|
Packit |
13e616 |
"> NOT FOUND.\n", p_mad->trans_id);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock);
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return (IB_SUCCESS);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_transaction_mgr_get_madw_for_tid(IN osm_vendor_t * const p_vend,
|
|
Packit |
13e616 |
IN ib_mad_t * const p_mad,
|
|
Packit |
13e616 |
OUT osm_madw_t ** req_madw_p)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_transaction_mgr_t *trans_mgr_p;
|
|
Packit |
13e616 |
osm_madw_req_t *osm_madw_req_p;
|
|
Packit |
13e616 |
cl_map_item_t *p_map_item;
|
|
Packit |
13e616 |
uint64_t key;
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
*req_madw_p = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_get_madw_for_tid: "
|
|
Packit |
13e616 |
"Looking for TID:<0x%" PRIx64 ">.\n", p_mad->trans_id);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
key = (uint64_t) p_mad->trans_id;
|
|
Packit |
13e616 |
cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock));
|
|
Packit |
13e616 |
p_map_item = cl_qmap_get(trans_mgr_p->madw_by_tid_map_p, key);
|
|
Packit |
13e616 |
if (p_map_item != cl_qmap_end(trans_mgr_p->madw_by_tid_map_p)) {
|
|
Packit |
13e616 |
/* we found such an item. */
|
|
Packit |
13e616 |
/* get the osm_madw_req_p */
|
|
Packit |
13e616 |
osm_madw_req_p =
|
|
Packit |
13e616 |
PARENT_STRUCT(p_map_item, osm_madw_req_t, map_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Since the Transaction was looked up and provided for */
|
|
Packit |
13e616 |
/* processing we retire it */
|
|
Packit |
13e616 |
cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p,
|
|
Packit |
13e616 |
&(osm_madw_req_p->list_item));
|
|
Packit |
13e616 |
/* remove the item from the qmap */
|
|
Packit |
13e616 |
cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p,
|
|
Packit |
13e616 |
&(osm_madw_req_p->map_item));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_get_madw_for_tid: "
|
|
Packit |
13e616 |
"Removed TID:<0x%" PRIx64 ">.\n", p_mad->trans_id);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
*req_madw_p = osm_madw_req_p->p_madw;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_release(&(trans_mgr_p->transaction_mgr_lock));
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_transaction_mgr_get_madw_for_tid: "
|
|
Packit |
13e616 |
"Got MADW:%p.\n", *req_madw_p);
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
return (IB_SUCCESS);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#endif
|