Event counter support

XGMI related events are supported

Change-Id: If17036fe890c8be45da3654353599821b5828c14
This commit is contained in:
Chris Freehill
2019-06-22 20:54:31 -05:00
parent 04479f0b44
commit ea26baec20
13 changed files with 1344 additions and 19 deletions
+209 -12
View File
@@ -109,7 +109,11 @@ typedef enum {
RSMI_STATUS_NOT_FOUND, //!< An item was searched for but not
//!< found
RSMI_STATUS_INSUFFICIENT_SIZE, //!< Not enough resources were
//!< for the operation
//!< available for the operation
RSMI_STATUS_INTERRUPT, //!< An interrupt occurred during
//!< execution of function
RSMI_STATUS_UNEXPECTED_SIZE, //!< An unexpected amount of data
//!< was read
RSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF, //!< An unknown error occurred
} rsmi_status_t;
@@ -171,6 +175,74 @@ typedef enum {
RSMI_SW_COMP_LAST = RSMI_SW_COMP_DRIVER
} rsmi_sw_component_t;
/**
* Event counter types
*/
/**
* @brief Handle to performance event counter
*/
typedef uintptr_t rsmi_event_handle_t;
/**
* Event Groups
*
* @brief Enum denoting an event group. The value of the enum is the
* base value for all the event enums in the group.
*/
typedef enum {
RSMI_EVNT_GRP_XGMI = 0, //!< Data Fabric (XGMI) related events
RSMI_EVNT_GRP_INVALID = 0xFFFFFFFF
} rsmi_event_group_t;
/**
* Event types
* @brief Event type enum. Events belonging to a particular event group
* ::rsmi_event_group_t should begin ennumerating at the ::rsmi_event_group_t
* value for that group.
*/
typedef enum {
RSMI_EVNT_FIRST = RSMI_EVNT_GRP_XGMI,
RSMI_EVNT_XGMI_FIRST = RSMI_EVNT_GRP_XGMI,
RSMI_EVNT_XGMI_0_NOP_TX = RSMI_EVNT_XGMI_FIRST, //!< NOPs sent to neighbor 0
RSMI_EVNT_XGMI_0_REQUEST_TX, //!< Outgoing requests to
//!< neighbor 0
RSMI_EVNT_XGMI_0_RESPONSE_TX, //!< Outgoing responses to
//!< neighbor 0
RSMI_EVNT_XGMI_0_BEATS_TX, //!< Data beats sent to
//!< neighbor 0
RSMI_EVNT_XGMI_1_NOP_TX, //!< NOPs sent to neighbor 1
RSMI_EVNT_XGMI_1_REQUEST_TX, //!< Outgoing requests to
//!< neighbor 1
RSMI_EVNT_XGMI_1_RESPONSE_TX, //!< Outgoing responses to
//!< neighbor 1
RSMI_EVNT_XGMI_1_BEATS_TX, //!< Data beats sent to
//!< neighbor 1
RSMI_EVNT_XGMI_LAST = RSMI_EVNT_XGMI_1_BEATS_TX,
RSMI_EVNT_LAST = RSMI_EVNT_XGMI_LAST
} rsmi_event_type_t;
/**
* Event counter commands
*/
typedef enum {
RSMI_CNTR_CMD_START = 0, //!< Start the counter
RSMI_CNTR_CMD_STOP, //!< Stop the counter
} rsmi_counter_command_t;
/**
* Counter value
*/
typedef struct {
uint64_t value; //!< Counter value
uint64_t time_enabled; //!< Time that the counter was enabled
uint64_t time_running; //!< Time that che counter was running
} rsmi_counter_value_t;
/**
* Clock types
*/
@@ -876,9 +948,8 @@ rsmi_status_t rsmi_dev_pci_bandwidth_set(uint32_t dv_ind, uint64_t bw_bitmask);
* device index.
*
* @details Given a device index @p dv_ind and a pointer to a uint64_t
* @p power, this function will write the current average power consumption to
* the uint64_t in microwatts pointed to by @p power. This function requires
* root privilege.
* @p power, this function will write the current average power consumption
* (in microwatts) to the uint64_t pointed to by @p power.
*
* @param[in] dv_ind a device index
*
@@ -1077,16 +1148,13 @@ rsmi_status_t rsmi_dev_fan_rpms_get(uint32_t dv_ind, uint32_t sensor_ind,
int64_t *speed);
/**
* @brief Get the fan speed for the specified device in RPMs.
*
* @details Given a device index @p dv_ind
* this function will get the fan speed.
*
* @param[in] dv_ind a device index
* @brief Get the fan speed for the specified device as a value relative to
* ::RSMI_MAX_FAN_SPEED
*
* @details Given a device index @p dv_ind and a pointer to a uint32_t
* @p speed, this function will write the current fan speed (a value
* between 0 and 255) to the uint32_t pointed to by @p speed
* between 0 and the maximum fan speed, ::RSMI_MAX_FAN_SPEED) to the uint32_t
* pointed to by @p speed
*
* @param[in] dv_ind a device index
*
@@ -1268,7 +1336,8 @@ rsmi_status_t rsmi_dev_overdrive_level_get(uint32_t dv_ind, uint32_t *od);
* @param[in] clk_type the type of clock for which the frequency is desired
*
* @param[inout] f a pointer to a caller provided ::rsmi_frequencies_t structure
* to which the frequency information will be written
* to which the frequency information will be written. Frequency values are in
* Hz.
*
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
*
@@ -1628,6 +1697,134 @@ rsmi_status_string(rsmi_status_t status, const char **status_string);
/** @} */ // end of ErrQuer
/*****************************************************************************/
/** @defgroup PerfCntr Performance Counter Functions
* These functions are used to configure, query and control performance
* counting.
* @{
*/
/**
* @brief Tell if an event group is supported by a given device
*
* @details Given a device index @p dv_ind and an event group specifier @p
* group, tell if @p group type events are supported by the device associated
* with @p dv_ind
*
* @param[in] dv_ind device index of device being queried
*
* @param[in] group ::rsmi_event_group_t identifier of group for which support
* is being queried
*
* @retval
* ::RSMI_STATUS_SUCCESS if the device associatee with @p dv_ind
* support counting events of the type indicated by @p group.
*
* ::RSMI_STATUS_NOT_SUPPORTED If the device does not support event group @p
* group
*
*/
rsmi_status_t
rsmi_dev_counter_group_supported(uint32_t dv_ind, rsmi_event_group_t group);
/**
* @brief Create a performance counter object
*
* @details Create a performance counter object of type @p type for the device
* with a device index of @p dv_ind, and write a handle to the object to the
* memory location pointed to by @p evnt_handle. @p evnt_handle can be used
* with other performance event operations. The handle should be deallocated
* with ::rsmi_dev_counter_destroy() when no longer needed.
*
* @param[in] dv_ind a device index
*
* @param[in] type the type of performance event to create
*
* @param[inout] evnt_handle A pointer to a ::rsmi_event_handle_t which will be
* associated with a newly allocated counter
*
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call
*
*/
rsmi_status_t
rsmi_dev_counter_create(uint32_t dv_ind, rsmi_event_type_t type,
rsmi_event_handle_t *evnt_handle);
/**
* @brief Deallocate a performance counter object
*
* @details Deallocate the performance counter object with the provided
* ::rsmi_event_handle_t @p evnt_handle
*
* @param[in] evnt_handle handle to event object to be deallocated
*
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call
*
*/
rsmi_status_t
rsmi_dev_counter_destroy(rsmi_event_handle_t evnt_handle);
/**
* @brief Issue performance counter control commands
*
* @details Issue a command @p cmd on the event counter associated with the
* provided handle @p evt_handle.
*
* @param[in] evt_handle an event handle
*
* @param[in] cmd The event counter command to be issued
*
* @param[inout] cmd_args Currently not used. Should be set to NULL.
*
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call
*
*/
rsmi_status_t
rsmi_counter_control(rsmi_event_handle_t evt_handle,
rsmi_counter_command_t cmd, void *cmd_args);
/**
* @brief Read the current value of a performance counter
*
* @details Read the current counter value of the counter associated with the
* provided handle @p evt_handle and write the value to the location pointed
* to by @p value.
*
* @param[in] evt_handle an event handle
*
* @param[inout] value pointer to memory of size of ::rsmi_counter_value_t to
* which the counter value will be written
*
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call
*
*/
rsmi_status_t
rsmi_counter_read(rsmi_event_handle_t evt_handle,
rsmi_counter_value_t *value);
/**
* @brief Get the number of currently available counters
*
* @details Given a device index @p dv_ind, a performance event group @p grp,
* and a pointer to a uint32_t @p available, this function will write the
* number of @p grp type counters that are available on the device with index
* @p dv_ind to the memory that @p available points to.
*
* @param[in] dv_ind a device index
*
* @param[in] grp an event device group
*
* @param[inout] available A pointer to a uint32_t to which the number of
* available counters will be written
*
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call
*
*/
rsmi_status_t
rsmi_counter_available_counters_get(uint32_t dv_ind,
rsmi_event_group_t grp, uint32_t *available);
/** @} */ // end of PerfCntr
#ifdef __cplusplus
}
#endif // __cplusplus
+124
View File
@@ -0,0 +1,124 @@
/*
* =============================================================================
* ROC Runtime Conformance Release License
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2019, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#ifndef INCLUDE_ROCM_SMI_ROCM_SMI_COUNTERS_H_
#define INCLUDE_ROCM_SMI_ROCM_SMI_COUNTERS_H_
#include <linux/perf_event.h>
#include <cstdint>
#include <vector>
#include <unordered_set>
#include <string>
#include "rocm_smi/rocm_smi.h"
namespace amd {
namespace smi {
namespace evt {
class RSMIEventGrpHashFunction {
public:
size_t operator()(const rsmi_event_group_t& grp) const {
return static_cast<size_t>(grp);
}
};
typedef std::unordered_set<rsmi_event_group_t, RSMIEventGrpHashFunction>
dev_evt_grp_set_t;
void
GetSupportedEventGroups(uint32_t dev_ind, dev_evt_grp_set_t*supported_grps);
struct evnt_info_t {
uint8_t start_bit;
uint8_t field_size;
uint32_t value;
};
struct perf_read_format_t {
union {
struct {
uint64_t value;
uint64_t enabled_time;
uint64_t run_time;
};
uint64_t values[3];
};
};
class Event {
public:
explicit Event(rsmi_event_type_t event, uint32_t dev_ind);
~Event(void);
uint32_t openPerfHandle();
uint32_t startCounter(void);
uint32_t stopCounter(void);
uint32_t getValue(rsmi_counter_value_t *val);
uint32_t dev_file_ind(void) const {return dev_file_ind_;}
uint32_t dev_ind(void) const {return dev_ind_;}
private:
// perf_event_attr fields
std::vector<evnt_info_t> event_info_;
std::string evt_path_root_;
rsmi_event_type_t event_type_;
uint32_t dev_file_ind_;
uint32_t dev_ind_;
int32_t fd_;
perf_event_attr attr_;
uint32_t get_event_file_info(void);
uint32_t get_event_type(uint32_t *ev_type);
};
} // namespace evt
} // namespace smi
} // namespace amd
#endif // INCLUDE_ROCM_SMI_ROCM_SMI_COUNTERS_H_
+7
View File
@@ -50,11 +50,13 @@
#include <utility>
#include <cstdint>
#include <vector>
#include <unordered_set>
#include "rocm_smi/rocm_smi_monitor.h"
#include "rocm_smi/rocm_smi_power_mon.h"
#include "rocm_smi/rocm_smi_common.h"
#include "rocm_smi/rocm_smi.h"
#include "rocm_smi/rocm_smi_counters.h"
extern "C" {
#include "shared_mutex.h" // NOLINT
};
@@ -92,6 +94,7 @@ enum DevInfoTypes {
kDevMemUsedVRAM,
kDevPCIEReplayCount,
kDevUniqueId,
kDevDFCountersAvailable,
};
class Device {
@@ -118,6 +121,8 @@ class Device {
void set_bdfid(uint64_t val) {bdfid_ = val;}
uint64_t get_bdfid(void) const {return bdfid_;}
pthread_mutex_t *mutex(void) {return mutex_.ptr;}
evt::dev_evt_grp_set_t* supported_event_groups(void) {
return &supported_event_groups_;}
private:
std::shared_ptr<Monitor> monitor_;
@@ -134,6 +139,8 @@ class Device {
std::vector<std::string> *retVec);
int writeDevInfoStr(DevInfoTypes type, std::string valStr);
uint64_t bdfid_;
std::unordered_set<rsmi_event_group_t,
evt::RSMIEventGrpHashFunction> supported_event_groups_;
};
} // namespace smi
+1 -1
View File
@@ -55,7 +55,7 @@ namespace smi {
/// @brief Exception type which carries an error code to return to the user.
class rsmi_exception : public std::exception {
public:
rsmi_exception(rsmi_status_t error, const char* description) :
rsmi_exception(rsmi_status_t error, const std::string description) :
err_(error), desc_(description) {}
rsmi_status_t error_code() const noexcept { return err_; }
const char* what() const noexcept override { return desc_.c_str(); }