Skip to content

Commit

Permalink
Added interface in Net.cc to configure NIC from application (Config),…
Browse files Browse the repository at this point in the history
… starting to add perf and other counters such as RAPL for counting power usage.
  • Loading branch information
handong32 committed Dec 18, 2019
1 parent 5b98f29 commit e138668
Show file tree
Hide file tree
Showing 10 changed files with 538 additions and 222 deletions.
532 changes: 337 additions & 195 deletions src/native/IxgbeDriver.cc

Large diffs are not rendered by default.

61 changes: 41 additions & 20 deletions src/native/IxgbeDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "Pfn.h"
#include "SlabAllocator.h"
#include "Perf.h"
#include "Rapl.h"

// Receive Side Scaling (RSC) enabled
//#define RSC_EN
Expand All @@ -28,11 +29,12 @@
//#define TX_HEAD_WB

// Collect Statistics Flag
//#define STATS_EN
#define STATS_EN
//#define MAX_DESC

namespace ebbrt {

namespace ebbrt {

// Per-core receive and transmit queue
typedef struct {
rdesc_legacy_t* rx_ring;
Expand Down Expand Up @@ -67,7 +69,7 @@ class IxgbeDriver : public EthernetDevice {
// each core gets a queue struct
ixgmq.resize(Cpu::Count());
}

static void Create(pci::Device& dev);
static bool Probe(pci::Device& dev) {
if (dev.GetVendorId() == kIxgbeVendorId &&
Expand All @@ -77,12 +79,14 @@ class IxgbeDriver : public EthernetDevice {
}
return false;
}

void Run();
//void Run();
void Send(std::unique_ptr<IOBuf> buf, PacketInfo pinfo) override;
void Config(std::string s, uint32_t v) override;
const EthernetAddress& GetMacAddress() override;

protected:

static const constexpr uint16_t kIxgbeVendorId = 0x8086;
static const constexpr uint16_t kIxgbeDeviceId = 0x10FB;

Expand All @@ -101,10 +105,8 @@ class IxgbeDriver : public EthernetDevice {
static const constexpr uint32_t NTXDESCS = 8192;
static const constexpr uint32_t NRXDESCS = 8192;
#else
//static const constexpr uint32_t NTXDESCS = 512;
//static const constexpr uint32_t NRXDESCS = 512;
static const constexpr uint32_t NTXDESCS = 128;
static const constexpr uint32_t NRXDESCS = 128;
static const constexpr uint32_t NTXDESCS = 64;
static const constexpr uint32_t NRXDESCS = 64;
#endif

// Linux Defaults
Expand All @@ -114,7 +116,7 @@ class IxgbeDriver : public EthernetDevice {
//static const constexpr uint32_t RXBUFSZ = 4096;
//static const constexpr uint32_t RXBUFSZ = 16384;

static const constexpr uint8_t ITR_INTERVAL = 6;
static const constexpr uint8_t ITR_INTERVAL = 200;
// 3 bits only (0 - 7) in (RSC_DELAY + 1) * 4 us
static const constexpr uint8_t RSC_DELAY = 1;

Expand Down Expand Up @@ -142,6 +144,11 @@ class IxgbeDriver : public EthernetDevice {
// TODO: should be optimized
rsc_chain_.reserve(NRXDESCS+1);

// keeps a log of descriptors where eop == 1
// used to coalesce reclaiming of tx descriptors
// once the threshold of some limit is hit
send_to_watch.reserve(NRXDESCS);

// RX ring buffer allocation
auto sz = align::Up(sizeof(rdesc_legacy_t) * NRXDESCS, 4096);
auto order = Fls(sz - 1) - pmem::kPageShift + 1;
Expand Down Expand Up @@ -198,7 +205,7 @@ class IxgbeDriver : public EthernetDevice {
ebbrt::kbugon((tx_size_bytes_ & 0x7F) != 0,
"tx_size_bytes_ not 128 byte aligned\n");
}

size_t rx_head_;
size_t rx_tail_;
size_t rx_size_;
Expand All @@ -215,7 +222,8 @@ class IxgbeDriver : public EthernetDevice {

std::vector<std::unique_ptr<MutIOBuf>> circ_buffer_;
std::vector<std::pair<uint32_t, uint32_t>> rsc_chain_;

std::vector<uint32_t> send_to_watch;

rdesc_legacy_t* rx_ring_;
tdesc_legacy_t* tx_ring_;
bool* tx_isctx_;
Expand All @@ -228,18 +236,28 @@ class IxgbeDriver : public EthernetDevice {
#endif

// stats
uint64_t stat_num_itr{0};
uint64_t stat_num_recv{0};
uint64_t stat_num_send{0};
uint64_t stat_num_rx{0};
uint64_t stat_num_tx{0};

bool stat_perf{false};
uint64_t stat_num_rx_bytes{0};
uint64_t stat_num_tx_bytes{0};
uint64_t time_us{0};
uint64_t ttotalt{0};
uint64_t totalCycles{0};
uint64_t totalIns{0};
uint64_t totalLLCmisses{0};
double totalNrg{0.0};
double totalTime{0.0};

bool stat_start{false};
bool stat_init{false};
ebbrt::perf::PerfCounter perfCycles;
ebbrt::perf::PerfCounter perfInst;
ebbrt::perf::PerfCounter perfLLC_ref;
ebbrt::perf::PerfCounter perfLLC_miss;
ebbrt::perf::PerfCounter perfTLB_store_miss;
ebbrt::perf::PerfCounter perfTLB_load_miss;
ebbrt::rapl::RaplCounter powerMeter;

};

private:
Expand Down Expand Up @@ -483,7 +501,7 @@ class IxgbeDriver : public EthernetDevice {
friend class IxgbeDriverRep;
}; // class IxgbeDriver

class IxgbeDriverRep : public MulticoreEbb<IxgbeDriverRep, IxgbeDriver> {
class IxgbeDriverRep : public MulticoreEbb<IxgbeDriverRep, IxgbeDriver>, Timer::Hook {
public:
explicit IxgbeDriverRep(const IxgbeDriver& root);
void Run();
Expand All @@ -495,7 +513,9 @@ class IxgbeDriverRep : public MulticoreEbb<IxgbeDriverRep, IxgbeDriver> {
enum l4_type l4type);
void AddTx(uint64_t pa, uint64_t len, uint64_t totallen, bool first,
bool last, uint8_t ctx, bool ip_cksum, bool tcpudp_cksum, bool tse, int hdr_len);

void StartTimer();
void StopTimer();

private:
uint16_t ReadRdh_1(uint32_t n);
uint16_t ReadRdt_1(uint32_t n);
Expand All @@ -509,7 +529,8 @@ class IxgbeDriverRep : public MulticoreEbb<IxgbeDriverRep, IxgbeDriver> {
uint32_t ReadTdt_1(uint32_t n);
uint32_t GetRxBuf(uint32_t* len, uint64_t* bAddr, uint64_t* rxflag,
bool* process_rsc, uint32_t* rnt, uint32_t* rxhead);

void Fire() override;

const IxgbeDriver& root_;
e10k_queue_t& ixgq_;
IxgbeDriver::e10Kq& ixgmq_;
Expand Down
2 changes: 1 addition & 1 deletion src/native/Msr.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ inline uint64_t Read(uint32_t index) {

inline void Write(uint32_t index, uint64_t data) {
uint32_t low = data;
uint32_t high = data >> 32;
uint32_t high = (data >> 32) & 0xFFFFFFFF;

#ifdef __EBBRT_ENABLE_BAREMETAL_NIC__
// TODO - correct fix is here?
Expand Down
8 changes: 8 additions & 0 deletions src/native/Net.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,11 @@ void ebbrt::NetworkManager::Interface::Send(std::unique_ptr<IOBuf> b,
PacketInfo pinfo) {
ether_dev_.Send(std::move(b), std::move(pinfo));
}

void ebbrt::NetworkManager::Config(std::string s, uint32_t v) {
interface_->Config(std::move(s), v);
}

void ebbrt::NetworkManager::Interface::Config(std::string s, uint32_t v) {
ether_dev_.Config(std::move(s), v);
}
10 changes: 7 additions & 3 deletions src/native/Net.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class EthernetDevice {
public:
virtual void Send(std::unique_ptr<IOBuf> buf,
PacketInfo pinfo = PacketInfo()) = 0;
virtual void Config(std::string s, uint32_t v) = 0;
virtual const EthernetAddress& GetMacAddress() = 0;
virtual ~EthernetDevice() {}
};
Expand Down Expand Up @@ -246,6 +247,8 @@ class NetworkManager : public StaticSharedEbb<NetworkManager> {
std::unique_ptr<IOBuf> buf);
void SendIp(std::unique_ptr<MutIOBuf> buf, Ipv4Address src, Ipv4Address dst,
uint8_t proto, PacketInfo pinfo = PacketInfo());
void Config(std::string s, uint32_t v);

const EthernetAddress& MacAddress();
const ItfAddress* Address() const { return address_.get(); }
void SetAddress(std::unique_ptr<ItfAddress> address) {
Expand All @@ -256,7 +259,7 @@ class NetworkManager : public StaticSharedEbb<NetworkManager> {
private:
struct DhcpPcb : public CacheAligned, public Timer::Hook {
void Fire() override;

UdpPcb udp_pcb;
DhcpMessage last_offer;
enum State { kInactive, kSelecting, kRequesting, kBound } state;
Expand Down Expand Up @@ -311,9 +314,10 @@ class NetworkManager : public StaticSharedEbb<NetworkManager> {

Interface& NewInterface(EthernetDevice& ether_dev);
Ipv4Address IpAddress();

void Config(std::string s, uint32_t v);

private:
Future<void> StartDhcp();
Future<void> StartDhcp();
void SendIp(std::unique_ptr<MutIOBuf> buf, Ipv4Address src, Ipv4Address dst,
uint8_t proto, PacketInfo = PacketInfo());
void TcpReset(bool ack, uint32_t seqno, uint32_t ackno,
Expand Down
6 changes: 3 additions & 3 deletions src/native/NetIcmp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ void ebbrt::NetworkManager::Interface::ReceiveIcmp(
EthernetHeader& eth_header, Ipv4Header& ip_header,
std::unique_ptr<MutIOBuf> buf) {
auto packet_len = buf->ComputeChainDataLength();
ebbrt::kprintf("ReceiveIcmp() packet_len=%u\n", packet_len);
//ebbrt::kprintf("ReceiveIcmp() packet_len=%u\n", packet_len);

if (unlikely(packet_len < sizeof(IcmpHeader)))
return;

auto dp = buf->GetMutDataPointer();
auto& icmp_header = dp.Get<IcmpHeader>();

ebbrt::kprintf("ReceiveIcmp() packet_len=%u\n", packet_len);
//ebbrt::kprintf("ReceiveIcmp() packet_len=%u\n", packet_len);
#ifndef __EBBRT_ENABLE_BAREMETAL_NIC__
// software checksum
if (IpCsum(*buf))
Expand Down Expand Up @@ -51,7 +51,7 @@ void ebbrt::NetworkManager::Interface::ReceiveIcmp(
PacketInfo pinfo;
pinfo.flags = 0;
// hijacking ping to dump ixgbe statistics
pinfo.get_stats = false;
pinfo.get_stats = true;
//#ifdef __EBBRT_ENABLE_BAREMETAL_NIC__
// hardware ip checksum offload
// pinfo.flags |= PacketInfo::kNeedsIpCsum;
Expand Down
11 changes: 11 additions & 0 deletions src/native/Rapl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "Debug.h"
//#include "Msr.h"
#include "Rapl.h"

ebbrt::rapl::RaplCounter::~RaplCounter() {
return;
}

double ebbrt::rapl::RaplCounter::Read() {
return counter_offset;
}
127 changes: 127 additions & 0 deletions src/native/Rapl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright Boston University SESA Group 2013 - 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BAREMETAL_SRC_INCLUDE_EBBRT_RAPL_H_
#define BAREMETAL_SRC_INCLUDE_EBBRT_RAPL_H_
#include <cstdint>
#include <cmath>

#include "Debug.h"
#include "Msr.h"
#include "Clock.h"

namespace ebbrt {
namespace rapl {
const constexpr uint32_t kMsrIntelRaplPowerUnit = 0x606;

/* Package RAPL Domain */
const constexpr uint32_t kMsrPkgRaplPowerLimit = 0x610;
const constexpr uint32_t kMsrIntelPkgEnergyStatus = 0x611;
const constexpr uint32_t kMsrPkgPerfStatus = 0x613;
const constexpr uint32_t kMsrPkgPowerInfo = 0x614;

/* PP0 RAPL Domain */
const constexpr uint32_t kMsrPp0PowerLimit = 0x638;
const constexpr uint32_t kMsrIntelPp0EnergyStatus = 0x639;
const constexpr uint32_t kMsrPp0Policy = 0x63A;
const constexpr uint32_t kMsrPp0PerfStatus = 0x63B;

/* PP1 RAPL Domain, may reflect to uncore devices */
const constexpr uint32_t kMsrPp1PowerLimit = 0x640;
const constexpr uint32_t kMsrPp1EnergyStatus = 0x641;
const constexpr uint32_t kMsrPp1Polcy = 0x642;

/* DRAM RAPL Domain */
const constexpr uint32_t kMsrDramPowerLimit = 0x618;
const constexpr uint32_t kMsrDramEnergyStatus = 0x619;
const constexpr uint32_t kMsrDramPerfStatus = 0x61B;
const constexpr uint32_t kMsrDramPowerInfo = 0x61C;

/* PSYS RAPL Domain */
const constexpr uint32_t kMsrPlatformEnergyStatus = 0x64d;

/* RAPL UNIT BITMASK */
const constexpr uint32_t POWER_UNIT_OFFSET = 0;
const constexpr uint32_t POWER_UNIT_MASK = 0x0F;

const constexpr uint32_t ENERGY_UNIT_OFFSET = 0x08;
const constexpr uint32_t ENERGY_UNIT_MASK = 0x1F00;

const constexpr uint32_t TIME_UNIT_OFFSET = 0x10;
const constexpr uint32_t TIME_UNIT_MASK = 0xF000;

class RaplCounter { //: public Timer::Hook {
public:
RaplCounter() {
uint64_t res = ebbrt::msr::Read(kMsrIntelRaplPowerUnit);
rapl_power_units = pow(0.5,(double)(res&0xf));
rapl_cpu_energy_units = pow(0.5,(double)((res>>8)&0x1f));
rapl_time_units = pow(0.5,(double)((res>>16)&0xf));
rapl_dram_energy_units = rapl_cpu_energy_units;
};
// move constructors
RaplCounter(RaplCounter&& other) {
rapl_power_units = other.rapl_power_units;
rapl_cpu_energy_units = other.rapl_cpu_energy_units;
rapl_time_units = other.rapl_time_units;
rapl_dram_energy_units = other.rapl_dram_energy_units;

other.rapl_power_units = 0.0;
other.rapl_cpu_energy_units = 0.0;
other.rapl_time_units = 0.0;
other.rapl_dram_energy_units = 0.0;
};
RaplCounter& operator=(RaplCounter&& other) {
rapl_power_units = other.rapl_power_units;
rapl_cpu_energy_units = other.rapl_cpu_energy_units;
rapl_time_units = other.rapl_time_units;
rapl_dram_energy_units = other.rapl_dram_energy_units;

other.rapl_power_units = 0.0;
other.rapl_cpu_energy_units = 0.0;
other.rapl_time_units = 0.0;
other.rapl_dram_energy_units = 0.0;

return *this;
};

// delete implicitly created copy constructor
RaplCounter(const RaplCounter& other) = delete;
RaplCounter& operator=(const RaplCounter& other) = delete;

~RaplCounter();
void Start() {
uint64_t res = ebbrt::msr::Read(kMsrIntelPkgEnergyStatus);
counter_offset = (double)res*rapl_cpu_energy_units;

/*ebbrt::kprintf("\t\tPower units = %.3fW\n",rapl_power_units);
ebbrt::kprintf("\t\tCPU Energy units = %.8fJ\n",rapl_cpu_energy_units);
ebbrt::kprintf("\t\tDRAM Energy units = %.8fJ\n",rapl_dram_energy_units);
ebbrt::kprintf("\t\tTime units = %.8fs\n",rapl_time_units); */
//ebbrt::kprintf("Package Energy before: %.6fJ\n", counter_offset);
}

void Stop() {
uint64_t res = ebbrt::msr::Read(kMsrIntelPkgEnergyStatus);
double after = (double)res*rapl_cpu_energy_units;
//ebbrt::kprintf("Package Energy after: %.6fJ\n", after);
counter_offset = after - counter_offset;
//ebbrt::kprintf("Total Package Energy used: %.6fJ\n", after - counter_offset);
}

double Read();
private:
double rapl_power_units{0.0};
double rapl_cpu_energy_units{0.0};
double rapl_time_units{0.0};
double rapl_dram_energy_units{0.0};
double counter_offset{0.0};
//void Fire() override;
};

} // namespace rapl
} // namespace ebbrt

#endif
Loading

0 comments on commit e138668

Please sign in to comment.