mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Add a "hot cache" to the XDP LPM lookup system.
Adds a new BPF map (an LRU hash) containing IP addresses and TC mapping info. IPs are first checked against the hot cache, because a hashmap lookup is faster than an LPM lookup. If found, the cached value is used. If not found, then the key is inserted into the LRU map (so currently hot stays present, others expire over time) for future cache use.
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include "maximums.h"
|
||||
#include "debug.h"
|
||||
#include "dissector.h"
|
||||
|
||||
// Data structure used for map_ip_hash
|
||||
@@ -24,6 +23,22 @@ struct ip_hash_key {
|
||||
struct in6_addr address; // An IPv6 address. IPv4 uses the last 32 bits.
|
||||
};
|
||||
|
||||
// Hot cache for recent IP lookups, an attempt
|
||||
// at a speed improvement predicated on the idea
|
||||
// that LPM isn't the fastest
|
||||
// The cache is optional. define USE_HOTCACHE
|
||||
// to enable it.
|
||||
#define USE_HOTCACHE 1
|
||||
|
||||
#ifdef USE_HOTCACHE
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_LRU_HASH);
|
||||
__uint(max_entries, HOT_CACHE_SIZE);
|
||||
__type(key, struct in6_addr);
|
||||
__type(value, struct ip_hash_info);
|
||||
} ip_to_cpu_and_tc_hotcache SEC(".maps");
|
||||
#endif
|
||||
|
||||
// Map describing IP to CPU/TC mappings
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_LPM_TRIE);
|
||||
@@ -71,13 +86,39 @@ static __always_inline struct ip_hash_info * setup_lookup_key_and_tc_cpu(
|
||||
struct dissector_t * dissector
|
||||
)
|
||||
{
|
||||
struct ip_hash_info * ip_info;
|
||||
|
||||
lookup_key->prefixlen = 128;
|
||||
lookup_key->address = (direction == 1) ? dissector->dst_ip :
|
||||
dissector->src_ip;
|
||||
struct ip_hash_info * ip_info = bpf_map_lookup_elem(
|
||||
|
||||
#ifdef USE_HOTCACHE
|
||||
// Try a hot cache search
|
||||
ip_info = bpf_map_lookup_elem(
|
||||
&ip_to_cpu_and_tc_hotcache,
|
||||
&lookup_key->address
|
||||
);
|
||||
if (ip_info) {
|
||||
// We got a cache hit, so return
|
||||
return ip_info;
|
||||
}
|
||||
#endif
|
||||
|
||||
ip_info = bpf_map_lookup_elem(
|
||||
&map_ip_to_cpu_and_tc,
|
||||
lookup_key
|
||||
);
|
||||
#ifdef USE_HOTCACHE
|
||||
if (ip_info) {
|
||||
// We found it, so add it to the cache
|
||||
bpf_map_update_elem(
|
||||
&ip_to_cpu_and_tc_hotcache,
|
||||
&lookup_key->address,
|
||||
ip_info,
|
||||
BPF_NOEXIST
|
||||
);
|
||||
}
|
||||
#endif
|
||||
return ip_info;
|
||||
}
|
||||
|
||||
@@ -104,9 +145,10 @@ static __always_inline struct ip_hash_info * tc_setup_lookup_key_and_tc_cpu(
|
||||
lookup_key->prefixlen = 128;
|
||||
// Direction is reversed because we are operating on egress
|
||||
if (direction < 3) {
|
||||
lookup_key->address = (direction == 1) ? dissector->src_ip :
|
||||
lookup_key->address = (direction == 1) ? dissector->src_ip :
|
||||
dissector->dst_ip;
|
||||
*out_effective_direction = direction;
|
||||
|
||||
struct ip_hash_info * ip_info = bpf_map_lookup_elem(
|
||||
&map_ip_to_cpu_and_tc,
|
||||
lookup_key
|
||||
|
||||
@@ -14,3 +14,6 @@
|
||||
|
||||
// Maximum number of packet pairs to track per flow.
|
||||
#define MAX_PACKETS MAX_FLOWS
|
||||
|
||||
// Hot Cache Size
|
||||
#define HOT_CACHE_SIZE 512
|
||||
Reference in New Issue
Block a user