Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(block I/O): Implement Block I/O tracing #197

Merged
merged 2 commits into from
Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ set(SOURCE_FILES
src/monitor/scope_monitor.cpp
src/monitor/threaded_monitor.cpp
src/monitor/tracepoint_monitor.cpp
src/monitor/bio_monitor.cpp
src/process_controller.cpp

src/perf/event_provider.cpp
Expand All @@ -148,6 +149,7 @@ set(SOURCE_FILES
src/perf/time/converter.cpp src/perf/time/reader.cpp
src/perf/tracepoint/format.cpp
src/perf/tracepoint/writer.cpp
src/perf/bio/event_cacher.cpp

src/time/time.cpp

Expand Down
3 changes: 3 additions & 0 deletions include/lo2s/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ struct Config
clockid_t clockid;
// x86_energy
bool use_x86_energy;
// block I/O
bool use_block_io;
size_t block_io_cache_size;
};

const Config& config();
Expand Down
8 changes: 8 additions & 0 deletions include/lo2s/measurement_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum class MeasurementScopeType
GROUP_METRIC,
USERSPACE_METRIC,
SWITCH,
BIO,
UNKNOWN
};

Expand Down Expand Up @@ -66,6 +67,11 @@ struct MeasurementScope
return { MeasurementScopeType::SWITCH, s };
}

static MeasurementScope bio(ExecutionScope s)
{
return { MeasurementScopeType::BIO, s };
}

friend bool operator==(const MeasurementScope& lhs, const MeasurementScope& rhs)
{
return (lhs.scope == rhs.scope) && lhs.type == rhs.type;
Expand Down Expand Up @@ -94,6 +100,8 @@ struct MeasurementScope
return fmt::format("samples for {}", scope.name());
case MeasurementScopeType::SWITCH:
return fmt::format("context switches for {}", scope.name());
case MeasurementScopeType::BIO:
return fmt::format("block layer I/O events for {}", scope.name());
default:
throw new std::runtime_error("Unknown ExecutionScopeType!");
}
Expand Down
61 changes: 61 additions & 0 deletions include/lo2s/monitor/bio_monitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* This file is part of the lo2s software.
* Linux OTF2 sampling
*
* Copyright (c) 2017,
* Technische Universitaet Dresden, Germany
*
* lo2s is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lo2s is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lo2s. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <lo2s/perf/bio/event_cacher.hpp>
#include <lo2s/perf/bio/writer.hpp>

#include <lo2s/monitor/poll_monitor.hpp>
#include <lo2s/trace/trace.hpp>

#include <map>
#include <memory>

namespace lo2s
{
namespace monitor
{

class BioMonitor : public PollMonitor
{
public:
BioMonitor(trace::Trace& trace, Cpu cpu,
std::map<dev_t, std::unique_ptr<perf::bio::Writer>>& writers_);

private:
void monitor(int fd) override;
void initialize_thread() override;
void finalize_thread() override;

std::string group() const override
{
return "lo2s::BioMonitor";
}

private:
Cpu cpu_;
perf::bio::EventCacher bio_insert_cacher_;
perf::bio::EventCacher bio_issue_cacher_;
perf::bio::EventCacher bio_complete_cacher_;
};
} // namespace monitor
} // namespace lo2s
5 changes: 4 additions & 1 deletion include/lo2s/monitor/main_monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <lo2s/metric/x86_energy/metrics.hpp>
#endif
#include <lo2s/mmap.hpp>
#include <lo2s/monitor/bio_monitor.hpp>
#include <lo2s/monitor/tracepoint_monitor.hpp>
#include <lo2s/process_info.hpp>
#include <lo2s/trace/trace.hpp>
Expand Down Expand Up @@ -63,10 +64,12 @@ class MainMonitor

protected:
trace::Trace trace_;

std::map<Process, ProcessInfo> process_infos_;
metric::plugin::Metrics metrics_;
std::vector<std::unique_ptr<TracepointMonitor>> tracepoint_monitors_;

std::map<dev_t, std::unique_ptr<perf::bio::Writer>> writers_;
std::vector<std::unique_ptr<BioMonitor>> bio_monitors_;
#ifdef HAVE_X86_ADAPT
std::unique_ptr<metric::x86_adapt::Metrics> x86_adapt_metrics_;
#endif
Expand Down
66 changes: 66 additions & 0 deletions include/lo2s/perf/bio/block_device.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* This file is part of the lo2s software.
* Linux OTF2 sampling
*
* Copyright (c) 2022,
* Technische Universitaet Dresden, Germany
*
* lo2s is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lo2s is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lo2s. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <string>

extern "C"
{
#include <sys/types.h>
}

namespace lo2s
{

enum class BlockDeviceType
{
PARTITION,
DISK
};

struct BlockDevice
{
BlockDevice() : id(0), name(), type(BlockDeviceType::PARTITION), parent(0)
{
}

BlockDevice(dev_t id, const std::string& name, BlockDeviceType type, dev_t parent)
: id(id), name(name), type(type), parent(parent)
{
}

static BlockDevice partition(dev_t id, const std::string& name, dev_t parent)
{
return BlockDevice(id, name, BlockDeviceType::PARTITION, parent);
}

static BlockDevice disk(dev_t id, const std::string& name)
{
return BlockDevice(id, name, BlockDeviceType::DISK, 0);
}

dev_t id;
std::string name;
BlockDeviceType type;
dev_t parent;
};
} // namespace lo2s
91 changes: 91 additions & 0 deletions include/lo2s/perf/bio/event_cacher.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* This file is part of the lo2s software.
* Linux OTF2 sampling
*
* Copyright (c) 2017,
* Technische Universitaet Dresden, Germany
*
* lo2s is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lo2s is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lo2s. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <lo2s/perf/bio/reader.hpp>
#include <lo2s/perf/bio/writer.hpp>
#include <lo2s/perf/time/converter.hpp>

#include <lo2s/trace/trace.hpp>

#include <otf2xx/definition/metric_instance.hpp>
#include <otf2xx/event/metric.hpp>
#include <otf2xx/writer/local.hpp>

#include <unordered_map>
#include <vector>

namespace lo2s
{
namespace perf
{
namespace bio
{
// Note, this cannot be protected for CRTP reasons...

class EventCacher : public Reader<EventCacher>
{
public:
struct __attribute((__packed__)) RecordBlock
{
uint16_t common_type; // 2
uint8_t common_flag; // 3
uint8_t common_preempt_count; // 4
int32_t common_pid; // 8

uint32_t dev; // 12
char padding[4]; // 16
uint64_t sector; // 24

uint32_t nr_sector; // 28
int32_t error_or_bytes; // 32

char rwbs[8]; // 40
};

EventCacher(Cpu cpu, std::map<dev_t, std::unique_ptr<Writer>>& writers, BioEventType type);

EventCacher(const EventCacher& other) = delete;

EventCacher(EventCacher&& other) = default;

public:
using Reader<EventCacher>::handle;

bool handle(const Reader::RecordSampleType* sample);

void finalize()
{
for (auto& events : events_)
{
writers_[events.first]->submit_events(events.second);
}
}

private:
std::map<dev_t, std::unique_ptr<Writer>>& writers_;
std::unordered_map<dev_t, std::vector<BioEvent>> events_;
};

} // namespace bio
} // namespace perf
} // namespace lo2s
Loading