Skip to content

Commit

Permalink
Fix NEC sampling if threads are involved
Browse files Browse the repository at this point in the history
ve_check_pid() only works for processes, not threads, so lo2s complained
that it could not find the real NEC device id for those threads.

Rewrite the code to use ve_sysfs_path_info(). This gives us the correct
sysfs path for a NEC device id, so we dont have to find it using
ve_check_pid().
  • Loading branch information
cvonelm committed Oct 22, 2024
1 parent 801fe92 commit c129f5e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 35 deletions.
33 changes: 21 additions & 12 deletions include/lo2s/topology.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,17 @@

#include <filesystem>

#include <lo2s/error.hpp>
#include <lo2s/log.hpp>
#include <lo2s/types.hpp>

#ifdef HAVE_VEOSINFO
extern "C"
{
#include <veosinfo/veosinfo.h>
}
#endif

using namespace std::literals::string_literals;

namespace lo2s
Expand Down Expand Up @@ -71,25 +80,25 @@ class Topology
return cpus_;
}

#ifdef HAVE_VEOSINFO
const std::set<NecDevice> nec_devices() const
{
std::set<NecDevice> devices;

const std::regex nec_regex("/sys/class/ve/ve(\\d)");

for (auto& dir_entry : std::filesystem::directory_iterator("/sys/class/ve"))
ve_nodeinfo nodeinfo;
auto ret = ve_node_info(&nodeinfo);
if (ret == -1)
{
std::smatch nec_match;

auto path = dir_entry.path().string();
if (std::regex_match(path, nec_match, nec_regex))
{
devices.emplace(NecDevice(std::stoi(nec_match[1])));
}
Log::error() << "Failed to get Vector Engine node information!";
throw_errno();
}

std::set<NecDevice> devices;
for (int i = 0; i < nodeinfo.total_node_count; i++)
{
devices.emplace(NecDevice(i));
}
return devices;
}
#endif

Core core_of(Cpu cpu) const
{
Expand Down
41 changes: 18 additions & 23 deletions src/monitor/nec_monitor_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,35 @@
* along with lo2s. If not, see <http://www.gnu.org/licenses/>.
*/

#include <filesystem>

#include <lo2s/log.hpp>
#include <lo2s/monitor/nec_monitor_main.hpp>

extern "C"
{
extern int ve_sysfs_path_info(int nodeid, char* ve_sysfs_path);
}

namespace lo2s
{
namespace nec
{

std::optional<NecDevice> NecMonitorMain::get_device_of(Thread thread)
std::vector<Thread> NecMonitorMain::get_tasks_of(NecDevice device)
{
// /sys/class/ve/ve0 is not device 0, because that would make too much sense
// So look the device id up here
char sysfs_path_str[PATH_MAX];
memset(sysfs_path_str, 0, PATH_MAX);

for (int i = 0; i < nodeinfo_.total_node_count; i++)
auto ret = ve_sysfs_path_info(device.as_int(), sysfs_path_str);
if (ret == -1)
{
if (!ve_check_pid(nodeinfo_.nodeid[i], thread.as_pid_t()))
{
return NecDevice(nodeinfo_.nodeid[i]);
}
throw_errno();
}
return std::optional<NecDevice>();
}

std::vector<Thread> NecMonitorMain::get_tasks_of(NecDevice device)
{
std::ifstream task_stream(fmt::format("/sys/class/ve/ve{}/task_id_all", device.as_int()));
std::filesystem::path sysfs_path(sysfs_path_str);
sysfs_path /= "task_id_all";
std::ifstream task_stream(sysfs_path);

std::vector<Thread> threads;

Expand Down Expand Up @@ -97,17 +101,8 @@ void NecMonitorMain::run()
continue;
}

auto real_device_id = get_device_of(thread);

if (!real_device_id)
{
Log::warn() << "Could not find real vector accelerator id for "
<< thread.as_pid_t();
continue;
}

auto ret = monitors_.emplace(std::piecewise_construct, std::forward_as_tuple(thread),
std::forward_as_tuple(thread, trace_, *real_device_id));
std::forward_as_tuple(thread, trace_, device_));
if (ret.second)
{
ret.first->second.start();
Expand Down

0 comments on commit c129f5e

Please sign in to comment.