Skip to content

Commit 47b3d1a

Browse files
authored
Merge pull request kmesh-net#1029 from nlgwcy/optimize
optimize xDS bpf map
2 parents ce92599 + e57194b commit 47b3d1a

39 files changed

+795
-1159
lines changed

bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.c

Lines changed: 364 additions & 842 deletions
Large diffs are not rendered by default.

bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.h

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,6 @@
66

77
#include <stdbool.h>
88

9-
/* equal MAP_SIZE_OF_OUTTER_MAP */
10-
#define MAX_OUTTER_MAP_ENTRIES (1 << 20)
11-
#define OUTTER_MAP_USAGE_HIGH_PERCENT (0.7)
12-
#define OUTTER_MAP_USAGE_LOW_PERCENT (0.3)
13-
#define TASK_SIZE (512)
14-
15-
// 32,768
16-
#define OUTTER_MAP_SCALEUP_STEP (1 << 15)
17-
// 8,192
18-
#define OUTTER_MAP_SCALEIN_STEP (1 << 13)
19-
20-
#define ELASTIC_SLOTS_NUM \
21-
((OUTTER_MAP_SCALEUP_STEP > OUTTER_MAP_SCALEIN_STEP) ? OUTTER_MAP_SCALEUP_STEP : OUTTER_MAP_SCALEIN_STEP)
22-
239
struct element_list_node {
2410
void *elem;
2511
struct element_list_node *next;
@@ -32,8 +18,7 @@ void deserial_free_elem(void *value);
3218
void deserial_free_elem_list(struct element_list_node *head);
3319
int deserial_delete_elem(void *key, const void *msg_desciptor);
3420

35-
int deserial_init(bool restore);
36-
int deserial_uninit(bool persist);
37-
int inner_map_mng_persist();
21+
int deserial_init();
22+
void deserial_uninit();
3823

39-
#endif /* __DESERIALIZATION_TO_BPF_MAP_H__ */
24+
#endif /* __DESERIALIZATION_TO_BPF_MAP_H__ */

bpf/include/bpf_common.h

Lines changed: 68 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,36 @@ struct {
5656
} map_of_sock_storage SEC(".maps");
5757

5858
struct {
59-
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
59+
__uint(type, BPF_MAP_TYPE_HASH);
60+
__uint(key_size, sizeof(__u32));
61+
__uint(value_size, MAP_VAL_SIZE_64);
62+
__uint(max_entries, MAP_MAX_ENTRIES);
63+
__uint(map_flags, BPF_F_NO_PREALLOC);
64+
} kmesh_map64 SEC(".maps");
65+
66+
struct {
67+
__uint(type, BPF_MAP_TYPE_HASH);
68+
__uint(key_size, sizeof(__u32));
69+
__uint(value_size, MAP_VAL_SIZE_192);
70+
__uint(max_entries, MAP_MAX_ENTRIES);
71+
__uint(map_flags, BPF_F_NO_PREALLOC);
72+
} kmesh_map192 SEC(".maps");
73+
74+
struct {
75+
__uint(type, BPF_MAP_TYPE_HASH);
6076
__uint(key_size, sizeof(__u32));
61-
__uint(value_size, sizeof(__u32));
62-
__uint(max_entries, MAP_SIZE_OF_OUTTER_MAP);
63-
__uint(map_flags, 0);
64-
} outer_map SEC(".maps");
77+
__uint(value_size, MAP_VAL_SIZE_296);
78+
__uint(max_entries, MAP_MAX_ENTRIES);
79+
__uint(map_flags, BPF_F_NO_PREALLOC);
80+
} kmesh_map296 SEC(".maps");
6581

6682
struct {
67-
__uint(type, BPF_MAP_TYPE_ARRAY);
83+
__uint(type, BPF_MAP_TYPE_HASH);
6884
__uint(key_size, sizeof(__u32));
69-
__uint(value_size, BPF_INNER_MAP_DATA_LEN);
70-
__uint(max_entries, 1);
71-
__uint(map_flags, 0);
72-
} inner_map SEC(".maps");
85+
__uint(value_size, MAP_VAL_SIZE_1600);
86+
__uint(max_entries, MAP_MAX_ENTRIES);
87+
__uint(map_flags, BPF_F_NO_PREALLOC);
88+
} kmesh_map1600 SEC(".maps");
7389

7490
/*
7591
* From v5.4, bpf_get_netns_cookie can be called for bpf cgroup hooks, from v5.15, it can be called for bpf sockops
@@ -160,31 +176,51 @@ static inline bool handle_kmesh_manage_process(struct kmesh_context *kmesh_ctx)
160176
return false;
161177
}
162178

163-
static inline void *kmesh_get_ptr_val(const void *ptr)
179+
static inline void kmesh_parse_outer_key(__u32 outer_key, __u8 *type, __u32 *inner_idx)
164180
{
165-
/*
166-
map_in_map -- outer_map:
167-
key value
168-
idx1 inner_map_fd1 // point to inner map1
169-
idx2 inner_map_fd2 // point to inner map2
170-
171-
structA.ptr_member1 = idx1; // store idx in outer_map
172-
*/
173-
void *inner_map_instance = NULL;
174-
__u32 inner_idx = 0;
175-
__u32 idx = (__u32)(uintptr_t)ptr;
176-
177-
if (!ptr) {
178-
return NULL;
179-
}
181+
*type = MAP_GET_TYPE(outer_key);
182+
*inner_idx = MAP_GET_INDEX(outer_key);
183+
return;
184+
}
180185

181-
/* get inner_map_instance by idx */
182-
inner_map_instance = kmesh_map_lookup_elem(&outer_map, &idx);
183-
if (!inner_map_instance) {
186+
static inline void *get_ptr_val_from_map(void *map, __u8 map_type, const void *ptr)
187+
{
188+
__u8 type;
189+
__u32 inner_idx;
190+
__u32 outer_key = (__u32)(uintptr_t)ptr;
191+
192+
kmesh_parse_outer_key(outer_key, &type, &inner_idx);
193+
if (type != map_type) {
194+
BPF_LOG(ERR, KMESH, "get_ptr_val: invalid map type(%u %u)\n", type, map_type);
184195
return NULL;
185196
}
186197

187-
/* get inner_map_instance value */
188-
return kmesh_map_lookup_elem(inner_map_instance, &inner_idx);
198+
return kmesh_map_lookup_elem(map, &inner_idx);
189199
}
190-
#endif
200+
201+
#define KMESH_GET_PTR_VAL(ptr, type) \
202+
({ \
203+
void *val_tmp = NULL; \
204+
if (sizeof(type) == sizeof(void *)) { \
205+
if (__builtin_types_compatible_p(type, char *)) \
206+
val_tmp = get_ptr_val_from_map(&kmesh_map192, MAP_TYPE_192, ptr); \
207+
else if (__builtin_types_compatible_p(type, void *)) \
208+
val_tmp = get_ptr_val_from_map(&kmesh_map1600, MAP_TYPE_1600, ptr); \
209+
else if (__builtin_types_compatible_p(type, void **)) \
210+
val_tmp = get_ptr_val_from_map(&kmesh_map1600, MAP_TYPE_1600, ptr); \
211+
else \
212+
val_tmp = get_ptr_val_from_map(&kmesh_map64, MAP_TYPE_64, ptr); \
213+
} else if (sizeof(type) <= MAP_VAL_SIZE_64) \
214+
val_tmp = get_ptr_val_from_map(&kmesh_map64, MAP_TYPE_64, ptr); \
215+
else if (sizeof(type) <= MAP_VAL_SIZE_192) \
216+
val_tmp = get_ptr_val_from_map(&kmesh_map192, MAP_TYPE_192, ptr); \
217+
else if (sizeof(type) <= MAP_VAL_SIZE_296) \
218+
val_tmp = get_ptr_val_from_map(&kmesh_map296, MAP_TYPE_296, ptr); \
219+
else if (sizeof(type) <= MAP_VAL_SIZE_1600) \
220+
val_tmp = get_ptr_val_from_map(&kmesh_map1600, MAP_TYPE_1600, ptr); \
221+
else \
222+
val_tmp = NULL; \
223+
val_tmp; \
224+
})
225+
226+
#endif

bpf/include/inner_map_defs.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@
44
#ifndef __INNER_MAP_H__
55
#define __INNER_MAP_H__
66

7-
#define BPF_INNER_MAP_DATA_LEN 1300
7+
// outer key:
8+
// map_type(1 byte) + inner_index(3 bytes)
89

9-
#endif // __INNER_MAP_H__
10+
typedef enum { MAP_TYPE_64, MAP_TYPE_192, MAP_TYPE_296, MAP_TYPE_1600, MAP_TYPE_MAX } map_in_map_type;
11+
12+
#define MAP_GET_TYPE(idx) (__u8)((__u32)(idx) >> 24)
13+
#define MAP_GET_INDEX(idx) (__u32)((__u32)(idx)&0xFFFFFF)
14+
#define MAP_GEN_OUTER_KEY(map_type, pos) ((__u32)((((__u8)(map_type)&0xFF) << 24) + ((__u32)(pos)&0xFFFFFF)))
15+
16+
#define MAP_VAL_SIZE_64 64
17+
#define MAP_VAL_SIZE_192 192
18+
#define MAP_VAL_SIZE_296 296
19+
#define MAP_VAL_SIZE_1600 1600
20+
#define MAP_MAX_ENTRIES 1000000
21+
22+
#define MAP_VAL_STR_SIZE MAP_VAL_SIZE_192
23+
#define MAP_VAL_REPEAT_SIZE MAP_VAL_SIZE_1600
24+
25+
#define SET_BIT(bitmap, n) ((bitmap)[(n) / 8] |= (1U << ((n) % 8)))
26+
27+
#define CLEAR_BIT(bitmap, n) ((bitmap)[(n) / 8] &= ~(1U << ((n) % 8)))
28+
29+
#define IS_SET(bitmap, n) (((bitmap)[(n) / 8] & (1U << ((n) % 8))) != 0)
30+
31+
#define IS_CLEAR(bitmap, n) (((bitmap)[(n) / 8] & (1U << ((n) % 8))) == 0)
32+
33+
#define FLIP_BIT(bitmap, n) ((bitmap)[(n) / 8] ^= (1U << ((n) % 8)))
34+
35+
#endif // __INNER_MAP_H__

bpf/kmesh/ads/include/circuit_breaker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static inline int on_cluster_sock_bind(ctx_buff_t *ctx, const Cluster__Cluster *
8686

8787
if (stats != NULL) {
8888
Cluster__CircuitBreakers *cbs = NULL;
89-
cbs = kmesh_get_ptr_val(cluster->circuit_breakers);
89+
cbs = KMESH_GET_PTR_VAL(cluster->circuit_breakers, Cluster__CircuitBreakers);
9090
if (cbs != NULL && stats->active_connections >= cbs->max_connections) {
9191
BPF_LOG(
9292
DEBUG,

bpf/kmesh/ads/include/cluster.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ cluster_add_endpoints(const Endpoint__LocalityLbEndpoints *lb_ep, struct cluster
9393
__u32 i;
9494
void *ep_ptrs = NULL;
9595

96-
ep_ptrs = kmesh_get_ptr_val(lb_ep->lb_endpoints);
96+
ep_ptrs = KMESH_GET_PTR_VAL(lb_ep->lb_endpoints, void *);
9797
if (!ep_ptrs)
9898
return -1;
9999

@@ -115,7 +115,7 @@ static inline __u32 cluster_get_endpoints_num(const Endpoint__ClusterLoadAssignm
115115
void *ptrs = NULL;
116116
Endpoint__LocalityLbEndpoints *lb_ep = NULL;
117117

118-
ptrs = kmesh_get_ptr_val(cla->endpoints);
118+
ptrs = KMESH_GET_PTR_VAL(cla->endpoints, void *);
119119
if (!ptrs)
120120
return 0;
121121

@@ -125,7 +125,8 @@ static inline __u32 cluster_get_endpoints_num(const Endpoint__ClusterLoadAssignm
125125
break;
126126
}
127127

128-
lb_ep = (Endpoint__LocalityLbEndpoints *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i));
128+
lb_ep = (Endpoint__LocalityLbEndpoints *)KMESH_GET_PTR_VAL(
129+
(void *)*((__u64 *)ptrs + i), Endpoint__LocalityLbEndpoints);
129130
if (!lb_ep)
130131
continue;
131132

@@ -152,7 +153,7 @@ static inline int cluster_init_endpoints(const char *cluster_name, const Endpoin
152153
}
153154
cluster_eps->ep_num = 0;
154155

155-
ptrs = kmesh_get_ptr_val(cla->endpoints);
156+
ptrs = KMESH_GET_PTR_VAL(cla->endpoints, void *);
156157
if (!ptrs) {
157158
BPF_LOG(ERR, CLUSTER, "failed to get cla endpoints ptrs\n");
158159
return -1;
@@ -163,7 +164,8 @@ static inline int cluster_init_endpoints(const char *cluster_name, const Endpoin
163164
if (i >= cla->n_endpoints)
164165
break;
165166

166-
ep = (Endpoint__LocalityLbEndpoints *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i));
167+
ep = (Endpoint__LocalityLbEndpoints *)KMESH_GET_PTR_VAL(
168+
(void *)*((__u64 *)ptrs + i), Endpoint__LocalityLbEndpoints);
167169
if (!ep)
168170
continue;
169171

@@ -186,7 +188,7 @@ cluster_check_endpoints(const struct cluster_endpoints *eps, const Endpoint__Clu
186188
if (!eps || eps->ep_num != lb_num)
187189
return 0;
188190

189-
ptrs = kmesh_get_ptr_val(cla->endpoints);
191+
ptrs = KMESH_GET_PTR_VAL(cla->endpoints, void *);
190192
if (!ptrs)
191193
return 0;
192194

@@ -207,7 +209,7 @@ static inline struct cluster_endpoints *cluster_refresh_endpoints(const Cluster_
207209
struct cluster_endpoints *eps = NULL;
208210
Endpoint__ClusterLoadAssignment *cla = NULL;
209211

210-
cla = kmesh_get_ptr_val(cluster->load_assignment);
212+
cla = KMESH_GET_PTR_VAL(cluster->load_assignment, Endpoint__ClusterLoadAssignment);
211213
if (!cla) {
212214
BPF_LOG(ERR, CLUSTER, "get load_assignment failed\n");
213215
return NULL;
@@ -264,13 +266,13 @@ static inline Core__SocketAddress *cluster_get_ep_sock_addr(const void *ep_ident
264266
Endpoint__Endpoint *ep = NULL;
265267
Core__SocketAddress *sock_addr = NULL;
266268

267-
ep = kmesh_get_ptr_val(ep_identity);
269+
ep = KMESH_GET_PTR_VAL(ep_identity, Endpoint__Endpoint);
268270
if (!ep) {
269271
BPF_LOG(ERR, CLUSTER, "cluster get ep failed\n");
270272
return NULL;
271273
}
272274

273-
sock_addr = kmesh_get_ptr_val(ep->address);
275+
sock_addr = KMESH_GET_PTR_VAL(ep->address, Core__SocketAddress);
274276
if (!sock_addr) {
275277
BPF_LOG(ERR, CLUSTER, "ep get sock addr failed\n");
276278
return NULL;
@@ -285,7 +287,7 @@ static inline int cluster_handle_loadbalance(Cluster__Cluster *cluster, address_
285287
Core__SocketAddress *sock_addr = NULL;
286288
struct cluster_endpoints *eps = NULL;
287289

288-
name = kmesh_get_ptr_val(cluster->name);
290+
name = KMESH_GET_PTR_VAL(cluster->name, char *);
289291
if (!name) {
290292
BPF_LOG(ERR, CLUSTER, "failed to get cluster\n");
291293
return -EAGAIN;
@@ -350,4 +352,4 @@ int cluster_manager(ctx_buff_t *ctx)
350352
return KMESH_TAIL_CALL_RET(ret);
351353
}
352354

353-
#endif
355+
#endif

bpf/kmesh/ads/include/filter.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static inline int filter_chain_filter_match(
5353
}
5454

5555
/* filter match */
56-
ptrs = kmesh_get_ptr_val(filter_chain->filters);
56+
ptrs = KMESH_GET_PTR_VAL(filter_chain->filters, void *);
5757
if (!ptrs) {
5858
BPF_LOG(ERR, FILTER, "failed to get filter ptrs\n");
5959
return -1;
@@ -66,7 +66,7 @@ static inline int filter_chain_filter_match(
6666
break;
6767
}
6868

69-
filter = (Listener__Filter *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i));
69+
filter = (Listener__Filter *)KMESH_GET_PTR_VAL((void *)*((__u64 *)ptrs + i), Listener__Filter);
7070
if (!filter) {
7171
continue;
7272
}
@@ -89,7 +89,7 @@ static inline int handle_http_connection_manager(
8989
ctx_key_t ctx_key = {0};
9090
ctx_val_t ctx_val = {0};
9191

92-
route_name = kmesh_get_ptr_val((http_conn->route_config_name));
92+
route_name = KMESH_GET_PTR_VAL((http_conn->route_config_name), char *);
9393
if (!route_name) {
9494
BPF_LOG(ERR, FILTER, "failed to get http conn route name\n");
9595
return -1;
@@ -120,7 +120,7 @@ int filter_manager(ctx_buff_t *ctx)
120120
return KMESH_TAIL_CALL_RET(-1);
121121
}
122122

123-
filter = (Listener__Filter *)kmesh_get_ptr_val((void *)ctx_val->val);
123+
filter = (Listener__Filter *)KMESH_GET_PTR_VAL((void *)ctx_val->val, Listener__Filter);
124124
if (!filter) {
125125
BPF_LOG(ERR, FILTER, "failed to get filter\n");
126126
return KMESH_TAIL_CALL_RET(-1);
@@ -130,7 +130,7 @@ int filter_manager(ctx_buff_t *ctx)
130130
switch (filter->config_type_case) {
131131
#ifndef CGROUP_SOCK_MANAGE
132132
case LISTENER__FILTER__CONFIG_TYPE_HTTP_CONNECTION_MANAGER:
133-
http_conn = kmesh_get_ptr_val(filter->http_connection_manager);
133+
http_conn = KMESH_GET_PTR_VAL(filter->http_connection_manager, Filter__HttpConnectionManager);
134134
ret = bpf_parse_header_msg(ctx_val->msg);
135135
if (GET_RET_PROTO_TYPE(ret) != PROTO_HTTP_1_1) {
136136
BPF_LOG(DEBUG, FILTER, "http filter manager,only support http1.1 this version");
@@ -146,7 +146,7 @@ int filter_manager(ctx_buff_t *ctx)
146146
break;
147147
#endif
148148
case LISTENER__FILTER__CONFIG_TYPE_TCP_PROXY:
149-
tcp_proxy = kmesh_get_ptr_val(filter->tcp_proxy);
149+
tcp_proxy = KMESH_GET_PTR_VAL(filter->tcp_proxy, Filter__TcpProxy);
150150
if (!tcp_proxy) {
151151
BPF_LOG(ERR, FILTER, "get tcp_prxoy failed\n");
152152
ret = -1;
@@ -181,7 +181,7 @@ int filter_chain_manager(ctx_buff_t *ctx)
181181
}
182182
kmesh_tail_delete_ctx(&ctx_key);
183183

184-
filter_chain = (Listener__FilterChain *)kmesh_get_ptr_val((void *)ctx_val_ptr->val);
184+
filter_chain = (Listener__FilterChain *)KMESH_GET_PTR_VAL((void *)ctx_val_ptr->val, Listener__FilterChain);
185185
if (filter_chain == NULL) {
186186
return KMESH_TAIL_CALL_RET(-1);
187187
}
@@ -212,4 +212,4 @@ int filter_chain_manager(ctx_buff_t *ctx)
212212
return KMESH_TAIL_CALL_RET(ret);
213213
}
214214

215-
#endif
215+
#endif

0 commit comments

Comments
 (0)