Skip to content

Commit

Permalink
feat(block I/O): Implement Block I/O tracing (#197)
Browse files Browse the repository at this point in the history
* feat(block I/O): Implement Block I/O tracing

- introduce --block-io and --block-cache-size options
- write insert, issue, and complete as a non-blocking event
- based on block:block_rq_insert block:block_rq_issue and
  block:block_rq_complete tracepoints

Co-authored-by: Mario Bielert <[email protected]>
  • Loading branch information
cvonelm and bmario authored Mar 15, 2022
1 parent 05e2278 commit ed1889f
Show file tree
Hide file tree
Showing 19 changed files with 976 additions and 12 deletions.
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

0 comments on commit ed1889f

Please sign in to comment.