|
Packit |
6d2c1b |
/*
|
|
Packit |
6d2c1b |
* Copyright (c) 2001-2020 Mellanox Technologies, Ltd. All rights reserved.
|
|
Packit |
6d2c1b |
*
|
|
Packit |
6d2c1b |
* This software is available to you under a choice of one of two
|
|
Packit |
6d2c1b |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
6d2c1b |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
6d2c1b |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
6d2c1b |
* BSD license below:
|
|
Packit |
6d2c1b |
*
|
|
Packit |
6d2c1b |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
6d2c1b |
* without modification, are permitted provided that the following
|
|
Packit |
6d2c1b |
* conditions are met:
|
|
Packit |
6d2c1b |
*
|
|
Packit |
6d2c1b |
* - Redistributions of source code must retain the above
|
|
Packit |
6d2c1b |
* copyright notice, this list of conditions and the following
|
|
Packit |
6d2c1b |
* disclaimer.
|
|
Packit |
6d2c1b |
*
|
|
Packit |
6d2c1b |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
6d2c1b |
* copyright notice, this list of conditions and the following
|
|
Packit |
6d2c1b |
* disclaimer in the documentation and/or other materials
|
|
Packit |
6d2c1b |
* provided with the distribution.
|
|
Packit |
6d2c1b |
*
|
|
Packit |
6d2c1b |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
6d2c1b |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
6d2c1b |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
6d2c1b |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
6d2c1b |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
6d2c1b |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
6d2c1b |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
6d2c1b |
* SOFTWARE.
|
|
Packit |
6d2c1b |
*/
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#include "time_converter.h"
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#include <stdlib.h>
|
|
Packit |
6d2c1b |
#include "vlogger/vlogger.h"
|
|
Packit |
6d2c1b |
#include "utils/rdtsc.h"
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#include "vma/util/sys_vars.h"
|
|
Packit |
6d2c1b |
#include "vma/util/instrumentation.h"
|
|
Packit |
6d2c1b |
#include "vma/event/event_handler_manager.h"
|
|
Packit |
6d2c1b |
#include "vma/ib/base/verbs_extra.h"
|
|
Packit |
6d2c1b |
#include "vma/dev/net_device_table_mgr.h"
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#define MODULE_NAME "time_converter"
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#define ibchtc_logerr __log_err
|
|
Packit |
6d2c1b |
#define ibchtc_logwarn __log_warn
|
|
Packit |
6d2c1b |
#define ibchtc_loginfo __log_info
|
|
Packit |
6d2c1b |
#define ibchtc_logdbg __log_dbg
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#define IB_CTX_TC_DEVIATION_THRESHOLD 10
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#define VMA_QUERY_DEVICE_SUPPORTED (1 << 0)
|
|
Packit |
6d2c1b |
#define VMA_QUERY_VALUES_SUPPORTED (1 << 1)
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
uint32_t time_converter::get_single_converter_status(struct ibv_context* ctx) {
|
|
Packit |
6d2c1b |
uint32_t dev_status = 0;
|
|
Packit |
6d2c1b |
#ifdef DEFINED_IBV_CQ_TIMESTAMP
|
|
Packit |
6d2c1b |
int rval;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
// Checking if ibv_exp_query_device() is valid
|
|
Packit |
6d2c1b |
vma_ibv_device_attr_ex device_attr;
|
|
Packit |
6d2c1b |
memset(&device_attr, 0, sizeof(device_attr));
|
|
Packit |
6d2c1b |
device_attr.comp_mask = VMA_IBV_DEVICE_ATTR_HCA_CORE_CLOCK;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
if ((rval = vma_ibv_query_device(ctx ,&device_attr)) || !device_attr.hca_core_clock) {
|
|
Packit |
6d2c1b |
ibchtc_logdbg("time_converter::get_single_converter_status :Error in querying hca core clock "
|
|
Packit |
6d2c1b |
"(vma_ibv_query_device() return value=%d ) (ibv context %p) (errno=%d %m)\n", rval, ctx, errno);
|
|
Packit |
6d2c1b |
} else {
|
|
Packit |
6d2c1b |
dev_status |= VMA_QUERY_DEVICE_SUPPORTED;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
// Checking if ibv_exp_query_values() is valid
|
|
Packit |
6d2c1b |
vma_ts_values queried_values;
|
|
Packit |
6d2c1b |
memset(&queried_values, 0, sizeof(queried_values));
|
|
Packit |
6d2c1b |
queried_values.comp_mask = VMA_IBV_VALUES_MASK_RAW_CLOCK;
|
|
Packit |
6d2c1b |
if ((rval = vma_ibv_query_values(ctx, &queried_values)) || !vma_get_ts_val(queried_values)) {
|
|
Packit |
6d2c1b |
ibchtc_logdbg("time_converter::get_single_converter_status :Error in querying hw clock, can't convert"
|
|
Packit |
6d2c1b |
" hw time to system time (vma_ibv_query_values() return value=%d ) (ibv context %p) (errno=%d %m)\n", rval, ctx, errno);
|
|
Packit |
6d2c1b |
} else {
|
|
Packit |
6d2c1b |
dev_status |= VMA_QUERY_VALUES_SUPPORTED;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
#else
|
|
Packit |
6d2c1b |
NOT_IN_USE(ctx);
|
|
Packit |
6d2c1b |
#endif
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
return dev_status;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
ts_conversion_mode_t time_converter::update_device_converters_status(net_device_map_t& net_devices)
|
|
Packit |
6d2c1b |
{
|
|
Packit |
6d2c1b |
ibchtc_logdbg("Checking RX HW time stamp status for all devices [%d]", net_devices.size());
|
|
Packit |
6d2c1b |
ts_conversion_mode_t ts_conversion_mode = TS_CONVERSION_MODE_DISABLE;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
if (net_devices.empty()) {
|
|
Packit |
6d2c1b |
ibchtc_logdbg("No supported devices was found, return");
|
|
Packit |
6d2c1b |
return ts_conversion_mode;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#ifdef DEFINED_IBV_CQ_TIMESTAMP
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
if (safe_mce_sys().hw_ts_conversion_mode != TS_CONVERSION_MODE_DISABLE) {
|
|
Packit |
6d2c1b |
uint32_t devs_status = VMA_QUERY_DEVICE_SUPPORTED | VMA_QUERY_VALUES_SUPPORTED;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
/* Get common time conversion mode for all devices */
|
|
Packit |
6d2c1b |
for (net_device_map_index_t::iterator dev_iter = net_devices.begin(); dev_iter != net_devices.end(); dev_iter++) {
|
|
Packit |
6d2c1b |
if (dev_iter->second->get_state() == net_device_val::RUNNING) {
|
|
Packit |
6d2c1b |
slave_data_vector_t slaves = dev_iter->second->get_slave_array();
|
|
Packit |
6d2c1b |
for (slave_data_vector_t::iterator slaves_iter = slaves.begin(); slaves_iter != slaves.end(); slaves_iter++) {
|
|
Packit |
6d2c1b |
devs_status &= get_single_converter_status((*slaves_iter)->p_ib_ctx->get_ibv_context());
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
switch (safe_mce_sys().hw_ts_conversion_mode) {
|
|
Packit |
6d2c1b |
case TS_CONVERSION_MODE_RAW:
|
|
Packit |
6d2c1b |
ts_conversion_mode = devs_status & VMA_QUERY_DEVICE_SUPPORTED ? TS_CONVERSION_MODE_RAW : TS_CONVERSION_MODE_DISABLE;
|
|
Packit |
6d2c1b |
break;
|
|
Packit |
6d2c1b |
case TS_CONVERSION_MODE_BEST_POSSIBLE:
|
|
Packit |
6d2c1b |
if (devs_status == (VMA_QUERY_DEVICE_SUPPORTED | VMA_QUERY_VALUES_SUPPORTED)) {
|
|
Packit |
6d2c1b |
ts_conversion_mode = TS_CONVERSION_MODE_SYNC;
|
|
Packit |
6d2c1b |
} else {
|
|
Packit |
6d2c1b |
ts_conversion_mode = devs_status & VMA_QUERY_DEVICE_SUPPORTED ? TS_CONVERSION_MODE_RAW : TS_CONVERSION_MODE_DISABLE;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
break;
|
|
Packit |
6d2c1b |
case TS_CONVERSION_MODE_SYNC:
|
|
Packit |
6d2c1b |
ts_conversion_mode = devs_status == (VMA_QUERY_DEVICE_SUPPORTED | VMA_QUERY_VALUES_SUPPORTED) ? TS_CONVERSION_MODE_SYNC : TS_CONVERSION_MODE_DISABLE;
|
|
Packit |
6d2c1b |
break;
|
|
Packit |
6d2c1b |
case TS_CONVERSION_MODE_PTP:
|
|
Packit |
6d2c1b |
ts_conversion_mode = devs_status == (VMA_QUERY_DEVICE_SUPPORTED | VMA_QUERY_VALUES_SUPPORTED) ? TS_CONVERSION_MODE_PTP : TS_CONVERSION_MODE_DISABLE;
|
|
Packit |
6d2c1b |
break;
|
|
Packit |
6d2c1b |
default:
|
|
Packit |
6d2c1b |
ts_conversion_mode = TS_CONVERSION_MODE_DISABLE;
|
|
Packit |
6d2c1b |
break;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#endif
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
ibchtc_logdbg("Conversion status was set to %d", ts_conversion_mode);
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
for (net_device_map_index_t::iterator dev_iter = net_devices.begin(); dev_iter != net_devices.end(); dev_iter++) {
|
|
Packit |
6d2c1b |
slave_data_vector_t slaves = dev_iter->second->get_slave_array();
|
|
Packit |
6d2c1b |
for (slave_data_vector_t::iterator slaves_iter = slaves.begin(); slaves_iter != slaves.end(); slaves_iter++) {
|
|
Packit |
6d2c1b |
ts_conversion_mode_t dev_ts_conversion_mode = dev_iter->second->get_state() == net_device_val::RUNNING ? ts_conversion_mode : TS_CONVERSION_MODE_DISABLE;
|
|
Packit |
6d2c1b |
(*slaves_iter)->p_ib_ctx->set_ctx_time_converter_status(dev_ts_conversion_mode);
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
return ts_conversion_mode;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
void time_converter::clean_obj()
|
|
Packit |
6d2c1b |
{
|
|
Packit |
6d2c1b |
if (is_cleaned()) {
|
|
Packit |
6d2c1b |
return ;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
set_cleaned();
|
|
Packit |
6d2c1b |
m_timer_handle = NULL;
|
|
Packit |
6d2c1b |
if (g_p_event_handler_manager->is_running()) {
|
|
Packit |
6d2c1b |
g_p_event_handler_manager->unregister_timers_event_and_delete(this);
|
|
Packit |
6d2c1b |
} else {
|
|
Packit |
6d2c1b |
cleanable_obj::clean_obj();
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
}
|