mirror of
https://github.com/scylladb/scylladb.git
synced 2026-06-08 16:03:20 +00:00
net: add function to map packet's rss hash to a cpu
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.
This commit is contained in:
@@ -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
|
||||
|
||||
19
net/net.cc
19
net/net.cc
@@ -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) {
|
||||
@@ -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));
|
||||
|
||||
24
net/net.hh
24
net/net.hh
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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; });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user