|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2010 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 |
/*
|
|
Packit |
13e616 |
* Abstract:
|
|
Packit |
13e616 |
* Implementation of osm_vl15_t.
|
|
Packit |
13e616 |
* This object represents the VL15 Interface object.
|
|
Packit |
13e616 |
* This object is part of the opensm family of objects.
|
|
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 <string.h>
|
|
Packit |
13e616 |
#include <iba/ib_types.h>
|
|
Packit |
13e616 |
#include <complib/cl_thread.h>
|
|
Packit |
13e616 |
#include <opensm/osm_file_ids.h>
|
|
Packit |
13e616 |
#define FILE_ID OSM_FILE_VL15INTF_C
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_api.h>
|
|
Packit |
13e616 |
#include <opensm/osm_vl15intf.h>
|
|
Packit |
13e616 |
#include <opensm/osm_madw.h>
|
|
Packit |
13e616 |
#include <opensm/osm_log.h>
|
|
Packit |
13e616 |
#include <opensm/osm_helper.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void vl15_send_mad(osm_vl15_t * p_vl, osm_madw_t * p_madw)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
boolean_t resp_expected = p_madw->resp_expected;
|
|
Packit |
13e616 |
ib_smp_t * p_smp;
|
|
Packit |
13e616 |
ib_net16_t attr_id;
|
|
Packit |
13e616 |
uint8_t method;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_smp = osm_madw_get_smp_ptr(p_madw);
|
|
Packit |
13e616 |
method = p_smp->method;
|
|
Packit |
13e616 |
attr_id = p_smp->attr_id;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Non-response-expected mads are not throttled on the wire
|
|
Packit |
13e616 |
since we can have no confirmation that they arrived
|
|
Packit |
13e616 |
at their destination.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (resp_expected)
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Note that other threads may not see the response MAD
|
|
Packit |
13e616 |
arrive before send() even returns.
|
|
Packit |
13e616 |
In that case, the wire count would temporarily go negative.
|
|
Packit |
13e616 |
To avoid this confusion, preincrement the counts on the
|
|
Packit |
13e616 |
assumption that send() will succeed.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
cl_atomic_inc(&p_vl->p_stats->qp0_mads_outstanding_on_wire);
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
cl_atomic_inc(&p_vl->p_stats->qp0_unicasts_sent);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_atomic_inc(&p_vl->p_stats->qp0_mads_sent);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_vendor_send(osm_madw_get_bind_handle(p_madw),
|
|
Packit |
13e616 |
p_madw, p_madw->resp_expected);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (status == IB_SUCCESS) {
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"%u QP0 MADs on wire, %u outstanding, "
|
|
Packit |
13e616 |
"%u unicasts sent, %u total sent\n",
|
|
Packit |
13e616 |
p_vl->p_stats->qp0_mads_outstanding_on_wire,
|
|
Packit |
13e616 |
p_vl->p_stats->qp0_mads_outstanding,
|
|
Packit |
13e616 |
p_vl->p_stats->qp0_unicasts_sent,
|
|
Packit |
13e616 |
p_vl->p_stats->qp0_mads_sent);
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_ERROR, "ERR 3E03: "
|
|
Packit |
13e616 |
"MAD send failed (%s)\n", ib_get_err_str(status));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
The MAD was never successfully sent, so
|
|
Packit |
13e616 |
fix up the pre-incremented count values.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Decrement qp0_mads_sent that were incremented in the code above.
|
|
Packit |
13e616 |
qp0_mads_outstanding will be decremented by send error callback
|
|
Packit |
13e616 |
(called by osm_vendor_send() */
|
|
Packit |
13e616 |
cl_atomic_dec(&p_vl->p_stats->qp0_mads_sent);
|
|
Packit |
13e616 |
if (!resp_expected) {
|
|
Packit |
13e616 |
cl_atomic_dec(&p_vl->p_stats->qp0_unicasts_sent);
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* need to cause heavy-sweep if resp_expected MAD sending failed */
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_ERROR, "ERR 3E04: "
|
|
Packit |
13e616 |
"%s method failed for attribute 0x%X (%s)\n",
|
|
Packit |
13e616 |
method == IB_MAD_METHOD_SET ? "SET" : "GET",
|
|
Packit |
13e616 |
cl_ntoh16(attr_id), ib_get_sm_attr_str(attr_id));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vl->p_subn->subnet_initialization_error = TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void vl15_poller(IN void *p_ptr)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
osm_madw_t *p_madw;
|
|
Packit |
13e616 |
osm_vl15_t *p_vl = p_ptr;
|
|
Packit |
13e616 |
cl_qlist_t *p_fifo;
|
|
Packit |
13e616 |
int32_t max_smps = p_vl->max_wire_smps;
|
|
Packit |
13e616 |
int32_t max_smps2 = p_vl->max_wire_smps2;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_vl->thread_state == OSM_THREAD_STATE_NONE)
|
|
Packit |
13e616 |
p_vl->thread_state = OSM_THREAD_STATE_RUN;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
while (p_vl->thread_state == OSM_THREAD_STATE_RUN) {
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Start servicing the FIFOs by pulling off MAD wrappers
|
|
Packit |
13e616 |
and passing them to the transport interface.
|
|
Packit |
13e616 |
There are lots of corner cases here so tread carefully.
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
The unicast FIFO has priority, since somebody is waiting
|
|
Packit |
13e616 |
for a timely response.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_vl->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_qlist_count(&p_vl->ufifo) != 0)
|
|
Packit |
13e616 |
p_fifo = &p_vl->ufifo;
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
p_fifo = &p_vl->rfifo;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(p_fifo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_release(&p_vl->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_madw != (osm_madw_t *) cl_qlist_end(p_fifo)) {
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Servicing p_madw = %p\n", p_madw);
|
|
Packit |
13e616 |
if (OSM_LOG_IS_ACTIVE_V2(p_vl->p_log, OSM_LOG_FRAMES))
|
|
Packit |
13e616 |
osm_dump_dr_smp_v2(p_vl->p_log,
|
|
Packit |
13e616 |
osm_madw_get_smp_ptr(p_madw),
|
|
Packit |
13e616 |
FILE_ID, OSM_LOG_FRAMES);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
vl15_send_mad(p_vl, p_madw);
|
|
Packit |
13e616 |
} else
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
The VL15 FIFO is empty, so we have nothing left to do.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
status = cl_event_wait_on(&p_vl->signal,
|
|
Packit |
13e616 |
EVENT_NO_TIMEOUT, TRUE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
while (p_vl->p_stats->qp0_mads_outstanding_on_wire >= max_smps &&
|
|
Packit |
13e616 |
p_vl->thread_state == OSM_THREAD_STATE_RUN) {
|
|
Packit |
13e616 |
status = cl_event_wait_on(&p_vl->signal,
|
|
Packit |
13e616 |
p_vl->max_smps_timeout,
|
|
Packit |
13e616 |
TRUE);
|
|
Packit |
13e616 |
if (status == CL_TIMEOUT) {
|
|
Packit |
13e616 |
if (max_smps < max_smps2)
|
|
Packit |
13e616 |
max_smps++;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
} else if (status != CL_SUCCESS) {
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_ERROR, "ERR 3E02: "
|
|
Packit |
13e616 |
"Event wait failed (%s)\n",
|
|
Packit |
13e616 |
CL_STATUS_MSG(status));
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
max_smps = p_vl->max_wire_smps;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
since we abort immediately when the state != OSM_THREAD_STATE_RUN
|
|
Packit |
13e616 |
we might have some mads on the queues. After the thread exits
|
|
Packit |
13e616 |
the vl15 destroy routine should put these mads back...
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vl->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vl15_construct(IN osm_vl15_t * p_vl)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
memset(p_vl, 0, sizeof(*p_vl));
|
|
Packit |
13e616 |
p_vl->state = OSM_VL15_STATE_INIT;
|
|
Packit |
13e616 |
p_vl->thread_state = OSM_THREAD_STATE_NONE;
|
|
Packit |
13e616 |
cl_event_construct(&p_vl->signal);
|
|
Packit |
13e616 |
cl_spinlock_construct(&p_vl->lock);
|
|
Packit |
13e616 |
cl_qlist_init(&p_vl->rfifo);
|
|
Packit |
13e616 |
cl_qlist_init(&p_vl->ufifo);
|
|
Packit |
13e616 |
cl_thread_construct(&p_vl->poller);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vl15_destroy(IN osm_vl15_t * p_vl, IN struct osm_mad_pool *p_pool)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_madw_t *p_madw;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Signal our threads that we're leaving.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
p_vl->thread_state = OSM_THREAD_STATE_EXIT;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Don't trigger unless event has been initialized.
|
|
Packit |
13e616 |
Destroy the thread before we tear down the other objects.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_vl->state != OSM_VL15_STATE_INIT)
|
|
Packit |
13e616 |
cl_event_signal(&p_vl->signal);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_thread_destroy(&p_vl->poller);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Return the outstanding messages to the pool
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_vl->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
while (!cl_is_qlist_empty(&p_vl->rfifo)) {
|
|
Packit |
13e616 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo);
|
|
Packit |
13e616 |
osm_mad_pool_put(p_pool, p_madw);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
while (!cl_is_qlist_empty(&p_vl->ufifo)) {
|
|
Packit |
13e616 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo);
|
|
Packit |
13e616 |
osm_mad_pool_put(p_pool, p_madw);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_release(&p_vl->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_event_destroy(&p_vl->signal);
|
|
Packit |
13e616 |
p_vl->state = OSM_VL15_STATE_INIT;
|
|
Packit |
13e616 |
cl_spinlock_destroy(&p_vl->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vl->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_vl15_init(IN osm_vl15_t * p_vl, IN osm_vendor_t * p_vend,
|
|
Packit |
13e616 |
IN osm_log_t * p_log, IN osm_stats_t * p_stats,
|
|
Packit |
13e616 |
IN osm_subn_t * p_subn,
|
|
Packit |
13e616 |
IN int32_t max_wire_smps,
|
|
Packit |
13e616 |
IN int32_t max_wire_smps2,
|
|
Packit |
13e616 |
IN uint32_t max_smps_timeout)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vl->p_vend = p_vend;
|
|
Packit |
13e616 |
p_vl->p_log = p_log;
|
|
Packit |
13e616 |
p_vl->p_stats = p_stats;
|
|
Packit |
13e616 |
p_vl->p_subn = p_subn;
|
|
Packit |
13e616 |
p_vl->max_wire_smps = max_wire_smps;
|
|
Packit |
13e616 |
p_vl->max_wire_smps2 = max_wire_smps2;
|
|
Packit |
13e616 |
p_vl->max_smps_timeout = max_wire_smps < max_wire_smps2 ?
|
|
Packit |
13e616 |
max_smps_timeout : EVENT_NO_TIMEOUT;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = cl_event_init(&p_vl->signal, FALSE);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vl->state = OSM_VL15_STATE_READY;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = cl_spinlock_init(&p_vl->lock);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Initialize the thread after all other dependent objects
|
|
Packit |
13e616 |
have been initialized.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
status = cl_thread_init(&p_vl->poller, vl15_poller, p_vl,
|
|
Packit |
13e616 |
"opensm poller");
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vl15_poll(IN osm_vl15_t * p_vl)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_vl->state == OSM_VL15_STATE_READY);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
If we have room for more VL15 MADs on the wire,
|
|
Packit |
13e616 |
then signal the poller thread.
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
This is not an airtight check, since the poller thread
|
|
Packit |
13e616 |
could be just about to send another MAD as we signal
|
|
Packit |
13e616 |
the event here. To cover this rare case, the poller
|
|
Packit |
13e616 |
thread checks for a spurious wake-up.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_vl->p_stats->qp0_mads_outstanding_on_wire <
|
|
Packit |
13e616 |
(int32_t) p_vl->max_wire_smps) {
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Signalling poller thread\n");
|
|
Packit |
13e616 |
cl_event_signal(&p_vl->signal);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vl->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vl15_post(IN osm_vl15_t * p_vl, IN osm_madw_t * p_madw)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_vl->state == OSM_VL15_STATE_READY);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, "Posting p_madw = %p\n", p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Determine in which fifo to place the pending madw.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_vl->lock);
|
|
Packit |
13e616 |
if (p_madw->resp_expected == TRUE) {
|
|
Packit |
13e616 |
cl_qlist_insert_tail(&p_vl->rfifo, &p_madw->list_item);
|
|
Packit |
13e616 |
osm_stats_inc_qp0_outstanding(p_vl->p_stats);
|
|
Packit |
13e616 |
} else
|
|
Packit |
13e616 |
cl_qlist_insert_tail(&p_vl->ufifo, &p_madw->list_item);
|
|
Packit |
13e616 |
cl_spinlock_release(&p_vl->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"%u QP0 MADs on wire, %u QP0 MADs outstanding\n",
|
|
Packit |
13e616 |
p_vl->p_stats->qp0_mads_outstanding_on_wire,
|
|
Packit |
13e616 |
p_vl->p_stats->qp0_mads_outstanding);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_vl15_poll(p_vl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vl->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vl15_shutdown(IN osm_vl15_t * p_vl, IN osm_mad_pool_t * p_mad_pool)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_madw_t *p_madw;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* we only should get here after the VL15 interface was initialized */
|
|
Packit |
13e616 |
CL_ASSERT(p_vl->state == OSM_VL15_STATE_READY);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* grab a lock on the object */
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_vl->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* go over all outstanding MADs and retire their transactions */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* first we handle the list of response MADs */
|
|
Packit |
13e616 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo);
|
|
Packit |
13e616 |
while (p_madw != (osm_madw_t *) cl_qlist_end(&p_vl->ufifo)) {
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Releasing Response p_madw = %p\n", p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_mad_pool_put(p_mad_pool, p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Request MADs we send out */
|
|
Packit |
13e616 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo);
|
|
Packit |
13e616 |
while (p_madw != (osm_madw_t *) cl_qlist_end(&p_vl->rfifo)) {
|
|
Packit |
13e616 |
OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Releasing Request p_madw = %p\n", p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_mad_pool_put(p_mad_pool, p_madw);
|
|
Packit |
13e616 |
osm_stats_dec_qp0_outstanding(p_vl->p_stats);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* free the lock */
|
|
Packit |
13e616 |
cl_spinlock_release(&p_vl->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vl->p_log);
|
|
Packit |
13e616 |
}
|