Skip to content

Commit 7167dc6

Browse files
rjarrychristophefontaine
authored andcommitted
control_output: use dynfields
Replace the GR_MBUF_PRIV_DATA_TYPE based control_output_mbuf_data structure with DPDK dynamic fields. Register two dynfields at initialization: one for the control queue callback pointer and one for a generic uintptr_t private value. Using GR_MBUF_PRIV_DATA_TYPE for control_output_mbuf_data was problematic because it would overwrite mbuf private data set by previous nodes in the graph. Callers that needed to pass extra context to their callback had to copy data into the opaque cb_data buffer, which was error-prone and wasteful. With dynfields, the callback and priv value are stored at dedicated offsets that do not conflict with other node data. Callers can pass a pointer or value directly via the priv argument without any copying. For ICMP and ICMPv6, the timestamp is passed via priv and stored in the queue item structure on the control plane side. Provide control_output_set_cb() as the single entry point for setting the callback and private data on an mbuf destined for control plane processing. Signed-off-by: Robin Jarry <rjarry@redhat.com>
1 parent fc58c0f commit 7167dc6

File tree

22 files changed

+178
-168
lines changed

22 files changed

+178
-168
lines changed

devtools/complexity.json

Lines changed: 69 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
"uops": 49
1616
}
1717
],
18-
"ipc": 1.92,
19-
"self_cycles": 33.8,
20-
"total_cycles": 52.3,
21-
"uops": 135
18+
"ipc": 1.87,
19+
"self_cycles": 29.5,
20+
"total_cycles": 48.0,
21+
"uops": 118
2222
},
2323
"arp_input_request_process": {
2424
"callees": [
@@ -31,9 +31,9 @@
3131
}
3232
],
3333
"ipc": 1.72,
34-
"self_cycles": 28.2,
35-
"total_cycles": 46.7,
36-
"uops": 113
34+
"self_cycles": 28,
35+
"total_cycles": 46.5,
36+
"uops": 112
3737
},
3838
"arp_output_reply_process": {
3939
"callees": [
@@ -117,16 +117,16 @@
117117
"uops": 3
118118
}
119119
],
120-
"ipc": 1.54,
121-
"self_cycles": 26,
122-
"total_cycles": 145.6,
123-
"uops": 104
120+
"ipc": 1.65,
121+
"self_cycles": 27,
122+
"total_cycles": 146.6,
123+
"uops": 108
124124
},
125125
"dhcp_input_process": {
126-
"ipc": 1.91,
127-
"self_cycles": 35.5,
128-
"total_cycles": 35.5,
129-
"uops": 142
126+
"ipc": 1.96,
127+
"self_cycles": 36.2,
128+
"total_cycles": 36.2,
129+
"uops": 145
130130
},
131131
"dnat44_dynamic_process": {
132132
"callees": [
@@ -219,10 +219,10 @@
219219
"uops": 42
220220
}
221221
],
222-
"ipc": 2.64,
223-
"self_cycles": 55.2,
224-
"total_cycles": 73.5,
225-
"uops": 221
222+
"ipc": 2.62,
223+
"self_cycles": 54.5,
224+
"total_cycles": 72.8,
225+
"uops": 218
226226
},
227227
"icmp6_local_send_process": {
228228
"callees": [
@@ -262,10 +262,10 @@
262262
"uops": 402
263263
},
264264
"icmp_input_process": {
265-
"ipc": 2.97,
266-
"self_cycles": 59.8,
267-
"total_cycles": 59.8,
268-
"uops": 239
265+
"ipc": 3.02,
266+
"self_cycles": 60.8,
267+
"total_cycles": 60.8,
268+
"uops": 243
269269
},
270270
"icmp_local_send_process": {
271271
"ipc": 2.4,
@@ -310,10 +310,10 @@
310310
"uops": 112
311311
},
312312
"ip6_hold_process": {
313-
"ipc": 1.28,
314-
"self_cycles": 21.8,
315-
"total_cycles": 21.8,
316-
"uops": 87
313+
"ipc": 2.85,
314+
"self_cycles": 63.2,
315+
"total_cycles": 63.2,
316+
"uops": 253
317317
},
318318
"ip6_input_local_process": {
319319
"callees": [
@@ -353,10 +353,10 @@
353353
"uops": 209
354354
},
355355
"ip6_loadbalance_process": {
356-
"ipc": 1.78,
357-
"self_cycles": 28.5,
358-
"total_cycles": 28.5,
359-
"uops": 114
356+
"ipc": 1.7,
357+
"self_cycles": 27.5,
358+
"total_cycles": 27.5,
359+
"uops": 110
360360
},
361361
"ip6_output_process": {
362362
"callees": [
@@ -424,10 +424,10 @@
424424
"uops": 697
425425
},
426426
"ip_hold_process": {
427-
"ipc": 1.28,
428-
"self_cycles": 21.8,
429-
"total_cycles": 21.8,
430-
"uops": 87
427+
"ipc": 2.91,
428+
"self_cycles": 65.8,
429+
"total_cycles": 65.8,
430+
"uops": 263
431431
},
432432
"ip_input_local_process": {
433433
"ipc": 1.87,
@@ -483,7 +483,7 @@
483483
"ipc": 1.67,
484484
"name": "snat44_static_process",
485485
"self_cycles": 30,
486-
"total_cycles": 44.1,
486+
"total_cycles": 44.8,
487487
"uops": 120
488488
},
489489
{
@@ -496,7 +496,7 @@
496496
],
497497
"ipc": 2.53,
498498
"self_cycles": 48,
499-
"total_cycles": 866.1,
499+
"total_cycles": 866.8,
500500
"uops": 192
501501
},
502502
"ipip_input_process": {
@@ -552,10 +552,10 @@
552552
"uops": 127
553553
},
554554
"l2_redirect_process": {
555-
"ipc": 1.28,
556-
"self_cycles": 21.8,
557-
"total_cycles": 21.8,
558-
"uops": 87
555+
"ipc": 2.85,
556+
"self_cycles": 63.2,
557+
"total_cycles": 63.2,
558+
"uops": 253
559559
},
560560
"l4_input_local_process": {
561561
"ipc": 1.57,
@@ -579,10 +579,10 @@
579579
"uops": 307
580580
},
581581
"lacp_input_process": {
582-
"ipc": 2.07,
583-
"self_cycles": 37.5,
584-
"total_cycles": 37.5,
585-
"uops": 150
582+
"ipc": 2.05,
583+
"self_cycles": 37.8,
584+
"total_cycles": 37.8,
585+
"uops": 151
586586
},
587587
"lacp_output_process": {
588588
"ipc": 2.32,
@@ -591,10 +591,10 @@
591591
"uops": 159
592592
},
593593
"loop_xvrf_process": {
594-
"ipc": 1.82,
595-
"self_cycles": 30,
596-
"total_cycles": 30,
597-
"uops": 120
594+
"ipc": 1.74,
595+
"self_cycles": 29,
596+
"total_cycles": 29,
597+
"uops": 116
598598
},
599599
"loopback_input_process": {
600600
"ipc": 1.64,
@@ -603,10 +603,10 @@
603603
"uops": 108
604604
},
605605
"loopback_output_process": {
606-
"ipc": 1.19,
607-
"self_cycles": 21.2,
608-
"total_cycles": 21.2,
609-
"uops": 85
606+
"ipc": 2.85,
607+
"self_cycles": 63.2,
608+
"total_cycles": 63.2,
609+
"uops": 253
610610
},
611611
"ndp_na_input_process": {
612612
"callees": [
@@ -625,10 +625,10 @@
625625
"uops": 49
626626
}
627627
],
628-
"ipc": 2.4,
629-
"self_cycles": 40.8,
630-
"total_cycles": 126.3,
631-
"uops": 163
628+
"ipc": 2.42,
629+
"self_cycles": 38.8,
630+
"total_cycles": 124.3,
631+
"uops": 155
632632
},
633633
"ndp_na_output_process": {
634634
"ipc": 3.08,
@@ -653,10 +653,10 @@
653653
"uops": 49
654654
}
655655
],
656-
"ipc": 2.87,
657-
"self_cycles": 64.2,
658-
"total_cycles": 149.7,
659-
"uops": 257
656+
"ipc": 2.93,
657+
"self_cycles": 62.2,
658+
"total_cycles": 147.7,
659+
"uops": 249
660660
},
661661
"ndp_ns_output_process": {
662662
"callees": [
@@ -681,10 +681,10 @@
681681
"uops": 195
682682
},
683683
"ndp_rs_input_process": {
684-
"ipc": 1.48,
685-
"self_cycles": 25.5,
686-
"total_cycles": 25.5,
687-
"uops": 102
684+
"ipc": 1.5,
685+
"self_cycles": 25.2,
686+
"total_cycles": 25.2,
687+
"uops": 101
688688
},
689689
"ospf_redirect_process": {
690690
"callees": [
@@ -702,10 +702,10 @@
702702
"uops": 543
703703
},
704704
"port_output_process": {
705-
"ipc": 1.72,
706-
"self_cycles": 28.5,
707-
"total_cycles": 28.5,
708-
"uops": 114
705+
"ipc": 1.57,
706+
"self_cycles": 26.5,
707+
"total_cycles": 26.5,
708+
"uops": 106
709709
},
710710
"rx_process": {
711711
"callees": [

modules/dhcp/datapath/dhcp_input.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,12 @@ enum {
3030

3131
static uint16_t
3232
dhcp_input_process(struct rte_graph *graph, struct rte_node *node, void **objs, uint16_t nb_objs) {
33-
struct control_output_mbuf_data *d;
3433
struct rte_mbuf *mbuf;
3534

3635
for (uint16_t i = 0; i < nb_objs; i++) {
3736
mbuf = objs[i];
3837

39-
d = control_output_mbuf_data(mbuf);
40-
d->callback = dhcp_input_cb;
38+
control_output_set_cb(mbuf, dhcp_input_cb, 0);
4139

4240
if (gr_mbuf_is_traced(mbuf)) {
4341
struct dhcp_input_trace_data *t;

modules/infra/control/lacp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
static struct event *lacp_timer;
2727

2828
void lacp_input_cb(void *obj, uintptr_t, const struct control_queue_drain *drain) {
29-
struct control_output_mbuf_data *ctrl_data = control_output_mbuf_data(obj);
3029
const struct iface_info_port *port;
3130
const struct iface *port_iface;
3231
struct iface_info_bond *bond;
@@ -35,7 +34,8 @@ void lacp_input_cb(void *obj, uintptr_t, const struct control_queue_drain *drain
3534
struct bond_member *member;
3635
struct iface *bond_iface;
3736

38-
memcpy(&port_iface, ctrl_data->cb_data, sizeof(struct iface *));
37+
port_iface = mbuf_data(mbuf)->iface;
38+
3939
// Check if packet references deleted interface.
4040
if (drain && drain->event == GR_EVENT_IFACE_REMOVE && port_iface == drain->obj)
4141
goto out;

modules/infra/datapath/control_output.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,33 @@
1111

1212
#define ERROR 0
1313

14+
int cq_callback_offset;
15+
int cq_priv_offset;
16+
1417
static uint16_t control_output_process(
1518
struct rte_graph *graph,
1619
struct rte_node *node,
1720
void **objs,
1821
uint16_t n_objs
1922
) {
23+
control_queue_cb_t callback;
24+
struct rte_mbuf *m;
2025
unsigned sent = 0;
26+
uintptr_t priv;
2127

2228
for (unsigned i = 0; i < n_objs; i++) {
23-
const struct control_output_mbuf_data *d = control_output_mbuf_data(objs[i]);
24-
if (control_queue_push(d->callback, objs[i], 0) < 0)
25-
rte_node_enqueue_x1(graph, node, ERROR, objs[i]);
26-
else {
29+
m = objs[i];
30+
callback = *RTE_MBUF_DYNFIELD(m, cq_callback_offset, control_queue_cb_t *);
31+
priv = *RTE_MBUF_DYNFIELD(m, cq_priv_offset, uintptr_t *);
32+
33+
if (control_queue_push(callback, m, priv) < 0) {
34+
rte_node_enqueue_x1(graph, node, ERROR, m);
35+
} else {
2736
sent++;
28-
if (gr_mbuf_is_traced(objs[i])) {
37+
if (gr_mbuf_is_traced(m)) {
2938
// FIXME racy: we are operating on mbufs already enqueued in ring
30-
gr_mbuf_trace_add(objs[i], node, 0);
31-
gr_mbuf_trace_finish(objs[i]);
39+
gr_mbuf_trace_add(m, node, 0);
40+
gr_mbuf_trace_finish(m);
3241
}
3342
}
3443
}
@@ -38,6 +47,25 @@ static uint16_t control_output_process(
3847
return n_objs;
3948
}
4049

50+
static void control_output_register(void) {
51+
const struct rte_mbuf_dynfield cb_params = {
52+
.name = "cq_callback",
53+
.size = sizeof(control_queue_cb_t),
54+
.align = alignof(control_queue_cb_t),
55+
};
56+
const struct rte_mbuf_dynfield priv_params = {
57+
.name = "cq_priv",
58+
.size = sizeof(uintptr_t),
59+
.align = alignof(uintptr_t),
60+
};
61+
cq_callback_offset = rte_mbuf_dynfield_register(&cb_params);
62+
if (cq_callback_offset < 0)
63+
ABORT("rte_mbuf_dynfield_register(cq_callback): %s", rte_strerror(rte_errno));
64+
cq_priv_offset = rte_mbuf_dynfield_register(&priv_params);
65+
if (cq_priv_offset < 0)
66+
ABORT("rte_mbuf_dynfield_register(cq_priv): %s", rte_strerror(rte_errno));
67+
}
68+
4169
static struct rte_node_register control_output_node = {
4270
.name = "control_output",
4371
.process = control_output_process,
@@ -50,6 +78,7 @@ static struct rte_node_register control_output_node = {
5078
static struct gr_node_info info = {
5179
.node = &control_output_node,
5280
.type = GR_NODE_T_CONTROL,
81+
.register_callback = control_output_register,
5382
};
5483

5584
GR_NODE_REGISTER(info);

modules/infra/datapath/gr_control_output.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
#pragma once
66

77
#include <gr_control_queue.h>
8-
#include <gr_mbuf.h>
98

10-
GR_MBUF_PRIV_DATA_TYPE(control_output_mbuf_data, {
11-
control_queue_cb_t callback;
12-
clock_t timestamp;
13-
uint8_t cb_data[GR_MBUF_PRIV_MAX_SIZE - 6 * sizeof(size_t)];
14-
});
9+
#include <rte_mbuf.h>
10+
11+
extern int cq_callback_offset;
12+
extern int cq_priv_offset;
13+
14+
static inline void
15+
control_output_set_cb(struct rte_mbuf *m, control_queue_cb_t cb, uintptr_t priv) {
16+
*RTE_MBUF_DYNFIELD(m, cq_callback_offset, control_queue_cb_t *) = cb;
17+
*RTE_MBUF_DYNFIELD(m, cq_priv_offset, uintptr_t *) = priv;
18+
}

0 commit comments

Comments
 (0)