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

Mock Enso Pipe #4

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
5b7b1ca
removed func bodies in mock_pcie
Feb 18, 2023
3389722
phys to virt
Feb 18, 2023
5a3f267
added packet processing
Feb 19, 2023
f1bd43c
Fix new API performance (runs at 99.9Gbps)
hsadok Feb 22, 2023
a7c72de
Adding docs
hsadok Feb 26, 2023
7b659d5
added in consuming queue
Mar 10, 2023
bfda35c
added limit on num packets read
Mar 10, 2023
5815774
compiling
Mar 10, 2023
ee5d0c6
Adding libpcap as a dependency
hsadok Mar 10, 2023
be7f2aa
Fix get_unreported_completions and format
hsadok Mar 10, 2023
7c26a4d
Fix pcie.cpp
hsadok Mar 10, 2023
3b569a0
going to start rss
Apr 16, 2023
06df71d
added hash function
Apr 16, 2023
a82be0e
added RSS hashing
Apr 23, 2023
4df268f
added init flag
Apr 23, 2023
39f80c0
changes
May 12, 2023
024ea59
debugging
May 13, 2023
7e55f69
merged with master
May 13, 2023
b1436ea
reverted
kaajalbgupta May 13, 2023
b42979c
Delete settings.json
kaajalbgupta May 13, 2023
8f6b352
Delete Doxyfile.in
kaajalbgupta May 13, 2023
b384a4e
added hashmap of configs
kaajalbgupta May 13, 2023
80801ee
debugging
kaajalbgupta May 13, 2023
683ae48
Merge branch 'master' into rss
kaajalbgupta May 14, 2023
3c4609b
Delete enso_pipe.md
kaajalbgupta May 14, 2023
a9fad40
fixed initialization
kaajalbgupta May 14, 2023
95cca66
fixed malloc
kaajalbgupta May 14, 2023
c7c3e45
changed struct names
kaajalbgupta May 14, 2023
4f63c78
changed struct names
kaajalbgupta May 14, 2023
9d3911f
fixed config
kaajalbgupta May 14, 2023
d1c433c
Delete settings.json
kaajalbgupta May 15, 2023
ab567ef
removed comment
kaajalbgupta May 15, 2023
c38b99b
Add "mock" compile-time option
hsadok May 15, 2023
cebca96
Only require libpcap in mock mode
hsadok May 15, 2023
d68a1cb
debugged mock
kaajalbgupta May 15, 2023
46b1f9b
fixed include loop
kaajalbgupta May 15, 2023
575599e
Delete settings.json
kaajalbgupta May 15, 2023
0500260
working for yucca
kaajalbgupta May 16, 2023
67cc27b
debugged rxpipe
kaajalbgupta May 16, 2023
90d2525
echo working
kaajalbgupta May 16, 2023
98b034b
echo_copy working
kaajalbgupta May 17, 2023
09f27f1
Delete settings.json
kaajalbgupta May 17, 2023
5d0dd27
cleanup
kaajalbgupta May 18, 2023
203f933
echo_event
kaajalbgupta May 18, 2023
6cf2f76
changed consume queue
kaajalbgupta May 23, 2023
772a392
working
kaajalbgupta May 24, 2023
4d613f5
added input packet rate
kaajalbgupta May 26, 2023
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
Binary file added .DS_Store
Binary file not shown.
76 changes: 76 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"files.associations": {
"vector": "cpp",
"chrono": "cpp",
"__bit_reference": "cpp",
"__bits": "cpp",
"__config": "cpp",
"__debug": "cpp",
"__errc": "cpp",
"__hash_table": "cpp",
"__locale": "cpp",
"__mutex_base": "cpp",
"__node_handle": "cpp",
"__nullptr": "cpp",
"__split_buffer": "cpp",
"__string": "cpp",
"__threading_support": "cpp",
"__tuple": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"exception": "cpp",
"fstream": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"ios": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"locale": "cpp",
"memory": "cpp",
"mutex": "cpp",
"new": "cpp",
"numeric": "cpp",
"optional": "cpp",
"ostream": "cpp",
"queue": "cpp",
"random": "cpp",
"ratio": "cpp",
"sstream": "cpp",
"stack": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp",
"unordered_map": "cpp",
"variant": "cpp",
"algorithm": "cpp"
}
}
5 changes: 5 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ add_global_arguments('-march=native', language: ['c', 'cpp'])
notification_buf_size = get_option('notification_buf_size')
enso_pipe_size = get_option('enso_pipe_size')
latency_opt = get_option('latency_opt')
mock = get_option('mock')

add_global_arguments(f'-D NOTIFICATION_BUF_SIZE=@notification_buf_size@',
language: ['c', 'cpp'])
Expand All @@ -29,6 +30,10 @@ if latency_opt
add_global_arguments('-D LATENCY_OPT', language: ['c', 'cpp'])
endif

if mock
add_global_arguments(f'-D MOCK', language: ['c', 'cpp'])
endif

subdir('software')
subdir('docs')
subdir('hardware')
2 changes: 2 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ option('enso_pipe_size', type: 'integer', min: 0, max: 32768, value: 32768,
description: 'Buffer size used by each software enso pipe')
option('latency_opt', type: 'boolean', value: false,
description: 'Optimize for latency')
option('mock', type: 'boolean', value: false,
description: 'Build in mock mode. Does not require the hardware.')
1 change: 1 addition & 0 deletions software/examples/capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*/

#include <enso/helpers.h>
#include <enso/internals.h>
#include <enso/pipe.h>
#include <pcap/pcap.h>

Expand Down
3 changes: 3 additions & 0 deletions software/examples/echo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <chrono>
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <memory>
#include <thread>
Expand Down Expand Up @@ -86,6 +87,7 @@ void run_echo(uint32_t nb_queues, uint32_t core_id,
continue;
}

int num_pkts = 0;
for (auto pkt : batch) {
++pkt[63]; // Increment payload.

Expand All @@ -94,6 +96,7 @@ void run_echo(uint32_t nb_queues, uint32_t core_id,
}

++(stats->nb_pkts);
num_pkts += 1;
}
uint32_t batch_length = batch.processed_bytes();
pipe->ConfirmBytes(batch_length);
Expand Down
8 changes: 5 additions & 3 deletions software/examples/l2_forward.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ static volatile bool setup_done = false;

// Adapted from DPDK's rte_mov64() and rte_memcpy() functions.
static _enso_always_inline void mov64(uint8_t* dst, const uint8_t* src) {
__m512i zmm0;
zmm0 = _mm512_loadu_si512((const void*)src);
_mm512_storeu_si512((void*)dst, zmm0);
// __m512i zmm0;
// zmm0 = _mm512_loadu_si512((const void*)src);
// _mm512_storeu_si512((void*)dst, zmm0);
(void)dst;
(void)src;
}

static _enso_always_inline void memcpy_64_align(void* dst, const void* src,
Expand Down
24 changes: 24 additions & 0 deletions software/include/enso/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
#include <iostream>
#include <string>
#include <thread>
#include <tuple>
#include <unordered_map>
#include <vector>

namespace enso {
Expand All @@ -79,6 +81,26 @@ struct stats_t {
uint64_t nb_pkts;
} __attribute__((aligned(64)));

#ifdef MOCK
// RSS 5-tuple containing dst port, src port, dst ip, src ip, protocol
typedef std::tuple<uint16_t, uint16_t, uint32_t, uint32_t, uint32_t>
ConfigTuple;

// A hash function used to hash the config tuple
struct HashConfigTuple {
template <class T1, class T2, class T3, class T4, class T5>

size_t operator()(const std::tuple<T1, T2, T3, T4, T5>& x) const {
return std::get<0>(x) ^ std::get<1>(x) ^ std::get<2>(x) ^ std::get<3>(x) ^
std::get<4>(x);
}
};

// Hash map containing bindings of configurations to enso pipe IDs
extern std::unordered_map<ConfigTuple, int, HashConfigTuple> config_hashmap;

#endif

/**
* @brief Returns RTT, in number of cycles, for a given packet.
*
Expand Down Expand Up @@ -124,6 +146,8 @@ void print_pkt_header(uint8_t* pkt);

void print_buf(void* buf, const uint32_t nb_cache_lines);

int rss_hash_packet(uint8_t* pkt_buf, int mod);

int set_core_id(std::thread& thread, int core_id);

void show_stats(const std::vector<stats_t>& thread_stats,
Expand Down
20 changes: 19 additions & 1 deletion software/include/enso/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct __attribute__((__packed__)) RxNotification {
};

struct __attribute__((__packed__)) TxNotification {
uint64_t signal;
uint64_t signal; // whether or not notification has been consumed by hardware
uint64_t phys_addr;
uint64_t length; // In bytes (up to 1MB).
uint64_t pad[5];
Expand Down Expand Up @@ -114,17 +114,35 @@ struct NotificationBufPair {
void* uio_mmap_bar2_addr; // UIO mmap address for BAR 2.
};

#ifdef MOCK

struct RxEnsoPipeInternal {
uint32_t* buf;
uint64_t buf_phys_addr;
struct QueueRegs* regs;
uint32_t* buf_head_ptr;
uint32_t rx_head;
uint32_t rx_tail;
uint32_t rx_actual_tail;
uint64_t phys_buf_offset; // Use to convert between phys and virt address.
enso_pipe_id_t id;
};

#else

struct RxEnsoPipeInternal {
uint32_t* buf;
uint64_t buf_phys_addr;
struct QueueRegs* regs;
uint32_t* buf_head_ptr;
uint32_t rx_head;
uint32_t rx_tail;
uint64_t phys_buf_offset; // Use to convert between phys and virt address.
enso_pipe_id_t id;
};

#endif

} // namespace enso

#endif // SOFTWARE_INCLUDE_ENSO_INTERNALS_H_
12 changes: 10 additions & 2 deletions software/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ inc = include_directories('include')
subdir('include')
subdir('src')

enso_lib = library('enso', project_sources, install: true,
include_directories: inc)
if mock
pcap_dep = dependency('pcap', version : '>=1.0')
enso_lib = library('enso', project_sources, install: true,
include_directories: inc, dependencies: pcap_dep)

else
enso_lib = library('enso', project_sources, install: true,
include_directories: inc)
endif

pkg_mod = import('pkgconfig')
pkg_mod.generate(enso_lib)

Expand Down
41 changes: 41 additions & 0 deletions software/src/enso/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@
#include <enso/internals.h>
#include <immintrin.h>

#include <cassert>
#include <cstdio>
#include <tuple>
#include <vector>

#include "../mock_pcie.h"
#include "../pcie.h"

namespace enso {
Expand Down Expand Up @@ -86,12 +90,48 @@ struct __attribute__((__packed__)) RateLimitConfig {
/**
* Sends configuration through a notification buffer.
*
* NOTE: if mock enso pipe, then add config notification to global hash table
* of queue configurations.
*
* @param notification_buf_pair The notification buffer pair to send the
* configuration through.
* @param config_notification The configuration notification to send. Must be
* a config notification, i.e., signal >= 2.
* @return 0 on success, -1 on failure.
*/
#ifdef MOCK

int send_config(struct NotificationBufPair* notification_buf_pair,
struct TxNotification* config_notification) {
(void)notification_buf_pair;
FlowTableConfig* config = (FlowTableConfig*)config_notification;
// reject anything that is not binding a configuration to a pipe
assert(config->config_id == FLOW_TABLE_CONFIG_ID);

// Make sure it's a config notification.
if (config->signal < 2) {
return -1;
}

// Check if the enso pipe ID is within the hashmap of enso pipes
if (enso_pipes_map.find(config->enso_pipe_id) == enso_pipes_map.end())
return -2;

// Adding to hash map
uint16_t dst_port = config->dst_port;
uint16_t src_port = config->src_port;
uint32_t dst_ip = config->dst_ip;
uint32_t src_ip = config->src_ip;
uint32_t protocol = config->protocol;
ConfigTuple tup =
std::make_tuple(dst_port, src_port, dst_ip, src_ip, protocol);

config_hashmap[tup] = config->enso_pipe_id;

return 0;
}

#else
int send_config(struct NotificationBufPair* notification_buf_pair,
struct TxNotification* config_notification) {
struct TxNotification* tx_buf = notification_buf_pair->tx_buf;
Expand Down Expand Up @@ -134,6 +174,7 @@ int send_config(struct NotificationBufPair* notification_buf_pair,

return 0;
}
#endif

int insert_flow_entry(struct NotificationBufPair* notification_buf_pair,
uint16_t dst_port, uint16_t src_port, uint32_t dst_ip,
Expand Down
50 changes: 50 additions & 0 deletions software/src/enso/helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,13 @@
#include <iostream>
#include <thread>
#include <vector>

namespace enso {

#ifdef MOCK
std::unordered_map<ConfigTuple, int, HashConfigTuple> config_hashmap;
#endif

uint16_t get_bdf_from_pcie_addr(const std::string& pcie_addr) {
uint32_t domain, bus, dev, func;
uint16_t bdf = 0;
Expand Down Expand Up @@ -132,6 +137,51 @@ void print_pkt_header(uint8_t* pkt) {
}
}

#ifdef MOCK
/**
* @brief Hashes a packet with RSS to determine which pipe it should be
* directed to.
*
* @param pkt_buf packet buffer.
* @param mod number of pipes
* @return Index of pipe
*/
int rss_hash_packet(uint8_t* pkt_buf, int mod) {
struct ether_header* l2_hdr = (struct ether_header*)pkt_buf;
struct iphdr* l3_hdr = (struct iphdr*)(l2_hdr + 1);
uint32_t src_ip = l3_hdr->saddr;
uint32_t dst_ip = l3_hdr->daddr;
uint8_t protocol = l3_hdr->protocol;
uint32_t src_port;
uint32_t dst_port;
switch (protocol) {
case IPPROTO_TCP: {
struct tcphdr* l4_hdr = (struct tcphdr*)(l3_hdr + 1);
src_port = l4_hdr->source;
dst_port = l4_hdr->dest;
break;
}
case IPPROTO_UDP: {
struct udphdr* l4_hdr = (struct udphdr*)(l3_hdr + 1);
src_port = l4_hdr->source;
dst_port = l4_hdr->dest;
break;
}
default:
break;
}

// check if this configuration has already been bound
ConfigTuple tup(dst_port, src_port, dst_ip, src_ip, protocol);
if (config_hashmap.find(tup) != config_hashmap.end()) {
return config_hashmap[tup];
}

return (src_ip ^ dst_ip ^ protocol ^ src_port ^ dst_port) % mod;
}

#endif

int set_core_id(std::thread& thread, int core_id) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
Expand Down
Loading