Skip to content

Commit

Permalink
net: add function to map packet's rss hash to a cpu
Browse files Browse the repository at this point in the history
Provide a function that maps packet's rss hash to a cpu that should handle
it. This function is needed to find appropriate src port for outgoing
tcp/udp connection. Use this function to forward de-fragmented ip packet
to avoid one extra hop too.
  • Loading branch information
gleb-cloudius authored and avikivity committed Dec 23, 2014
1 parent db50b48 commit 510171d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 21 deletions.
2 changes: 1 addition & 1 deletion net/ip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ ipv4::handle_received_packet(packet p, ethernet_address from) {
hash_data.push_back(hton(h.src_ip.ip));
hash_data.push_back(hton(h.dst_ip.ip));
l4->forward(hash_data, ip_data, l4_offset);
cpu_id = _netif->hash2qid(toeplitz_hash(rsskey, hash_data));
cpu_id = _netif->hash2cpu(toeplitz_hash(rsskey, hash_data));
}

// No need to forward if the dst cpu is the current cpu
Expand Down
19 changes: 12 additions & 7 deletions net/net.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ interface::register_l3(eth_protocol_num proto_num,
return l3_rx.packet_stream.listen(std::move(next));
}

unsigned interface::hash2qid(uint32_t hash) {
return _dev->hash2qid(hash);
unsigned interface::hash2cpu(uint32_t hash) {
return _dev->hash2cpu(hash);
}

void interface::forward(unsigned cpuid, packet p) {
Expand All @@ -66,12 +66,17 @@ future<> interface::dispatch_packet(packet p) {
auto i = _proto_map.find(ntoh(eh->eth_proto));
if (i != _proto_map.end()) {
l3_rx_stream& l3 = i->second;
auto fw = _dev->forward_dst(p, [&l3] (packet& p) {
forward_hash data;
if (l3.forward(data, p, sizeof(eth_hdr))) {
return toeplitz_hash(rsskey, data);
auto fw = _dev->forward_dst(engine.cpu_id(), [&p, &l3] () {
auto hwrss = p.rss_hash();
if (hwrss) {
return hwrss.value();
} else {
forward_hash data;
if (l3.forward(data, p, sizeof(eth_hdr))) {
return toeplitz_hash(rsskey, data);
}
return 0u;
}
return 0u;
});
if (fw != engine.cpu_id()) {
forward(fw, std::move(p));
Expand Down
24 changes: 11 additions & 13 deletions net/net.hh
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public:
std::function<future<> (packet p, ethernet_address from)> next,
std::function<bool (forward_hash&, packet&, size_t)> forward);
void forward(unsigned cpuid, packet p);
unsigned hash2qid(uint32_t hash);
unsigned hash2cpu(uint32_t hash);
friend class l3_protocol;
};

Expand Down Expand Up @@ -145,21 +145,19 @@ public:
engine.at_exit([dev = std::move(dev)] {});
}
template <typename Func>
unsigned forward_dst(packet& p, Func&& hashfn) {
auto& qp = local_queue();
unsigned forward_dst(unsigned src_cpuid, Func&& hashfn) {
auto& qp = queue_for_cpu(src_cpuid);
if (!qp.may_forward()) {
return engine.cpu_id();
return src_cpuid;
}
auto hwrss = p.rss_hash();
uint32_t hash;
if (hwrss) {
hash = hwrss.value();
} else {
hash = hashfn(p);
}
hash >>= _rss_table_bits;
auto hash = hashfn() >> _rss_table_bits;
auto idx = hash % (qp.proxies.size() + 1);
return idx ? qp.proxies[idx - 1] : engine.cpu_id();
return idx ? qp.proxies[idx - 1] : src_cpuid;
}
virtual unsigned hash2cpu(uint32_t hash) {
// there is an assumption here that qid == cpu_id which will
// not necessary be true in the future
return forward_dst(hash2qid(hash), [hash] { return hash; });
}
};

Expand Down

0 comments on commit 510171d

Please sign in to comment.