Blame opae-libs/plugins/xfpga/metrics/metrics_utils.c

Packit 534379
// Copyright(c) 2018-2020, Intel Corporation
Packit 534379
//
Packit 534379
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
// modification, are permitted provided that the following conditions are met:
Packit 534379
//
Packit 534379
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer.
Packit 534379
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer in the documentation
Packit 534379
//   and/or other materials provided with the distribution.
Packit 534379
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
//   may be used to  endorse or promote  products derived  from this  software
Packit 534379
//   without specific prior written permission.
Packit 534379
//
Packit 534379
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 534379
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
// POSSIBILITY OF SUCH DAMAGE.
Packit 534379
Packit 534379
/**
Packit 534379
* \file metrics_utils.c
Packit 534379
* \brief fpga metrics utils functions
Packit 534379
*/
Packit 534379
Packit 534379
#ifdef HAVE_CONFIG_H
Packit 534379
#include <config.h>
Packit 534379
#endif // HAVE_CONFIG_H
Packit 534379
Packit 534379
#include <string.h>
Packit 534379
#include <glob.h>
Packit 534379
#include <sys/types.h>
Packit 534379
#include <sys/stat.h>
Packit 534379
#include <fcntl.h>
Packit 534379
#include <dirent.h>
Packit 534379
#include <uuid/uuid.h>
Packit 534379
#include <dlfcn.h>
Packit 534379
Packit 534379
#include "common_int.h"
Packit 534379
#include "metrics_int.h"
Packit 534379
#include "types_int.h"
Packit 534379
#include "opae/metrics.h"
Packit 534379
#include "metrics/vector.h"
Packit 534379
#include "xfpga.h"
Packit 534379
#include "metrics/bmc/bmc.h"
Packit 534379
#include "metrics/metrics_metadata.h"
Packit 534379
#include "mcp_metadata.h"
Packit 534379
#include "metrics_max10.h"
Packit 534379
Packit 534379
fpga_result metric_sysfs_path_is_dir(const char *path)
Packit 534379
{
Packit 534379
	struct stat astats;
Packit 534379
Packit 534379
	if (path == NULL) {
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if ((stat(path, &astats)) != 0) {
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	if (S_ISDIR(astats.st_mode)) {
Packit 534379
		return FPGA_OK;
Packit 534379
	}
Packit 534379
Packit 534379
	return FPGA_NOT_FOUND;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result metric_sysfs_path_is_file(const char *path)
Packit 534379
{
Packit 534379
	struct stat astats;
Packit 534379
Packit 534379
	if (path == NULL) {
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if ((stat(path, &astats)) != 0) {
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	if (S_ISREG(astats.st_mode)) {
Packit 534379
		return FPGA_OK;
Packit 534379
	}
Packit 534379
Packit 534379
	return FPGA_NOT_FOUND;
Packit 534379
}
Packit 534379
Packit 534379
// Adds Metrics info to vector
Packit 534379
fpga_result add_metric_vector(fpga_metric_vector *vector,
Packit 534379
				uint64_t metric_num,
Packit 534379
				const char *qualifier_name,
Packit 534379
				const char *group_name,
Packit 534379
				const char *group_sysfs,
Packit 534379
				const char *metric_name,
Packit 534379
				const char *metric_sysfs,
Packit 534379
				const char *metric_units,
Packit 534379
				enum fpga_metric_datatype  metric_datatype,
Packit 534379
				enum fpga_metric_type	metric_type,
Packit 534379
				enum fpga_hw_type	hw_type,
Packit 534379
				uint64_t mmio_offset)
Packit 534379
{
Packit 534379
Packit 534379
	fpga_result result                           = FPGA_OK;
Packit 534379
	struct _fpga_enum_metric *fpga_enum_metric   = NULL;
Packit 534379
	size_t len;
Packit 534379
Packit 534379
	if (vector == NULL ||
Packit 534379
		group_name == NULL ||
Packit 534379
		group_sysfs == NULL ||
Packit 534379
		metric_name == NULL ||
Packit 534379
		metric_sysfs == NULL ||
Packit 534379
		qualifier_name == NULL ||
Packit 534379
		metric_units == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	fpga_enum_metric = (struct _fpga_enum_metric *)malloc(sizeof(struct _fpga_enum_metric));
Packit 534379
	if (fpga_enum_metric == NULL) {
Packit 534379
		OPAE_ERR("Failed to allocate memory");
Packit 534379
		return FPGA_NO_MEMORY;
Packit 534379
	}
Packit 534379
Packit 534379
	len = strnlen(group_name, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_enum_metric->group_name, group_name, len);
Packit 534379
	fpga_enum_metric->group_name[len] = '\0';
Packit 534379
Packit 534379
	len = strnlen(group_sysfs, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_enum_metric->group_sysfs, group_sysfs, len);
Packit 534379
	fpga_enum_metric->group_sysfs[len] = '\0';
Packit 534379
Packit 534379
	len = strnlen(metric_name, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_enum_metric->metric_name, metric_name, len);
Packit 534379
	fpga_enum_metric->metric_name[len] = '\0';
Packit 534379
Packit 534379
	len = strnlen(metric_sysfs, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_enum_metric->metric_sysfs, metric_sysfs, len);
Packit 534379
	fpga_enum_metric->metric_sysfs[len] = '\0';
Packit 534379
Packit 534379
	len = strnlen(qualifier_name, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_enum_metric->qualifier_name, qualifier_name, len);
Packit 534379
	fpga_enum_metric->qualifier_name[len] = '\0';
Packit 534379
Packit 534379
	len = strnlen(metric_units, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_enum_metric->metric_units, metric_units, len);
Packit 534379
	fpga_enum_metric->metric_units[len] = '\0';
Packit 534379
Packit 534379
	fpga_enum_metric->metric_type = metric_type;
Packit 534379
	fpga_enum_metric->metric_datatype = metric_datatype;
Packit 534379
	fpga_enum_metric->hw_type = hw_type;
Packit 534379
	fpga_enum_metric->metric_num = metric_num;
Packit 534379
	fpga_enum_metric->mmio_offset = mmio_offset;
Packit 534379
Packit 534379
	fpga_vector_push(vector, fpga_enum_metric);
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result get_metric_data_info(const char *group_name,
Packit 534379
				const char *metric_name,
Packit 534379
				fpga_metric_metadata *metric_data_serach,
Packit 534379
				uint64_t size,
Packit 534379
				fpga_metric_metadata *metric_data)
Packit 534379
{
Packit 534379
	fpga_result result       = FPGA_OK;
Packit 534379
	uint64_t i               = 0;
Packit 534379
	int group_indicator      = 0;
Packit 534379
	int metric_indicator     = 0;
Packit 534379
Packit 534379
	if (group_name == NULL ||
Packit 534379
		metric_name == NULL ||
Packit 534379
		metric_data_serach == NULL ||
Packit 534379
		metric_data == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	for (i = 0; i < size; i++) {
Packit 534379
Packit 534379
		group_indicator = strcasecmp(metric_data_serach[i].group_name,
Packit 534379
					     group_name);
Packit 534379
Packit 534379
		metric_indicator = strcasecmp(metric_data_serach[i].metric_name,
Packit 534379
					      metric_name);
Packit 534379
Packit 534379
		if (group_indicator == 0 &&
Packit 534379
			metric_indicator == 0) {
Packit 534379
			*metric_data = (struct fpga_metric_metadata)metric_data_serach[i];
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
Packit 534379
	}
Packit 534379
Packit 534379
	return FPGA_NOT_SUPPORTED;
Packit 534379
}
Packit 534379
Packit 534379
// enumerates thermal metrics info
Packit 534379
fpga_result enum_thermalmgmt_metrics(fpga_metric_vector *vector,
Packit 534379
					uint64_t *metric_num,
Packit 534379
					const char *sysfspath,
Packit 534379
					enum fpga_hw_type	hw_type)
Packit 534379
{
Packit 534379
	fpga_result result                      = FPGA_OK;
Packit 534379
	fpga_metric_metadata metric_data;
Packit 534379
	size_t i = 0;
Packit 534379
	glob_t pglob;
Packit 534379
Packit 534379
	memset(&metric_data, 0, sizeof(metric_data));
Packit 534379
Packit 534379
	if (vector == NULL ||
Packit 534379
		sysfspath == NULL ||
Packit 534379
		metric_num == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	int gres = glob(sysfspath, GLOB_NOSORT, NULL, &pglob);
Packit 534379
	if (gres) {
Packit 534379
		OPAE_ERR("Failed pattern match %s: %s", sysfspath, strerror(errno));
Packit 534379
		//TODO refactor to common function
Packit 534379
		switch (gres) {
Packit 534379
		case GLOB_NOSPACE:
Packit 534379
			result = FPGA_NO_MEMORY;
Packit 534379
			break;
Packit 534379
		case GLOB_NOMATCH:
Packit 534379
			result = FPGA_NOT_FOUND;
Packit 534379
			break;
Packit 534379
		default:
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
		}
Packit 534379
Packit 534379
		if (pglob.gl_pathv) {
Packit 534379
			globfree(&pglob);
Packit 534379
		}
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	for (i = 0; i < pglob.gl_pathc; i++) {
Packit 534379
Packit 534379
		if (!pglob.gl_pathv) {
Packit 534379
			OPAE_ERR("No matching pattern");
Packit 534379
			break;
Packit 534379
		}
Packit 534379
Packit 534379
		char *dir_name = strrchr(pglob.gl_pathv[i], '/');
Packit 534379
Packit 534379
		if (!dir_name)
Packit 534379
			continue;
Packit 534379
Packit 534379
		if (!strcmp((dir_name + 1), REVISION))
Packit 534379
			continue;
Packit 534379
Packit 534379
		result = get_metric_data_info(THERLGMT, (dir_name + 1), mcp_metric_metadata, MCP_MDATA_SIZE, &metric_data);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_MSG("Failed to get metric metadata ");
Packit 534379
		}
Packit 534379
Packit 534379
		result = add_metric_vector(vector, *metric_num, THERLGMT, THERLGMT, sysfspath, (dir_name + 1), pglob.gl_pathv[i], metric_data.metric_units,
Packit 534379
								FPGA_METRIC_DATATYPE_INT, FPGA_METRIC_TYPE_THERMAL, hw_type, 0);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_MSG("Failed to add metrics");
Packit 534379
			if (pglob.gl_pathv) {
Packit 534379
				globfree(&pglob);
Packit 534379
			}
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
		*metric_num = *metric_num + 1;
Packit 534379
	}
Packit 534379
Packit 534379
	if (pglob.gl_pathv) {
Packit 534379
		globfree(&pglob);
Packit 534379
	}
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
// enumerates power metrics info
Packit 534379
fpga_result enum_powermgmt_metrics(fpga_metric_vector *vector,
Packit 534379
					uint64_t *metric_num,
Packit 534379
					const char *sysfspath,
Packit 534379
					enum fpga_hw_type hw_type)
Packit 534379
{
Packit 534379
	fpga_result result                  = FPGA_OK;
Packit 534379
	size_t i = 0;
Packit 534379
	fpga_metric_metadata metric_data;
Packit 534379
	glob_t pglob;
Packit 534379
Packit 534379
	memset(&metric_data, 0, sizeof(metric_data));
Packit 534379
Packit 534379
	if (vector == NULL ||
Packit 534379
		sysfspath == NULL ||
Packit 534379
		metric_num == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	int gres = glob(sysfspath, GLOB_NOSORT, NULL, &pglob);
Packit 534379
	if (gres) {
Packit 534379
		OPAE_ERR("Failed pattern match %s: %s", sysfspath, strerror(errno));
Packit 534379
		//TODO refactor to common function
Packit 534379
		switch (gres) {
Packit 534379
		case GLOB_NOSPACE:
Packit 534379
			result = FPGA_NO_MEMORY;
Packit 534379
			break;
Packit 534379
		case GLOB_NOMATCH:
Packit 534379
			result = FPGA_NOT_FOUND;
Packit 534379
			break;
Packit 534379
		default:
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
		}
Packit 534379
Packit 534379
		if (pglob.gl_pathv) {
Packit 534379
			globfree(&pglob);
Packit 534379
		}
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	for (i = 0; i < pglob.gl_pathc; i++) {
Packit 534379
Packit 534379
		if (!pglob.gl_pathv) {
Packit 534379
			OPAE_ERR("No matching pattern");
Packit 534379
			break;
Packit 534379
		}
Packit 534379
Packit 534379
		char *dir_name = strrchr(pglob.gl_pathv[i], '/');
Packit 534379
Packit 534379
		if (!dir_name)
Packit 534379
			continue;
Packit 534379
Packit 534379
		if (!strcmp((dir_name + 1), REVISION))
Packit 534379
			continue;
Packit 534379
Packit 534379
		result = get_metric_data_info(PWRMGMT, (dir_name + 1), mcp_metric_metadata, MCP_MDATA_SIZE, &metric_data);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_MSG("Failed to get metric metadata ");
Packit 534379
		}
Packit 534379
Packit 534379
		result = add_metric_vector(vector, *metric_num, PWRMGMT, PWRMGMT, sysfspath, (dir_name + 1), pglob.gl_pathv[i], metric_data.metric_units,
Packit 534379
								FPGA_METRIC_DATATYPE_INT, FPGA_METRIC_TYPE_POWER, hw_type, 0);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_MSG("Failed to add metrics");
Packit 534379
			if (pglob.gl_pathv) {
Packit 534379
				globfree(&pglob);
Packit 534379
			}
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
		*metric_num = *metric_num + 1;
Packit 534379
	}
Packit 534379
Packit 534379
	if (pglob.gl_pathv) {
Packit 534379
		globfree(&pglob);
Packit 534379
	}
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
// enumerates performance counters metrics info
Packit 534379
fpga_result enum_perf_counter_items(fpga_metric_vector *vector,
Packit 534379
				uint64_t *metric_num,
Packit 534379
				const char *qualifier_name,
Packit 534379
				const char *sysfspath,
Packit 534379
				const char *sysfs_name,
Packit 534379
				enum fpga_metric_type metric_type,
Packit 534379
				enum fpga_hw_type  hw_type)
Packit 534379
{
Packit 534379
	fpga_result result                  = FPGA_OK;
Packit 534379
	DIR *dir                            = NULL;
Packit 534379
	struct dirent *dirent               = NULL;
Packit 534379
	char sysfs_path[SYSFS_PATH_MAX]     = { 0, };
Packit 534379
	char metric_sysfs[SYSFS_PATH_MAX]   = { 0, };
Packit 534379
	char qname[SYSFS_PATH_MAX]          = { 0, };
Packit 534379
Packit 534379
	if (vector == NULL ||
Packit 534379
		sysfspath == NULL ||
Packit 534379
		sysfs_name == NULL ||
Packit 534379
		qualifier_name == NULL ||
Packit 534379
		metric_num == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	snprintf(sysfs_path, sizeof(sysfs_path),
Packit 534379
		 "%s/%s", sysfspath, sysfs_name);
Packit 534379
Packit 534379
	dir = opendir(sysfs_path);
Packit 534379
	if (NULL == dir) {
Packit 534379
		OPAE_MSG("can't find dir %s ", strerror(errno));
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	while ((dirent = readdir(dir)) != NULL) {
Packit 534379
		if (!strcmp(dirent->d_name, "."))
Packit 534379
			continue;
Packit 534379
		if (!strcmp(dirent->d_name, ".."))
Packit 534379
			continue;
Packit 534379
		if (!strcmp(dirent->d_name, PERF_ENABLE))
Packit 534379
			continue;
Packit 534379
Packit 534379
		if (!strcmp(dirent->d_name, PERF_FREEZE))
Packit 534379
			continue;
Packit 534379
Packit 534379
		if (dirent->d_type == DT_DIR) {
Packit 534379
Packit 534379
			if (snprintf(qname, sizeof(qname),
Packit 534379
				     "%s:%s", qualifier_name, dirent->d_name) < 0) {
Packit 534379
				OPAE_ERR("snprintf buffer overflow");
Packit 534379
				continue;
Packit 534379
			}
Packit 534379
Packit 534379
			result = enum_perf_counter_items(vector, metric_num, qname, sysfs_path, dirent->d_name, metric_type, hw_type);
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_MSG("Failed to add metrics");
Packit 534379
			}
Packit 534379
			continue;
Packit 534379
Packit 534379
		}
Packit 534379
Packit 534379
		if (snprintf(metric_sysfs, sizeof(metric_sysfs),
Packit 534379
			     "%s/%s", sysfs_path, dirent->d_name) < 0) {
Packit 534379
			OPAE_ERR("snprintf buffer overflow");
Packit 534379
			closedir(dir);
Packit 534379
			return FPGA_EXCEPTION;
Packit 534379
		}
Packit 534379
Packit 534379
		result = add_metric_vector(vector, *metric_num, qualifier_name, "performance", sysfs_path, dirent->d_name,
Packit 534379
			metric_sysfs, "", FPGA_METRIC_DATATYPE_INT, metric_type, hw_type, 0);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_MSG("Failed to add metrics");
Packit 534379
			closedir(dir);
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
Packit 534379
		*metric_num = *metric_num + 1;
Packit 534379
	}
Packit 534379
	closedir(dir);
Packit 534379
	return result;
Packit 534379
Packit 534379
}
Packit 534379
Packit 534379
// enumerates performance counters metrics info
Packit 534379
fpga_result enum_perf_counter_metrics(fpga_metric_vector *vector,
Packit 534379
					uint64_t *metric_num,
Packit 534379
					const char *sysfspath,
Packit 534379
					enum fpga_hw_type  hw_type)
Packit 534379
{
Packit 534379
	fpga_result result                  = FPGA_OK;
Packit 534379
	DIR *dir                            = NULL;
Packit 534379
	struct dirent *dirent               = NULL;
Packit 534379
	char sysfs_path[SYSFS_PATH_MAX]     = { 0, };
Packit 534379
	char qualifier_name[SYSFS_PATH_MAX] = { 0, };
Packit 534379
	glob_t pglob;
Packit 534379
	size_t len;
Packit 534379
Packit 534379
	if (vector == NULL ||
Packit 534379
		sysfspath == NULL ||
Packit 534379
		metric_num == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	int gres = glob(sysfspath, GLOB_NOSORT, NULL, &pglob);
Packit 534379
	if (gres) {
Packit 534379
		OPAE_ERR("Failed pattern match %s: %s", sysfspath, strerror(errno));
Packit 534379
		if (pglob.gl_pathv) {
Packit 534379
			globfree(&pglob);
Packit 534379
		}
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	len = strnlen(pglob.gl_pathv[0], sizeof(sysfs_path) - 1);
Packit 534379
	memcpy(sysfs_path, pglob.gl_pathv[0], len);
Packit 534379
	sysfs_path[len] = '\0';
Packit 534379
	globfree(&pglob);
Packit 534379
Packit 534379
	dir = opendir(sysfs_path);
Packit 534379
	if (NULL == dir) {
Packit 534379
		OPAE_MSG("can't find dirt %s ", strerror(errno));
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	while ((dirent = readdir(dir)) != NULL) {
Packit 534379
Packit 534379
		if (!strcmp(dirent->d_name, "."))
Packit 534379
			continue;
Packit 534379
		if (!strcmp(dirent->d_name, ".."))
Packit 534379
			continue;
Packit 534379
		if (!strcmp(dirent->d_name, REVISION))
Packit 534379
			continue;
Packit 534379
Packit 534379
Packit 534379
		if (strcmp(dirent->d_name, PERF_CACHE) == 0) {
Packit 534379
Packit 534379
			snprintf(qualifier_name, sizeof(qualifier_name),
Packit 534379
				 "%s:%s", PERFORMANCE, PERF_CACHE);
Packit 534379
Packit 534379
			result = enum_perf_counter_items(vector,
Packit 534379
					metric_num, qualifier_name,
Packit 534379
					sysfs_path, dirent->d_name,
Packit 534379
					FPGA_METRIC_TYPE_PERFORMANCE_CTR, hw_type);
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_MSG("Failed to add metrics");
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
Packit 534379
		if (strcmp(dirent->d_name, PERF_FABRIC) == 0) {
Packit 534379
Packit 534379
			snprintf(qualifier_name, sizeof(qualifier_name),
Packit 534379
				 "%s:%s", PERFORMANCE, PERF_FABRIC);
Packit 534379
Packit 534379
			result = enum_perf_counter_items(vector, metric_num,
Packit 534379
					qualifier_name, sysfs_path,
Packit 534379
					dirent->d_name, FPGA_METRIC_TYPE_PERFORMANCE_CTR, hw_type);
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_MSG("Failed to add metrics");
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
Packit 534379
		if (strcmp(dirent->d_name, PERF_IOMMU) == 0) {
Packit 534379
Packit 534379
			snprintf(qualifier_name, sizeof(qualifier_name),
Packit 534379
				 "%s:%s", PERFORMANCE, PERF_IOMMU);
Packit 534379
Packit 534379
			result = enum_perf_counter_items(vector, metric_num,
Packit 534379
					qualifier_name, sysfs_path, dirent->d_name,
Packit 534379
					FPGA_METRIC_TYPE_PERFORMANCE_CTR, hw_type);
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_MSG("Failed to add metrics");
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
Packit 534379
	}
Packit 534379
	closedir(dir);
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result xfpga_bmcLoadSDRs(struct _fpga_handle *_handle,
Packit 534379
		bmc_sdr_handle *records,
Packit 534379
		uint32_t *num_sensors)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_NOT_FOUND;
Packit 534379
	fpga_result(*bmcLoadSDRs)(fpga_token token, bmc_sdr_handle *records,
Packit 534379
		uint32_t *num_sensors);
Packit 534379
	if (_handle->bmc_handle != NULL) {
Packit 534379
Packit 534379
		bmcLoadSDRs = dlsym(_handle->bmc_handle, "bmcLoadSDRs");
Packit 534379
		if (bmcLoadSDRs)
Packit 534379
			result = bmcLoadSDRs(_handle->token, records, num_sensors);
Packit 534379
		else
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
Packit 534379
	}
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result xfpga_bmcDestroySDRs(struct _fpga_handle *_handle,
Packit 534379
		bmc_sdr_handle *records)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_NOT_FOUND;
Packit 534379
	fpga_result(*bmcDestroySDRs)(bmc_sdr_handle *records);
Packit 534379
Packit 534379
	if (_handle->bmc_handle != NULL) {
Packit 534379
Packit 534379
		bmcDestroySDRs = dlsym(_handle->bmc_handle, "bmcDestroySDRs");
Packit 534379
		if (bmcDestroySDRs)
Packit 534379
			result = bmcDestroySDRs(records);
Packit 534379
		else
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
Packit 534379
	}
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
fpga_result xfpga_bmcReadSensorValues(struct _fpga_handle *_handle,
Packit 534379
		bmc_sdr_handle records,
Packit 534379
		bmc_values_handle *values,
Packit 534379
		uint32_t *num_values)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_NOT_FOUND;
Packit 534379
	fpga_result(*bmcReadSensorValues)(bmc_sdr_handle records, bmc_values_handle *values, uint32_t *num_values);
Packit 534379
Packit 534379
	if (_handle->bmc_handle != NULL) {
Packit 534379
Packit 534379
		bmcReadSensorValues = dlsym(_handle->bmc_handle, "bmcReadSensorValues");
Packit 534379
		if (bmcReadSensorValues)
Packit 534379
			result = bmcReadSensorValues(records, values, num_values);
Packit 534379
		else
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
Packit 534379
	}
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
fpga_result xfpga_bmcDestroySensorValues(struct _fpga_handle *_handle,
Packit 534379
		bmc_values_handle *values)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_NOT_FOUND;
Packit 534379
	fpga_result(*bmcDestroySensorValues)(bmc_values_handle *values);
Packit 534379
Packit 534379
	if (_handle->bmc_handle != NULL) {
Packit 534379
Packit 534379
		bmcDestroySensorValues = dlsym(_handle->bmc_handle, "bmcDestroySensorValues");
Packit 534379
		if (bmcDestroySensorValues)
Packit 534379
			result = bmcDestroySensorValues(values);
Packit 534379
		else
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
Packit 534379
	}
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result xfpga_bmcGetSensorReading(struct _fpga_handle *_handle,
Packit 534379
		bmc_values_handle values,
Packit 534379
		uint32_t sensor_number,
Packit 534379
		uint32_t *is_valid,
Packit 534379
		double *value)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_NOT_FOUND;
Packit 534379
	fpga_result(*bmcGetSensorReading)(bmc_values_handle values,
Packit 534379
		uint32_t sensor_number, uint32_t *is_valid,
Packit 534379
		double *value);
Packit 534379
Packit 534379
	if (_handle->bmc_handle != NULL) {
Packit 534379
Packit 534379
		bmcGetSensorReading = dlsym(_handle->bmc_handle, "bmcGetSensorReading");
Packit 534379
		if (bmcGetSensorReading)
Packit 534379
			result = bmcGetSensorReading(values, sensor_number, is_valid, value);
Packit 534379
		else
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
Packit 534379
	}
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result xfpga_bmcGetSDRDetails(struct _fpga_handle *_handle,
Packit 534379
		bmc_values_handle values,
Packit 534379
		uint32_t sensor_number,
Packit 534379
		sdr_details *details)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_NOT_FOUND;
Packit 534379
	fpga_result(*bmcGetSDRDetails)(bmc_values_handle values, uint32_t sensor_number,
Packit 534379
		sdr_details *details);
Packit 534379
Packit 534379
	if (_handle->bmc_handle != NULL) {
Packit 534379
Packit 534379
		bmcGetSDRDetails = dlsym(_handle->bmc_handle, "bmcGetSDRDetails");
Packit 534379
		if (bmcGetSDRDetails)
Packit 534379
			result = bmcGetSDRDetails(values, sensor_number, details);
Packit 534379
		else
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
Packit 534379
	}
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
// enumerates bmc power & theraml metrics info
Packit 534379
fpga_result  enum_bmc_metrics_info(struct _fpga_handle *_handle,
Packit 534379
				fpga_metric_vector *vector,
Packit 534379
				uint64_t *metric_num,
Packit 534379
				enum fpga_hw_type  hw_type)
Packit 534379
{
Packit 534379
	fpga_result result                      = FPGA_OK;
Packit 534379
	uint32_t x                              = 0;
Packit 534379
	uint32_t num_sensors                    = 0;
Packit 534379
	uint32_t num_values                     = 0;
Packit 534379
	enum fpga_metric_type metric_type       = FPGA_METRIC_TYPE_POWER;
Packit 534379
	char group_name[SYSFS_PATH_MAX]         = { 0, };
Packit 534379
	char qualifier_name[SYSFS_PATH_MAX]     = { 0, };
Packit 534379
	char units[SYSFS_PATH_MAX]              = { 0, };
Packit 534379
	sdr_details details;
Packit 534379
	bmc_sdr_handle records;
Packit 534379
	bmc_values_handle values;
Packit 534379
	size_t len;
Packit 534379
Packit 534379
	if (vector == NULL ||
Packit 534379
		metric_num == NULL) {
Packit 534379
		OPAE_ERR("Invalid input");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
	result = xfpga_bmcLoadSDRs(_handle, &records, &num_sensors);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to load BMC SDR.");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	result = xfpga_bmcReadSensorValues(_handle, records, &values, &num_values);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read BMC sensor values.");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	for (x = 0; x < num_sensors; x++) {
Packit 534379
		result = xfpga_bmcGetSDRDetails(_handle, values, x, &details);
Packit 534379
Packit 534379
Packit 534379
		if (details.sensor_type == BMC_THERMAL) {
Packit 534379
Packit 534379
			metric_type = FPGA_METRIC_TYPE_THERMAL;
Packit 534379
Packit 534379
			len = strnlen(THERLGMT, sizeof(group_name) - 1);
Packit 534379
			memcpy(group_name, THERLGMT, len);
Packit 534379
			group_name[len] = '\0';
Packit 534379
Packit 534379
			len = strnlen(TEMP, sizeof(units) - 1);
Packit 534379
			memcpy(units, TEMP, len);
Packit 534379
			units[len] = '\0';
Packit 534379
Packit 534379
			snprintf(qualifier_name, sizeof(qualifier_name),
Packit 534379
				 "%s:%s", THERLGMT, details.name);
Packit 534379
Packit 534379
		} else if (details.sensor_type == BMC_POWER) {
Packit 534379
Packit 534379
			metric_type = FPGA_METRIC_TYPE_POWER;
Packit 534379
Packit 534379
			len = strnlen(PWRMGMT, sizeof(group_name) - 1);
Packit 534379
			memcpy(group_name, PWRMGMT, len);
Packit 534379
			group_name[len] = '\0';
Packit 534379
Packit 534379
			snprintf(qualifier_name, sizeof(qualifier_name),
Packit 534379
				 "%s:%s", PWRMGMT, details.name);
Packit 534379
Packit 534379
			snprintf(units, sizeof(units), "%ls", details.units);
Packit 534379
		} else {
Packit 534379
				continue;
Packit 534379
		}
Packit 534379
Packit 534379
		result = add_metric_vector(vector, *metric_num,
Packit 534379
				qualifier_name, group_name, "",
Packit 534379
				details.name, "", units, FPGA_METRIC_DATATYPE_DOUBLE,
Packit 534379
				metric_type, hw_type, 0);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_MSG("Failed to add metrics");
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
Packit 534379
		*metric_num = *metric_num + 1;
Packit 534379
	}
Packit 534379
Packit 534379
	result = xfpga_bmcDestroySensorValues(_handle, &values);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to Destroy Sensor value.");
Packit 534379
	}
Packit 534379
Packit 534379
	result = xfpga_bmcDestroySDRs(_handle, &records);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to Destroy SDR.");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
// frees metrics info vector
Packit 534379
fpga_result free_fpga_enum_metrics_vector(struct _fpga_handle *_handle)
Packit 534379
{
Packit 534379
	fpga_result result        = FPGA_OK;
Packit 534379
	uint64_t i                = 0;
Packit 534379
	uint64_t num_enun_metrics = 0;
Packit 534379
Packit 534379
	if (_handle == NULL) {
Packit 534379
		OPAE_ERR("Invalid handle ");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if (_handle->magic != FPGA_HANDLE_MAGIC) {
Packit 534379
		OPAE_MSG("Invalid handle");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	result = fpga_vector_total(&(_handle->fpga_enum_metric_vector), &num_enun_metrics);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to get metric total");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	for (i = 0; i < num_enun_metrics; i++) {
Packit 534379
		fpga_vector_delete(&(_handle->fpga_enum_metric_vector), i);
Packit 534379
	}
Packit 534379
Packit 534379
	fpga_vector_free(&(_handle->fpga_enum_metric_vector));
Packit 534379
Packit 534379
	if (_handle->bmc_handle) {
Packit 534379
		dlclose(_handle->bmc_handle);
Packit 534379
		_handle->bmc_handle = NULL;
Packit 534379
	}
Packit 534379
Packit 534379
	clear_cached_values(_handle);
Packit 534379
	_handle->metric_enum_status = false;
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
// retrives fpga object type
Packit 534379
fpga_result get_fpga_object_type(fpga_handle handle,
Packit 534379
		fpga_objtype *objtype)
Packit 534379
{
Packit 534379
	fpga_result result     = FPGA_OK;
Packit 534379
	fpga_result resval     = FPGA_OK;
Packit 534379
	fpga_properties prop;
Packit 534379
Packit 534379
	result = xfpga_fpgaGetPropertiesFromHandle(handle, &prop);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get properties");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	result = fpgaPropertiesGetObjectType(prop, objtype);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to object type.");
Packit 534379
	}
Packit 534379
Packit 534379
	resval = (result != FPGA_OK) ? result : resval;
Packit 534379
	result = fpgaDestroyProperties(&prop);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy properties");
Packit 534379
	}
Packit 534379
Packit 534379
	resval = (result != FPGA_OK) ? result : resval;
Packit 534379
Packit 534379
	return resval;
Packit 534379
}
Packit 534379
Packit 534379
void *metrics_load_bmc_lib(void)
Packit 534379
{
Packit 534379
	char plugin_path[PATH_MAX] = { 0, };
Packit 534379
	const char *search_paths[] = { OPAE_MODULE_SEARCH_PATHS };
Packit 534379
	unsigned i;
Packit 534379
	void *dl_handle;
Packit 534379
Packit 534379
	for (i = 0 ;
Packit 534379
		i < sizeof(search_paths) / sizeof(search_paths[0]) ;
Packit 534379
		++i) {
Packit 534379
Packit 534379
		snprintf(plugin_path, sizeof(plugin_path),
Packit 534379
			 "%s%s", search_paths[i], BMC_LIB);
Packit 534379
Packit 534379
		dl_handle = dlopen(plugin_path, RTLD_LAZY | RTLD_LOCAL);
Packit 534379
		if (dl_handle)
Packit 534379
			return dl_handle;
Packit 534379
	}
Packit 534379
Packit 534379
	return NULL;
Packit 534379
}
Packit 534379
Packit 534379
// enumerates FME & AFU metrics info
Packit 534379
fpga_result enum_fpga_metrics(fpga_handle handle)
Packit 534379
{
Packit 534379
	fpga_result result              = FPGA_OK;
Packit 534379
	struct _fpga_token *_token      = NULL;
Packit 534379
	enum fpga_hw_type hw_type	= FPGA_HW_UNKNOWN;
Packit 534379
	uint64_t mmio_offset            = 0;
Packit 534379
	uint64_t metric_num             = 0;
Packit 534379
	char metrics_path[SYSFS_PATH_MAX] = { 0 };
Packit 534379
Packit 534379
	fpga_objtype objtype;
Packit 534379
Packit 534379
	struct _fpga_handle *_handle = (struct _fpga_handle *)handle;
Packit 534379
Packit 534379
	if (_handle == NULL) {
Packit 534379
		OPAE_ERR("Invalid handle ");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if (_handle->metric_enum_status)
Packit 534379
		return FPGA_OK;
Packit 534379
Packit 534379
	_token = (struct _fpga_token *)_handle->token;
Packit 534379
	if (_token == NULL) {
Packit 534379
		OPAE_ERR("Invalid token within handle");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	result = get_fpga_object_type(handle, &objtype);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to init vector");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	// Init vector
Packit 534379
	result = fpga_vector_init(&(_handle->fpga_enum_metric_vector));
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to init vector");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	if (objtype == FPGA_ACCELERATOR) {
Packit 534379
		// enum AFU
Packit 534379
		result = discover_afu_metrics_feature(handle, &mmio_offset);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to discover AFU Metrics BBB");
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
Packit 534379
Packit 534379
		result = enum_afu_metrics(handle,
Packit 534379
			&(_handle->fpga_enum_metric_vector),
Packit 534379
			&metric_num,
Packit 534379
			mmio_offset);
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_ERR("Failed to enum AFU metrics BBB");
Packit 534379
				return result;
Packit 534379
			}
Packit 534379
Packit 534379
Packit 534379
	} else	if (objtype == FPGA_DEVICE) {
Packit 534379
		// enum FME
Packit 534379
Packit 534379
		// get fpga hw type.
Packit 534379
		result = get_fpga_hw_type(_handle, &hw_type);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to discover hardware type.");
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
Packit 534379
Packit 534379
		switch (hw_type) {
Packit 534379
			// MCP
Packit 534379
		case FPGA_HW_MCP: {
Packit 534379
Packit 534379
			memset(metrics_path, 0, SYSFS_PATH_MAX);
Packit 534379
Packit 534379
			if (sysfs_get_fme_pwr_path(_token, metrics_path) == FPGA_OK) {
Packit 534379
				result = enum_powermgmt_metrics(&(_handle->fpga_enum_metric_vector), &metric_num, metrics_path, FPGA_HW_MCP);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_ERR("Failed to Enum Power metrics.");
Packit 534379
				}
Packit 534379
			}
Packit 534379
Packit 534379
			memset(metrics_path, 0, SYSFS_PATH_MAX);
Packit 534379
			if (sysfs_get_fme_temp_path(_token, metrics_path) == FPGA_OK) {
Packit 534379
				result = enum_thermalmgmt_metrics(&(_handle->fpga_enum_metric_vector), &metric_num, metrics_path, FPGA_HW_MCP);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_ERR("Failed to Enum Thermal metrics.");
Packit 534379
				}
Packit 534379
			}
Packit 534379
Packit 534379
			memset(metrics_path, 0, SYSFS_PATH_MAX);
Packit 534379
			if (sysfs_get_fme_perf_path(_token, metrics_path) == FPGA_OK) {
Packit 534379
				result = enum_perf_counter_metrics(&(_handle->fpga_enum_metric_vector), &metric_num, metrics_path, FPGA_HW_MCP);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_ERR("Failed to Enum Performance metrics.");
Packit 534379
				}
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
		break;
Packit 534379
Packit 534379
		 // DCP RC
Packit 534379
		case FPGA_HW_DCP_RC: {
Packit 534379
Packit 534379
			memset(metrics_path, 0, SYSFS_PATH_MAX);
Packit 534379
			if (sysfs_get_fme_perf_path(_token, metrics_path) == FPGA_OK) {
Packit 534379
Packit 534379
				result = enum_perf_counter_metrics(&(_handle->fpga_enum_metric_vector), &metric_num, metrics_path, FPGA_HW_DCP_RC);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_ERR("Failed to Enum Performance metrics.");
Packit 534379
				}
Packit 534379
			}
Packit 534379
Packit 534379
			memset(metrics_path, 0, SYSFS_PATH_MAX);
Packit 534379
			if (sysfs_get_bmc_path(_token, metrics_path) == FPGA_OK) {
Packit 534379
Packit 534379
				if (_handle->bmc_handle == NULL)
Packit 534379
					_handle->bmc_handle = metrics_load_bmc_lib();
Packit 534379
Packit 534379
				if (_handle->bmc_handle) {
Packit 534379
					result = enum_bmc_metrics_info(_handle, &(_handle->fpga_enum_metric_vector), &metric_num, FPGA_HW_DCP_RC);
Packit 534379
					if (result != FPGA_OK) {
Packit 534379
						OPAE_ERR("Failed to enumerate BMC metrics.");
Packit 534379
					}
Packit 534379
Packit 534379
				}
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
		break;
Packit 534379
Packit 534379
		// DCP VC DC
Packit 534379
		case FPGA_HW_DCP_DC:
Packit 534379
		case FPGA_HW_DCP_VC: {
Packit 534379
Packit 534379
			memset(metrics_path, 0, SYSFS_PATH_MAX);
Packit 534379
			if (sysfs_get_max10_path(_token, metrics_path) == FPGA_OK) {
Packit 534379
Packit 534379
				// Max10 Power & Thermal
Packit 534379
				result = enum_max10_metrics_info(_handle,
Packit 534379
					&(_handle->fpga_enum_metric_vector),
Packit 534379
					&metric_num,
Packit 534379
					hw_type);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_ERR("Failed to Enum Power and Thermal metrics.");
Packit 534379
				}
Packit 534379
			}
Packit 534379
Packit 534379
			memset(metrics_path, 0, SYSFS_PATH_MAX);
Packit 534379
			if (sysfs_get_fme_perf_path(_token, metrics_path) == FPGA_OK) {
Packit 534379
Packit 534379
				// Perf Counters
Packit 534379
				result = enum_perf_counter_metrics(&(_handle->fpga_enum_metric_vector), &metric_num, _token->sysfspath, hw_type);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_ERR("Failed to Enum Performance metrics.");
Packit 534379
				}
Packit 534379
			}
Packit 534379
		}
Packit 534379
		break;
Packit 534379
Packit 534379
		default:
Packit 534379
			OPAE_MSG("Unknown hardware type.");
Packit 534379
			result = FPGA_EXCEPTION;
Packit 534379
		}
Packit 534379
Packit 534379
	} // if Object type
Packit 534379
Packit 534379
	if (result != FPGA_OK)
Packit 534379
		free_fpga_enum_metrics_vector(_handle);
Packit 534379
Packit 534379
	_handle->metric_enum_status = true;
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
fpga_result add_metric_info(struct _fpga_enum_metric *_enum_metrics,
Packit 534379
			struct fpga_metric_info *fpga_metric_info)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_OK;
Packit 534379
	size_t len;
Packit 534379
Packit 534379
	if (_enum_metrics == NULL ||
Packit 534379
		fpga_metric_info == NULL) {
Packit 534379
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	len = strnlen(_enum_metrics->group_name, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_metric_info->group_name, _enum_metrics->group_name, len);
Packit 534379
	fpga_metric_info->group_name[len] = '\0';
Packit 534379
Packit 534379
	len = strnlen(_enum_metrics->metric_name, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_metric_info->metric_name, _enum_metrics->metric_name, len);
Packit 534379
	fpga_metric_info->metric_name[len] = '\0';
Packit 534379
Packit 534379
	len = strnlen(_enum_metrics->qualifier_name, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_metric_info->qualifier_name, _enum_metrics->qualifier_name, len);
Packit 534379
	fpga_metric_info->qualifier_name[len] = '\0';
Packit 534379
Packit 534379
	len = strnlen(_enum_metrics->metric_units, SYSFS_PATH_MAX - 1);
Packit 534379
	memcpy(fpga_metric_info->metric_units, _enum_metrics->metric_units, len);
Packit 534379
	fpga_metric_info->metric_units[len] = '\0';
Packit 534379
Packit 534379
	fpga_metric_info->metric_num = _enum_metrics->metric_num;
Packit 534379
	fpga_metric_info->metric_type = _enum_metrics->metric_type;
Packit 534379
	fpga_metric_info->metric_datatype = _enum_metrics->metric_datatype;
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
// Reads bmc metric value
Packit 534379
fpga_result get_bmc_metrics_values(fpga_handle handle,
Packit 534379
				struct _fpga_enum_metric *_fpga_enum_metric,
Packit 534379
				struct fpga_metric *fpga_metric)
Packit 534379
{
Packit 534379
	fpga_result result                  = FPGA_OK;
Packit 534379
	uint32_t num_sensors                = 0;
Packit 534379
	uint32_t num_values                 = 0;
Packit 534379
	uint32_t x                          = 0;
Packit 534379
	uint32_t is_valid                   = 0;
Packit 534379
	double tmp                          = 0;
Packit 534379
	int metric_indicator                = 0;
Packit 534379
	bmc_sdr_handle records;
Packit 534379
	bmc_values_handle values;
Packit 534379
	sdr_details details;
Packit 534379
	size_t len;
Packit 534379
Packit 534379
	struct _fpga_handle *_handle = (struct _fpga_handle *)handle;
Packit 534379
Packit 534379
	if (_handle->_bmc_metric_cache_value) {
Packit 534379
Packit 534379
		for (x = 0; x < _handle->num_bmc_metric; x++) {
Packit 534379
Packit 534379
			metric_indicator = strcasecmp(_handle->_bmc_metric_cache_value[x].metric_name,
Packit 534379
				_fpga_enum_metric->metric_name);
Packit 534379
Packit 534379
			if (metric_indicator == 0) {
Packit 534379
				fpga_metric->value.dvalue = _handle->_bmc_metric_cache_value[x].fpga_metric.value.dvalue;
Packit 534379
				return result;
Packit 534379
			}
Packit 534379
		}
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	result = xfpga_bmcLoadSDRs(_handle, &records, &num_sensors);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to load BMC SDR.");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	if (_handle->_bmc_metric_cache_value == NULL) {
Packit 534379
		_handle->_bmc_metric_cache_value = calloc(sizeof(struct _fpga_bmc_metric), num_sensors);
Packit 534379
		if (_handle->_bmc_metric_cache_value == NULL) {
Packit 534379
			OPAE_ERR("Failed to allocate memory");
Packit 534379
			result = FPGA_NO_MEMORY;
Packit 534379
			goto out_destroy;
Packit 534379
		}
Packit 534379
		_handle->num_bmc_metric = num_sensors;
Packit 534379
	}
Packit 534379
Packit 534379
	result = xfpga_bmcReadSensorValues(_handle, records, &values, &num_values);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read BMC sensor values.");
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	for (x = 0; x < num_sensors; x++) {
Packit 534379
Packit 534379
		result = xfpga_bmcGetSDRDetails(_handle, values, x, &details);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_MSG("Failed to get SDR details.");
Packit 534379
		}
Packit 534379
Packit 534379
		result = xfpga_bmcGetSensorReading(_handle, values, x, &is_valid, &tmp);
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_MSG("Failed to read sensor readings.");
Packit 534379
			continue;
Packit 534379
		}
Packit 534379
Packit 534379
		if (!is_valid) {
Packit 534379
			continue;
Packit 534379
		}
Packit 534379
Packit 534379
		len = strnlen(details.name, sizeof(_handle->_bmc_metric_cache_value[x].metric_name) - 1);
Packit 534379
		memcpy(_handle->_bmc_metric_cache_value[x].metric_name, details.name, len);
Packit 534379
		_handle->_bmc_metric_cache_value[x].metric_name[len] = '\0';
Packit 534379
Packit 534379
		_handle->_bmc_metric_cache_value[x].fpga_metric.value.dvalue = tmp;
Packit 534379
Packit 534379
		metric_indicator = strcasecmp(details.name, _fpga_enum_metric->metric_name);
Packit 534379
		if (metric_indicator == 0) {
Packit 534379
			fpga_metric->value.dvalue = tmp;
Packit 534379
		}
Packit 534379
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	result = xfpga_bmcDestroySensorValues(_handle, &values);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to Destroy Sensor value.");
Packit 534379
	}
Packit 534379
Packit 534379
out_destroy:
Packit 534379
	result = xfpga_bmcDestroySDRs(_handle, &records);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to Destroy SDR.");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
// Reads mcp power & thermal metric value
Packit 534379
fpga_result get_pwr_thermal_max10_value(const char *sysfs_path,
Packit 534379
	double *dvalue)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_OK;
Packit 534379
Packit 534379
	uint64_t value;
Packit 534379
Packit 534379
	if (sysfs_path == NULL ||
Packit 534379
		dvalue == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	result = sysfs_read_u64(sysfs_path, &value);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to read Metrics values");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	*dvalue = ((double)value / MILLI);
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
// Reads mcp power & thermal metric value
Packit 534379
fpga_result get_pwr_thermal_value(const char *sysfs_path,
Packit 534379
				uint64_t *value)
Packit 534379
{
Packit 534379
	fpga_result result       = FPGA_OK;
Packit 534379
	char *ptr                = NULL;
Packit 534379
Packit 534379
	if (sysfs_path == NULL ||
Packit 534379
		value == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	result = sysfs_read_u64(sysfs_path, value);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read Metrics values");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	ptr = strstr(sysfs_path, FPGA_LIMIT);
Packit 534379
	if (ptr)
Packit 534379
		*value = *value / 8;
Packit 534379
Packit 534379
	ptr = NULL;
Packit 534379
	ptr = strstr(sysfs_path, XEON_LIMIT);
Packit 534379
	if (ptr)
Packit 534379
		*value = *value / 8;
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
// Reads mcp power & thermal metric value
Packit 534379
fpga_result get_performance_counter_value(const char *group_sysfs,
Packit 534379
				const char *metric_sysfs,
Packit 534379
				uint64_t *value)
Packit 534379
{
Packit 534379
	fpga_result result                  = FPGA_OK;
Packit 534379
	char sysfs_path[SYSFS_PATH_MAX]     = { 0, };
Packit 534379
	uint64_t val                        = 0;
Packit 534379
Packit 534379
	if (group_sysfs == NULL ||
Packit 534379
		metric_sysfs == NULL ||
Packit 534379
		value == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	snprintf(sysfs_path, sizeof(sysfs_path),
Packit 534379
		 "%s/%s", group_sysfs, PERF_ENABLE);
Packit 534379
Packit 534379
	result = metric_sysfs_path_is_file(sysfs_path);
Packit 534379
	if (result == FPGA_OK) {
Packit 534379
		result = sysfs_read_u64(sysfs_path, &val;;
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to read perf fabric enable");
Packit 534379
		}
Packit 534379
Packit 534379
		if (val == 0x0) {
Packit 534379
			// Writer Fabric Enable
Packit 534379
			result = sysfs_write_u64_decimal(sysfs_path, 1);;
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_ERR("Failed to read perf fabric enable");
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
	snprintf(sysfs_path, sizeof(sysfs_path),
Packit 534379
		 "%s/%s", group_sysfs, PERF_FREEZE);
Packit 534379
Packit 534379
	result = metric_sysfs_path_is_file(sysfs_path);
Packit 534379
	if (result == FPGA_OK) {
Packit 534379
Packit 534379
		result = sysfs_read_u64(sysfs_path, &val;;
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to read perf fabric freeze");
Packit 534379
		}
Packit 534379
Packit 534379
		if (val != 0x1) {
Packit 534379
			// Write Fabric Freeze
Packit 534379
			result = sysfs_write_u64(sysfs_path, 1);
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_ERR("Failed to write perf fabric freeze");
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
	*value = 0;
Packit 534379
	result = sysfs_read_u64(metric_sysfs, value);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("--Failed to read Metrics values");
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	snprintf(sysfs_path, sizeof(sysfs_path),
Packit 534379
		 "%s/%s", group_sysfs, PERF_FREEZE);
Packit 534379
Packit 534379
	result = metric_sysfs_path_is_file(sysfs_path);
Packit 534379
	if (result == FPGA_OK) {
Packit 534379
Packit 534379
		result = sysfs_read_u64(sysfs_path, &val;;
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to read perf fabric freeze");
Packit 534379
Packit 534379
		}
Packit 534379
Packit 534379
		if (val == 0x1) {
Packit 534379
			// Write Fabric Freeze
Packit 534379
			result = sysfs_write_u64(sysfs_path, 0);
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_ERR("Failed to write perf fabric freeze");
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
	result = FPGA_OK;
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
// Reads fme metric value
Packit 534379
fpga_result  get_fme_metric_value(fpga_handle handle,
Packit 534379
					fpga_metric_vector *enum_vector,
Packit 534379
					uint64_t metric_num,
Packit 534379
					struct fpga_metric *fpga_metric)
Packit 534379
{
Packit 534379
	fpga_result result                          = FPGA_OK;
Packit 534379
	uint64_t index                              = 0;
Packit 534379
	struct _fpga_enum_metric *_fpga_enum_metric = NULL;
Packit 534379
	uint64_t num_enun_metrics                  = 0;
Packit 534379
	metric_value value = {0};
Packit 534379
Packit 534379
	if (enum_vector == NULL ||
Packit 534379
		fpga_metric == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	result = fpga_vector_total(enum_vector, &num_enun_metrics);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get metric total");
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	fpga_metric->isvalid = false;
Packit 534379
	result = FPGA_NOT_FOUND;
Packit 534379
	for (index = 0; index < num_enun_metrics ; index++) {
Packit 534379
Packit 534379
		_fpga_enum_metric = (struct _fpga_enum_metric *)	fpga_vector_get(enum_vector, index);
Packit 534379
Packit 534379
		if (metric_num == _fpga_enum_metric->metric_num) {
Packit 534379
Packit 534379
			// Found Metic
Packit 534379
			memset(&value, 0, sizeof(value));
Packit 534379
Packit 534379
			// DCP Power & Thermal
Packit 534379
			if ((_fpga_enum_metric->hw_type == FPGA_HW_DCP_RC) &&
Packit 534379
				((_fpga_enum_metric->metric_type == FPGA_METRIC_TYPE_POWER) ||
Packit 534379
				(_fpga_enum_metric->metric_type == FPGA_METRIC_TYPE_THERMAL))) {
Packit 534379
Packit 534379
Packit 534379
				result  = get_bmc_metrics_values(handle, _fpga_enum_metric, fpga_metric);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_MSG("Failed to get BMC metric value");
Packit 534379
				} else {
Packit 534379
					fpga_metric->isvalid = true;
Packit 534379
				}
Packit 534379
				fpga_metric->metric_num = metric_num;
Packit 534379
Packit 534379
			 }
Packit 534379
Packit 534379
			if ((_fpga_enum_metric->hw_type == FPGA_HW_MCP) &&
Packit 534379
				((_fpga_enum_metric->metric_type == FPGA_METRIC_TYPE_POWER) ||
Packit 534379
				(_fpga_enum_metric->metric_type == FPGA_METRIC_TYPE_THERMAL))) {
Packit 534379
Packit 534379
				result = get_pwr_thermal_value(_fpga_enum_metric->metric_sysfs, &value.ivalue);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_MSG("Failed to get BMC metric value");
Packit 534379
				} else {
Packit 534379
					fpga_metric->isvalid = true;
Packit 534379
				}
Packit 534379
				fpga_metric->value = value;
Packit 534379
				fpga_metric->metric_num = metric_num;
Packit 534379
Packit 534379
			}
Packit 534379
Packit 534379
			// Read power theraml values from Max10
Packit 534379
			if (((_fpga_enum_metric->hw_type == FPGA_HW_DCP_DC) ||
Packit 534379
				(_fpga_enum_metric->hw_type == FPGA_HW_DCP_VC)) &&
Packit 534379
				((_fpga_enum_metric->metric_type == FPGA_METRIC_TYPE_POWER) ||
Packit 534379
				(_fpga_enum_metric->metric_type == FPGA_METRIC_TYPE_THERMAL))) {
Packit 534379
Packit 534379
				result = read_max10_value(_fpga_enum_metric, &value.dvalue);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_MSG("Failed to get Max10 metric value");
Packit 534379
				} else {
Packit 534379
					fpga_metric->isvalid = true;
Packit 534379
				}
Packit 534379
				fpga_metric->value = value;
Packit 534379
				fpga_metric->metric_num = metric_num;
Packit 534379
Packit 534379
			}
Packit 534379
Packit 534379
Packit 534379
			if (_fpga_enum_metric->metric_type == FPGA_METRIC_TYPE_PERFORMANCE_CTR) {
Packit 534379
Packit 534379
Packit 534379
				result = get_performance_counter_value(_fpga_enum_metric->group_sysfs, _fpga_enum_metric->metric_sysfs, &value.ivalue);
Packit 534379
				if (result != FPGA_OK) {
Packit 534379
					OPAE_MSG("Failed to get perf metric value");
Packit 534379
				} else {
Packit 534379
					fpga_metric->isvalid = true;
Packit 534379
				}
Packit 534379
				fpga_metric->value = value;
Packit 534379
				fpga_metric->metric_num = metric_num;
Packit 534379
Packit 534379
			}
Packit 534379
Packit 534379
			break;
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
// parses metric name strings
Packit 534379
fpga_result  parse_metric_num_name(const char *search_string,
Packit 534379
				fpga_metric_vector *fpga_enum_metrics_vector,
Packit 534379
				uint64_t *metric_num)
Packit 534379
{
Packit 534379
	fpga_result result                          = FPGA_OK;
Packit 534379
	char *str                                   = NULL;
Packit 534379
	char *str_last                              = NULL;
Packit 534379
	uint64_t i                                  = 0;
Packit 534379
	struct _fpga_enum_metric *fpga_enum_metric  = NULL;
Packit 534379
	char qualifier_name[SYSFS_PATH_MAX]         = { 0, };
Packit 534379
	char metrics_name[SYSFS_PATH_MAX]           = { 0, };
Packit 534379
	int qualifier_indicator                     = 0;
Packit 534379
	int metric_indicator                        = 0;
Packit 534379
	uint64_t num_enun_metrics                   = 0;
Packit 534379
	size_t len;
Packit 534379
Packit 534379
	if (search_string == NULL ||
Packit 534379
		fpga_enum_metrics_vector == NULL ||
Packit 534379
		metric_num == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	str = strrchr(search_string, ':');
Packit 534379
	if (!str) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	// Metric Name
Packit 534379
	len = strnlen(str + 1, FPGA_METRIC_STR_SIZE - 1);
Packit 534379
	memcpy(metrics_name, str + 1, len);
Packit 534379
	metrics_name[len] = '\0';
Packit 534379
Packit 534379
	// qualifier_name
Packit 534379
	str_last = strrchr(search_string, ':');
Packit 534379
	if (!str_last) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	memcpy(qualifier_name, search_string, str_last - search_string);
Packit 534379
	qualifier_name[str_last - search_string] = '\0';
Packit 534379
Packit 534379
	result = fpga_vector_total(fpga_enum_metrics_vector, &num_enun_metrics);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get metric total");
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	for (i = 0; i < num_enun_metrics; i++) {
Packit 534379
		fpga_enum_metric = (struct _fpga_enum_metric *) fpga_vector_get(fpga_enum_metrics_vector, i);
Packit 534379
Packit 534379
		qualifier_indicator = strcasecmp(fpga_enum_metric->qualifier_name, qualifier_name);
Packit 534379
		metric_indicator = strcasecmp(fpga_enum_metric->metric_name, metrics_name);
Packit 534379
Packit 534379
		if (qualifier_indicator == 0 &&
Packit 534379
			metric_indicator == 0) {
Packit 534379
Packit 534379
			*metric_num = fpga_enum_metric->metric_num;
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
Packit 534379
	} // end of for loop
Packit 534379
Packit 534379
	return FPGA_NOT_FOUND;
Packit 534379
}
Packit 534379
Packit 534379
// clears BMC values
Packit 534379
fpga_result  clear_cached_values(fpga_handle handle)
Packit 534379
{
Packit 534379
	struct _fpga_handle *_handle = (struct _fpga_handle *)handle;
Packit 534379
	fpga_result result           = FPGA_OK;
Packit 534379
Packit 534379
	if (_handle->_bmc_metric_cache_value) {
Packit 534379
		free(_handle->_bmc_metric_cache_value);
Packit 534379
		_handle->_bmc_metric_cache_value = NULL;
Packit 534379
	}
Packit 534379
Packit 534379
	_handle->num_bmc_metric = 0;
Packit 534379
	return result;
Packit 534379
}