|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2006-2009 Voltaire, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2012 Lawrence Livermore National Lab. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2014 Mellanox Technologies LTD. All rights reserved.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* This software is available to you under a choice of one of two
|
|
Packit Service |
54dbc3 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit Service |
54dbc3 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit Service |
54dbc3 |
* COPYING in the main directory of this source tree, or the
|
|
Packit Service |
54dbc3 |
* OpenIB.org BSD license below:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* Redistribution and use in source and binary forms, with or
|
|
Packit Service |
54dbc3 |
* without modification, are permitted provided that the following
|
|
Packit Service |
54dbc3 |
* conditions are met:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions of source code must retain the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions in binary form must reproduce the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer in the documentation and/or other materials
|
|
Packit Service |
54dbc3 |
* provided with the distribution.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit Service |
54dbc3 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit Service |
54dbc3 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit Service |
54dbc3 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit Service |
54dbc3 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit Service |
54dbc3 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit Service |
54dbc3 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit Service |
54dbc3 |
* SOFTWARE.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Abstract:
|
|
Packit Service |
54dbc3 |
* OSM Congestion Control configuration implementation
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* Author:
|
|
Packit Service |
54dbc3 |
* Albert Chu, LLNL
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#if HAVE_CONFIG_H
|
|
Packit Service |
54dbc3 |
# include <config.h>
|
|
Packit Service |
54dbc3 |
#endif /* HAVE_CONFIG_H */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#include <stdlib.h>
|
|
Packit Service |
54dbc3 |
#include <string.h>
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#include <iba/ib_types.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_debug.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_file_ids.h>
|
|
Packit Service |
54dbc3 |
#define FILE_ID OSM_FILE_CONGESTION_CONTROL_C
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_subnet.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_opensm.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_log.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_subnet.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_congestion_control.h>
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#define CONGESTION_CONTROL_INITIAL_TID_VALUE 0x7A93
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void cc_mad_post(osm_congestion_control_t *p_cc,
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw,
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node,
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp,
|
|
Packit Service |
54dbc3 |
ib_net16_t attr_id,
|
|
Packit Service |
54dbc3 |
ib_net32_t attr_mod)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_subn_opt_t *p_opt = &p_cc->subn->opt;
|
|
Packit Service |
54dbc3 |
ib_cc_mad_t *p_cc_mad;
|
|
Packit Service |
54dbc3 |
uint8_t port;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_cc->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
port = osm_physp_get_port_num(p_physp);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_mad = osm_madw_get_cc_mad_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.base_ver = 1;
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.mgmt_class = IB_MCLASS_CC;
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.class_ver = 2;
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.method = IB_MAD_METHOD_SET;
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.status = 0;
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.class_spec = 0;
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.trans_id =
|
|
Packit Service |
54dbc3 |
cl_hton64((uint64_t) cl_atomic_inc(&p_cc->trans_id) &
|
|
Packit Service |
54dbc3 |
(uint64_t) (0xFFFFFFFF));
|
|
Packit Service |
54dbc3 |
if (p_cc_mad->header.trans_id == 0)
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.trans_id =
|
|
Packit Service |
54dbc3 |
cl_hton64((uint64_t) cl_atomic_inc(&p_cc->trans_id) &
|
|
Packit Service |
54dbc3 |
(uint64_t) (0xFFFFFFFF));
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.attr_id = attr_id;
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.resv = 0;
|
|
Packit Service |
54dbc3 |
p_cc_mad->header.attr_mod = attr_mod;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_mad->cc_key = p_opt->cc_key;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memset(p_cc_mad->log_data, '\0', IB_CC_LOG_DATA_SIZE);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_madw->mad_addr.dest_lid = osm_node_get_base_lid(p_node, port);
|
|
Packit Service |
54dbc3 |
p_madw->mad_addr.addr_type.gsi.remote_qp = IB_QP1;
|
|
Packit Service |
54dbc3 |
p_madw->mad_addr.addr_type.gsi.remote_qkey =
|
|
Packit Service |
54dbc3 |
cl_hton32(IB_QP1_WELL_KNOWN_Q_KEY);
|
|
Packit Service |
54dbc3 |
p_madw->resp_expected = TRUE;
|
|
Packit Service |
54dbc3 |
p_madw->fail_msg = CL_DISP_MSGID_NONE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_madw->context.cc_context.node_guid = osm_node_get_node_guid(p_node);
|
|
Packit Service |
54dbc3 |
p_madw->context.cc_context.port_guid = osm_physp_get_port_guid(p_physp);
|
|
Packit Service |
54dbc3 |
p_madw->context.cc_context.port = port;
|
|
Packit Service |
54dbc3 |
p_madw->context.cc_context.mad_method = IB_MAD_METHOD_SET;
|
|
Packit Service |
54dbc3 |
p_madw->context.cc_context.attr_mod = attr_mod;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_spinlock_acquire(&p_cc->mad_queue_lock);
|
|
Packit Service |
54dbc3 |
cl_atomic_inc(&p_cc->outstanding_mads);
|
|
Packit Service |
54dbc3 |
cl_qlist_insert_tail(&p_cc->mad_queue, &p_madw->list_item);
|
|
Packit Service |
54dbc3 |
cl_spinlock_release(&p_cc->mad_queue_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_event_signal(&p_cc->cc_poller_wakeup);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void cc_setup_mad_data(osm_sm_t * p_sm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *p_cc = &p_sm->p_subn->p_osm->cc;
|
|
Packit Service |
54dbc3 |
osm_subn_opt_t *p_opt = &p_sm->p_subn->opt;
|
|
Packit Service |
54dbc3 |
uint16_t ccti_limit;
|
|
Packit Service |
54dbc3 |
unsigned i;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Switch Congestion Setting */
|
|
Packit Service |
54dbc3 |
p_cc->sw_cong_setting.control_map = p_opt->cc_sw_cong_setting_control_map;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(p_cc->sw_cong_setting.victim_mask,
|
|
Packit Service |
54dbc3 |
p_opt->cc_sw_cong_setting_victim_mask,
|
|
Packit Service |
54dbc3 |
IB_CC_PORT_MASK_DATA_SIZE);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(p_cc->sw_cong_setting.credit_mask,
|
|
Packit Service |
54dbc3 |
p_opt->cc_sw_cong_setting_credit_mask,
|
|
Packit Service |
54dbc3 |
IB_CC_PORT_MASK_DATA_SIZE);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* threshold is 4 bits, takes up upper nibble of byte */
|
|
Packit Service |
54dbc3 |
p_cc->sw_cong_setting.threshold_resv = (p_opt->cc_sw_cong_setting_threshold << 4);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->sw_cong_setting.packet_size = p_opt->cc_sw_cong_setting_packet_size;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* cs threshold is 4 bits, takes up upper nibble of short */
|
|
Packit Service |
54dbc3 |
p_cc->sw_cong_setting.cs_threshold_resv =
|
|
Packit Service |
54dbc3 |
cl_hton16(p_opt->cc_sw_cong_setting_credit_starvation_threshold << 12);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->sw_cong_setting.cs_return_delay =
|
|
Packit Service |
54dbc3 |
cl_hton16(p_opt->cc_sw_cong_setting_credit_starvation_return_delay.shift << 14
|
|
Packit Service |
54dbc3 |
| p_opt->cc_sw_cong_setting_credit_starvation_return_delay.multiplier);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->sw_cong_setting.marking_rate = p_opt->cc_sw_cong_setting_marking_rate;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* CA Congestion Setting */
|
|
Packit Service |
54dbc3 |
p_cc->ca_cong_setting.port_control = p_opt->cc_ca_cong_setting_port_control;
|
|
Packit Service |
54dbc3 |
p_cc->ca_cong_setting.control_map = p_opt->cc_ca_cong_setting_control_map;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < IB_CA_CONG_ENTRY_DATA_SIZE; i++) {
|
|
Packit Service |
54dbc3 |
ib_ca_cong_entry_t *p_entry;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_entry = &p_cc->ca_cong_setting.entry_list[i];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_entry->ccti_timer = p_opt->cc_ca_cong_entries[i].ccti_timer;
|
|
Packit Service |
54dbc3 |
p_entry->ccti_increase = p_opt->cc_ca_cong_entries[i].ccti_increase;
|
|
Packit Service |
54dbc3 |
p_entry->trigger_threshold = p_opt->cc_ca_cong_entries[i].trigger_threshold;
|
|
Packit Service |
54dbc3 |
p_entry->ccti_min = p_opt->cc_ca_cong_entries[i].ccti_min;
|
|
Packit Service |
54dbc3 |
p_entry->resv0 = 0;
|
|
Packit Service |
54dbc3 |
p_entry->resv1 = 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Congestion Control Table */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* if no entries, we will always send at least 1 mad to set ccti_limit = 0 */
|
|
Packit Service |
54dbc3 |
if (!p_opt->cc_cct.entries_len)
|
|
Packit Service |
54dbc3 |
p_cc->cc_tbl_mads = 1;
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
p_cc->cc_tbl_mads = p_opt->cc_cct.entries_len - 1;
|
|
Packit Service |
54dbc3 |
p_cc->cc_tbl_mads /= IB_CC_TBL_ENTRY_LIST_MAX;
|
|
Packit Service |
54dbc3 |
p_cc->cc_tbl_mads += 1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_cc->cc_tbl_mads <= OSM_CCT_ENTRY_MAD_BLOCKS);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_opt->cc_cct.entries_len)
|
|
Packit Service |
54dbc3 |
ccti_limit = 0;
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
ccti_limit = p_opt->cc_cct.entries_len - 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < p_cc->cc_tbl_mads; i++) {
|
|
Packit Service |
54dbc3 |
int j;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->cc_tbl[i].ccti_limit = cl_hton16(ccti_limit);
|
|
Packit Service |
54dbc3 |
p_cc->cc_tbl[i].resv = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memset(p_cc->cc_tbl[i].entry_list,
|
|
Packit Service |
54dbc3 |
'\0',
|
|
Packit Service |
54dbc3 |
sizeof(p_cc->cc_tbl[i].entry_list));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!ccti_limit)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j < IB_CC_TBL_ENTRY_LIST_MAX; j++) {
|
|
Packit Service |
54dbc3 |
int k;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
k = (i * IB_CC_TBL_ENTRY_LIST_MAX) + j;
|
|
Packit Service |
54dbc3 |
p_cc->cc_tbl[i].entry_list[j].shift_multiplier =
|
|
Packit Service |
54dbc3 |
cl_hton16(p_opt->cc_cct.entries[k].shift << 14
|
|
Packit Service |
54dbc3 |
| p_opt->cc_cct.entries[k].multiplier);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static ib_api_status_t cc_send_sw_cong_setting(osm_sm_t * p_sm,
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *p_cc = &p_sm->p_subn->p_osm->cc;
|
|
Packit Service |
54dbc3 |
unsigned force_update;
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw = NULL;
|
|
Packit Service |
54dbc3 |
ib_cc_mad_t *p_cc_mad = NULL;
|
|
Packit Service |
54dbc3 |
ib_sw_cong_setting_t *p_sw_cong_setting = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_physp = osm_node_get_physp_ptr(p_node, 0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
force_update = p_physp->need_update || p_sm->p_subn->need_update;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!force_update
|
|
Packit Service |
54dbc3 |
&& !memcmp(&p_cc->sw_cong_setting,
|
|
Packit Service |
54dbc3 |
&p_physp->cc.sw.sw_cong_setting,
|
|
Packit Service |
54dbc3 |
sizeof(p_cc->sw_cong_setting)))
|
|
Packit Service |
54dbc3 |
return IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_madw = osm_mad_pool_get(p_cc->mad_pool, p_cc->bind_handle,
|
|
Packit Service |
54dbc3 |
MAD_BLOCK_SIZE, NULL);
|
|
Packit Service |
54dbc3 |
if (p_madw == NULL) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR C101: "
|
|
Packit Service |
54dbc3 |
"failed to allocate mad\n");
|
|
Packit Service |
54dbc3 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_mad = osm_madw_get_cc_mad_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sw_cong_setting = ib_cc_mad_get_mgt_data_ptr(p_cc_mad);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(p_sw_cong_setting,
|
|
Packit Service |
54dbc3 |
&p_cc->sw_cong_setting,
|
|
Packit Service |
54dbc3 |
sizeof(p_cc->sw_cong_setting));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cc_mad_post(p_cc, p_madw, p_node, p_physp,
|
|
Packit Service |
54dbc3 |
IB_MAD_ATTR_SW_CONG_SETTING, 0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static ib_api_status_t cc_send_ca_cong_setting(osm_sm_t * p_sm,
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node,
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *p_cc = &p_sm->p_subn->p_osm->cc;
|
|
Packit Service |
54dbc3 |
unsigned force_update;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw = NULL;
|
|
Packit Service |
54dbc3 |
ib_cc_mad_t *p_cc_mad = NULL;
|
|
Packit Service |
54dbc3 |
ib_ca_cong_setting_t *p_ca_cong_setting = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
force_update = p_physp->need_update || p_sm->p_subn->need_update;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!force_update
|
|
Packit Service |
54dbc3 |
&& !memcmp(&p_cc->ca_cong_setting,
|
|
Packit Service |
54dbc3 |
&p_physp->cc.ca.ca_cong_setting,
|
|
Packit Service |
54dbc3 |
sizeof(p_cc->ca_cong_setting)))
|
|
Packit Service |
54dbc3 |
return IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_madw = osm_mad_pool_get(p_cc->mad_pool, p_cc->bind_handle,
|
|
Packit Service |
54dbc3 |
MAD_BLOCK_SIZE, NULL);
|
|
Packit Service |
54dbc3 |
if (p_madw == NULL) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR C102: "
|
|
Packit Service |
54dbc3 |
"failed to allocate mad\n");
|
|
Packit Service |
54dbc3 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_mad = osm_madw_get_cc_mad_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_ca_cong_setting = ib_cc_mad_get_mgt_data_ptr(p_cc_mad);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(p_ca_cong_setting,
|
|
Packit Service |
54dbc3 |
&p_cc->ca_cong_setting,
|
|
Packit Service |
54dbc3 |
sizeof(p_cc->ca_cong_setting));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cc_mad_post(p_cc, p_madw, p_node, p_physp,
|
|
Packit Service |
54dbc3 |
IB_MAD_ATTR_CA_CONG_SETTING, 0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static ib_api_status_t cc_send_cct(osm_sm_t * p_sm,
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node,
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *p_cc = &p_sm->p_subn->p_osm->cc;
|
|
Packit Service |
54dbc3 |
unsigned force_update;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw = NULL;
|
|
Packit Service |
54dbc3 |
ib_cc_mad_t *p_cc_mad = NULL;
|
|
Packit Service |
54dbc3 |
ib_cc_tbl_t *p_cc_tbl = NULL;
|
|
Packit Service |
54dbc3 |
unsigned int index = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
force_update = p_physp->need_update || p_sm->p_subn->need_update;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (index = 0; index < p_cc->cc_tbl_mads; index++) {
|
|
Packit Service |
54dbc3 |
if (!force_update
|
|
Packit Service |
54dbc3 |
&& !memcmp(&p_cc->cc_tbl[index],
|
|
Packit Service |
54dbc3 |
&p_physp->cc.ca.cc_tbl[index],
|
|
Packit Service |
54dbc3 |
sizeof(p_cc->cc_tbl[index])))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_madw = osm_mad_pool_get(p_cc->mad_pool, p_cc->bind_handle,
|
|
Packit Service |
54dbc3 |
MAD_BLOCK_SIZE, NULL);
|
|
Packit Service |
54dbc3 |
if (p_madw == NULL) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR C103: "
|
|
Packit Service |
54dbc3 |
"failed to allocate mad\n");
|
|
Packit Service |
54dbc3 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_mad = osm_madw_get_cc_mad_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_tbl = (ib_cc_tbl_t *)ib_cc_mad_get_mgt_data_ptr(p_cc_mad);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(p_cc_tbl,
|
|
Packit Service |
54dbc3 |
&p_cc->cc_tbl[index],
|
|
Packit Service |
54dbc3 |
sizeof(p_cc->cc_tbl[index]));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cc_mad_post(p_cc, p_madw, p_node, p_physp,
|
|
Packit Service |
54dbc3 |
IB_MAD_ATTR_CC_TBL, cl_hton32(index));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
int osm_congestion_control_setup(struct osm_opensm *p_osm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
cl_qmap_t *p_tbl;
|
|
Packit Service |
54dbc3 |
cl_map_item_t *p_next;
|
|
Packit Service |
54dbc3 |
int ret = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_osm->subn.opt.congestion_control)
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(&p_osm->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Do nothing unless the most recent routing attempt was successful.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (!p_osm->routing_engine_used)
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cc_setup_mad_data(&p_osm->sm);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_plock_acquire(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_tbl = &p_osm->subn.port_guid_tbl;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_head(p_tbl);
|
|
Packit Service |
54dbc3 |
while (p_next != cl_qmap_end(p_tbl)) {
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port = (osm_port_t *) p_next;
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node = p_port->p_node;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_next(p_next);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_port->cc_unavailable_flag)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH) {
|
|
Packit Service |
54dbc3 |
status = cc_send_sw_cong_setting(&p_osm->sm, p_node);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
} else if (osm_node_get_type(p_node) == IB_NODE_TYPE_CA) {
|
|
Packit Service |
54dbc3 |
status = cc_send_ca_cong_setting(&p_osm->sm,
|
|
Packit Service |
54dbc3 |
p_node,
|
|
Packit Service |
54dbc3 |
p_port->p_physp);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cc_send_cct(&p_osm->sm,
|
|
Packit Service |
54dbc3 |
p_node,
|
|
Packit Service |
54dbc3 |
p_port->p_physp);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_plock_release(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(&p_osm->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
int osm_congestion_control_wait_pending_transactions(struct osm_opensm *p_osm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *cc = &p_osm->cc;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_osm->subn.opt.congestion_control)
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
while (1) {
|
|
Packit Service |
54dbc3 |
unsigned count = cc->outstanding_mads;
|
|
Packit Service |
54dbc3 |
if (!count || osm_exit_flag)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
cl_event_wait_on(&cc->outstanding_mads_done_event,
|
|
Packit Service |
54dbc3 |
EVENT_NO_TIMEOUT,
|
|
Packit Service |
54dbc3 |
TRUE);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return osm_exit_flag;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static inline void decrement_outstanding_mads(osm_congestion_control_t *p_cc)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint32_t outstanding;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
outstanding = cl_atomic_dec(&p_cc->outstanding_mads);
|
|
Packit Service |
54dbc3 |
if (!outstanding)
|
|
Packit Service |
54dbc3 |
cl_event_signal(&p_cc->outstanding_mads_done_event);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_atomic_dec(&p_cc->outstanding_mads_on_wire);
|
|
Packit Service |
54dbc3 |
cl_event_signal(&p_cc->sig_mads_on_wire_continue);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void cc_rcv_mad(void *context, void *data)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *p_cc = context;
|
|
Packit Service |
54dbc3 |
osm_opensm_t *p_osm = p_cc->osm;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw = data;
|
|
Packit Service |
54dbc3 |
ib_cc_mad_t *p_cc_mad;
|
|
Packit Service |
54dbc3 |
osm_madw_context_t *p_mad_context = &p_madw->context;
|
|
Packit Service |
54dbc3 |
ib_mad_t *p_mad = osm_madw_get_mad_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
ib_net64_t node_guid = p_mad_context->cc_context.node_guid;
|
|
Packit Service |
54dbc3 |
ib_net64_t port_guid = p_mad_context->cc_context.port_guid;
|
|
Packit Service |
54dbc3 |
uint8_t port = p_mad_context->cc_context.port;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_cc->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Processing received MAD status 0x%x for "
|
|
Packit Service |
54dbc3 |
"attr ID %u mod 0x%x node 0x%" PRIx64 " port %u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(p_mad->status), cl_ntoh16(p_mad->attr_id),
|
|
Packit Service |
54dbc3 |
cl_ntoh32(p_mad_context->cc_context.attr_mod),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(node_guid), port);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_mad = osm_madw_get_cc_mad_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_plock_acquire(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_port = osm_get_port_by_guid(p_cc->subn, port_guid);
|
|
Packit Service |
54dbc3 |
if (!p_port) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C109: "
|
|
Packit Service |
54dbc3 |
"Port GUID 0x%" PRIx64 " not in table\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(port_guid));
|
|
Packit Service |
54dbc3 |
cl_plock_release(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_port->cc_timeout_count = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_cc_mad->header.status) {
|
|
Packit Service |
54dbc3 |
if (p_cc_mad->header.status & IB_MAD_STATUS_UNSUP_CLASS_VER
|
|
Packit Service |
54dbc3 |
|| p_cc_mad->header.status & IB_MAD_STATUS_UNSUP_METHOD
|
|
Packit Service |
54dbc3 |
|| p_cc_mad->header.status & IB_MAD_STATUS_UNSUP_METHOD_ATTR)
|
|
Packit Service |
54dbc3 |
p_port->cc_unavailable_flag = TRUE;
|
|
Packit Service |
54dbc3 |
cl_plock_release(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
p_port->cc_unavailable_flag = FALSE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_cc_mad->header.attr_id == IB_MAD_ATTR_SW_CONG_SETTING) {
|
|
Packit Service |
54dbc3 |
ib_sw_cong_setting_t *p_sw_cong_setting;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_sw_cong_setting = ib_cc_mad_get_mgt_data_ptr(p_cc_mad);
|
|
Packit Service |
54dbc3 |
p_port->p_physp->cc.sw.sw_cong_setting = *p_sw_cong_setting;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
else if (p_cc_mad->header.attr_id == IB_MAD_ATTR_CA_CONG_SETTING) {
|
|
Packit Service |
54dbc3 |
ib_ca_cong_setting_t *p_ca_cong_setting;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_ca_cong_setting = ib_cc_mad_get_mgt_data_ptr(p_cc_mad);
|
|
Packit Service |
54dbc3 |
p_port->p_physp->cc.ca.ca_cong_setting = *p_ca_cong_setting;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
else if (p_cc_mad->header.attr_id == IB_MAD_ATTR_CC_TBL) {
|
|
Packit Service |
54dbc3 |
ib_net32_t attr_mod = p_mad_context->cc_context.attr_mod;
|
|
Packit Service |
54dbc3 |
uint32_t index = cl_ntoh32(attr_mod);
|
|
Packit Service |
54dbc3 |
ib_cc_tbl_t *p_cc_tbl;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc_tbl = ib_cc_mad_get_mgt_data_ptr(p_cc_mad);
|
|
Packit Service |
54dbc3 |
p_port->p_physp->cc.ca.cc_tbl[index] = *p_cc_tbl;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C10A: "
|
|
Packit Service |
54dbc3 |
"Unexpected MAD attribute ID %u received\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(p_cc_mad->header.attr_id));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_plock_release(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
decrement_outstanding_mads(p_cc);
|
|
Packit Service |
54dbc3 |
osm_mad_pool_put(p_cc->mad_pool, p_madw);
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void cc_poller_send(osm_congestion_control_t *p_cc,
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_subn_opt_t *p_opt = &p_cc->subn->opt;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
cl_status_t sts;
|
|
Packit Service |
54dbc3 |
osm_madw_context_t mad_context = p_madw->context;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_vendor_send(p_cc->bind_handle, p_madw, TRUE);
|
|
Packit Service |
54dbc3 |
if (status == IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
cl_atomic_inc(&p_cc->outstanding_mads_on_wire);
|
|
Packit Service |
54dbc3 |
while (p_cc->outstanding_mads_on_wire >
|
|
Packit Service |
54dbc3 |
(int32_t)p_opt->cc_max_outstanding_mads) {
|
|
Packit Service |
54dbc3 |
wait:
|
|
Packit Service |
54dbc3 |
sts = cl_event_wait_on(&p_cc->sig_mads_on_wire_continue,
|
|
Packit Service |
54dbc3 |
EVENT_NO_TIMEOUT, TRUE);
|
|
Packit Service |
54dbc3 |
if (sts != CL_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto wait;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C104: "
|
|
Packit Service |
54dbc3 |
"send failed to node 0x%" PRIx64 "port %u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(mad_context.cc_context.node_guid),
|
|
Packit Service |
54dbc3 |
mad_context.cc_context.port);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void cc_poller(void *p_ptr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *p_cc = p_ptr;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_cc->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_cc->thread_state == OSM_THREAD_STATE_NONE)
|
|
Packit Service |
54dbc3 |
p_cc->thread_state = OSM_THREAD_STATE_RUN;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
while (p_cc->thread_state == OSM_THREAD_STATE_RUN) {
|
|
Packit Service |
54dbc3 |
cl_spinlock_acquire(&p_cc->mad_queue_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_cc->mad_queue);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_spinlock_release(&p_cc->mad_queue_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_madw != (osm_madw_t *) cl_qlist_end(&p_cc->mad_queue))
|
|
Packit Service |
54dbc3 |
cc_poller_send(p_cc, p_madw);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
cl_event_wait_on(&p_cc->cc_poller_wakeup,
|
|
Packit Service |
54dbc3 |
EVENT_NO_TIMEOUT, TRUE);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_api_status_t osm_congestion_control_init(osm_congestion_control_t * p_cc,
|
|
Packit Service |
54dbc3 |
struct osm_opensm *p_osm,
|
|
Packit Service |
54dbc3 |
const osm_subn_opt_t * p_opt)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(&p_osm->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memset(p_cc, 0, sizeof(*p_cc));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->osm = p_osm;
|
|
Packit Service |
54dbc3 |
p_cc->subn = &p_osm->subn;
|
|
Packit Service |
54dbc3 |
p_cc->sm = &p_osm->sm;
|
|
Packit Service |
54dbc3 |
p_cc->log = &p_osm->log;
|
|
Packit Service |
54dbc3 |
p_cc->mad_pool = &p_osm->mad_pool;
|
|
Packit Service |
54dbc3 |
p_cc->trans_id = CONGESTION_CONTROL_INITIAL_TID_VALUE;
|
|
Packit Service |
54dbc3 |
p_cc->vendor = p_osm->p_vendor;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->cc_disp_h = cl_disp_register(&p_osm->disp, OSM_MSG_MAD_CC,
|
|
Packit Service |
54dbc3 |
cc_rcv_mad, p_cc);
|
|
Packit Service |
54dbc3 |
if (p_cc->cc_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_qlist_init(&p_cc->mad_queue);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_spinlock_init(&p_cc->mad_queue_lock);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_event_construct(&p_cc->cc_poller_wakeup);
|
|
Packit Service |
54dbc3 |
status = cl_event_init(&p_cc->cc_poller_wakeup, FALSE);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_event_construct(&p_cc->outstanding_mads_done_event);
|
|
Packit Service |
54dbc3 |
status = cl_event_init(&p_cc->outstanding_mads_done_event, FALSE);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_event_construct(&p_cc->sig_mads_on_wire_continue);
|
|
Packit Service |
54dbc3 |
status = cl_event_init(&p_cc->sig_mads_on_wire_continue, FALSE);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->thread_state = OSM_THREAD_STATE_NONE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = cl_thread_init(&p_cc->cc_poller, cc_poller, p_cc,
|
|
Packit Service |
54dbc3 |
"cc poller");
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
return status;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void cc_mad_recv_callback(osm_madw_t * p_madw, void *bind_context,
|
|
Packit Service |
54dbc3 |
osm_madw_t * p_req_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *p_cc = bind_context;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_cc->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* HACK - should be extended when supporting CC traps */
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_req_madw != NULL);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_madw_copy_context(p_madw, p_req_madw);
|
|
Packit Service |
54dbc3 |
osm_mad_pool_put(p_cc->mad_pool, p_req_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Do not decrement outstanding mads here, do it in the dispatcher */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (cl_disp_post(p_cc->cc_disp_h, OSM_MSG_MAD_CC,
|
|
Packit Service |
54dbc3 |
p_madw, NULL, NULL) != CL_SUCCESS) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C105: "
|
|
Packit Service |
54dbc3 |
"Congestion Control Dispatcher post failed\n");
|
|
Packit Service |
54dbc3 |
osm_mad_pool_put(p_cc->mad_pool, p_madw);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void cc_mad_send_err_callback(void *bind_context,
|
|
Packit Service |
54dbc3 |
osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_congestion_control_t *p_cc = bind_context;
|
|
Packit Service |
54dbc3 |
osm_madw_context_t *p_madw_context = &p_madw->context;
|
|
Packit Service |
54dbc3 |
osm_opensm_t *p_osm = p_cc->osm;
|
|
Packit Service |
54dbc3 |
uint64_t node_guid = p_madw_context->cc_context.node_guid;
|
|
Packit Service |
54dbc3 |
uint64_t port_guid = p_madw_context->cc_context.port_guid;
|
|
Packit Service |
54dbc3 |
uint8_t port = p_madw_context->cc_context.port;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port;
|
|
Packit Service |
54dbc3 |
int log_flag = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_cc->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_plock_acquire(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_port = osm_get_port_by_guid(p_cc->subn, port_guid);
|
|
Packit Service |
54dbc3 |
if (!p_port) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C10B: "
|
|
Packit Service |
54dbc3 |
"Port GUID 0x%" PRIx64 " not in table\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(port_guid));
|
|
Packit Service |
54dbc3 |
cl_plock_release(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* If timed out before, don't bothering logging again
|
|
Packit Service |
54dbc3 |
* we assume no CC support
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_madw->status == IB_TIMEOUT
|
|
Packit Service |
54dbc3 |
&& p_port->cc_timeout_count)
|
|
Packit Service |
54dbc3 |
log_flag = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (log_flag)
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C106: MAD Error (%s): "
|
|
Packit Service |
54dbc3 |
"attr id = %u LID %u GUID 0x%016" PRIx64 " port %u "
|
|
Packit Service |
54dbc3 |
"TID 0x%" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
ib_get_err_str(p_madw->status),
|
|
Packit Service |
54dbc3 |
p_madw->p_mad->attr_id,
|
|
Packit Service |
54dbc3 |
cl_ntoh16(p_madw->mad_addr.dest_lid),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(node_guid),
|
|
Packit Service |
54dbc3 |
port,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_madw->p_mad->trans_id));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_madw->status == IB_TIMEOUT) {
|
|
Packit Service |
54dbc3 |
p_port->cc_timeout_count++;
|
|
Packit Service |
54dbc3 |
if (p_port->cc_timeout_count > OSM_CC_TIMEOUT_COUNT_THRESHOLD
|
|
Packit Service |
54dbc3 |
&& !p_port->cc_unavailable_flag) {
|
|
Packit Service |
54dbc3 |
p_port->cc_unavailable_flag = TRUE;
|
|
Packit Service |
54dbc3 |
p_port->cc_timeout_count = 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
p_cc->subn->subnet_initialization_error = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_plock_release(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
osm_mad_pool_put(p_cc->mad_pool, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
decrement_outstanding_mads(p_cc);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_api_status_t osm_congestion_control_bind(osm_congestion_control_t * p_cc,
|
|
Packit Service |
54dbc3 |
ib_net64_t port_guid)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_bind_info_t bind_info;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_cc->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
bind_info.port_guid = p_cc->port_guid = port_guid;
|
|
Packit Service |
54dbc3 |
bind_info.mad_class = IB_MCLASS_CC;
|
|
Packit Service |
54dbc3 |
bind_info.class_version = 2;
|
|
Packit Service |
54dbc3 |
bind_info.is_responder = FALSE;
|
|
Packit Service |
54dbc3 |
bind_info.is_report_processor = FALSE;
|
|
Packit Service |
54dbc3 |
bind_info.is_trap_processor = FALSE;
|
|
Packit Service |
54dbc3 |
bind_info.recv_q_size = OSM_SM_DEFAULT_QP1_RCV_SIZE;
|
|
Packit Service |
54dbc3 |
bind_info.send_q_size = OSM_SM_DEFAULT_QP1_SEND_SIZE;
|
|
Packit Service |
54dbc3 |
bind_info.timeout = p_cc->subn->opt.transaction_timeout;
|
|
Packit Service |
54dbc3 |
bind_info.retries = p_cc->subn->opt.transaction_retries;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Binding to port GUID 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->bind_handle = osm_vendor_bind(p_cc->vendor, &bind_info,
|
|
Packit Service |
54dbc3 |
p_cc->mad_pool,
|
|
Packit Service |
54dbc3 |
cc_mad_recv_callback,
|
|
Packit Service |
54dbc3 |
cc_mad_send_err_callback, p_cc);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_cc->bind_handle == OSM_BIND_INVALID_HANDLE) {
|
|
Packit Service |
54dbc3 |
status = IB_ERROR;
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR C107: Vendor specific bind failed (%s)\n",
|
|
Packit Service |
54dbc3 |
ib_get_err_str(status));
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
return status;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_congestion_control_shutdown(osm_congestion_control_t * p_cc)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_cc->log);
|
|
Packit Service |
54dbc3 |
if (p_cc->bind_handle == OSM_BIND_INVALID_HANDLE) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_cc->log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR C108: No previous bind\n");
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
cl_disp_unregister(p_cc->cc_disp_h);
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_congestion_control_destroy(osm_congestion_control_t * p_cc)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_cc->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_cc->thread_state = OSM_THREAD_STATE_EXIT;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_event_signal(&p_cc->sig_mads_on_wire_continue);
|
|
Packit Service |
54dbc3 |
cl_event_signal(&p_cc->cc_poller_wakeup);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_thread_destroy(&p_cc->cc_poller);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_spinlock_acquire(&p_cc->mad_queue_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
while (!cl_is_qlist_empty(&p_cc->mad_queue)) {
|
|
Packit Service |
54dbc3 |
p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_cc->mad_queue);
|
|
Packit Service |
54dbc3 |
osm_mad_pool_put(p_cc->mad_pool, p_madw);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_spinlock_release(&p_cc->mad_queue_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_spinlock_destroy(&p_cc->mad_queue_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_event_destroy(&p_cc->cc_poller_wakeup);
|
|
Packit Service |
54dbc3 |
cl_event_destroy(&p_cc->outstanding_mads_done_event);
|
|
Packit Service |
54dbc3 |
cl_event_destroy(&p_cc->sig_mads_on_wire_continue);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_cc->log);
|
|
Packit Service |
54dbc3 |
}
|