From 9a3973e3a36bfd4dd8dbffe130a92649fc1b73d3 Mon Sep 17 00:00:00 2001 From: Benoît Ganne Date: Fri, 2 Oct 2020 19:36:57 +0200 Subject: vlib: fix trace number accounting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using classifier to filter traces, not all packets will be traced. In that case, we should only count traced packets. Type: fix Change-Id: I87d1e217b580ebff8c6ade7860eb43950420ae78 Signed-off-by: Benoît Ganne --- src/vnet/bonding/device.c | 39 ++++++++++++++++-------------- src/vnet/devices/af_packet/node.c | 6 ++--- src/vnet/devices/virtio/node.c | 5 ++-- src/vnet/devices/virtio/vhost_user_input.c | 28 +++++++++++---------- src/vnet/ethernet/p2p_ethernet_input.c | 22 ++++++++++------- src/vnet/interface_output.c | 28 +++++++++++---------- src/vnet/ip/punt_node.c | 6 +++-- src/vnet/pg/input.c | 27 +++++++++++++-------- src/vnet/session/session_node.c | 26 +++++++++++--------- src/vnet/unix/tuntap.c | 8 +++--- 10 files changed, 108 insertions(+), 87 deletions(-) (limited to 'src/vnet') diff --git a/src/vnet/bonding/device.c b/src/vnet/bonding/device.c index bc185867c10..7ce5ad87bd7 100644 --- a/src/vnet/bonding/device.c +++ b/src/vnet/bonding/device.c @@ -651,25 +651,28 @@ bond_tx_trace (vlib_main_t * vm, vlib_node_runtime_t * node, bond_if_t * bif, while (n_trace > 0 && n_left > 0) { - bond_packet_trace_t *t0; - ethernet_header_t *eth; - u32 next0 = 0; - - vlib_trace_buffer (vm, node, next0, b[0], 0 /* follow_chain */ ); - vlib_set_trace_count (vm, node, --n_trace); - t0 = vlib_add_trace (vm, node, b[0], sizeof (*t0)); - eth = vlib_buffer_get_current (b[0]); - t0->ethernet = *eth; - t0->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_TX]; - if (!h) + if (PREDICT_TRUE + (vlib_trace_buffer (vm, node, 0, b[0], 0 /* follow_chain */ ))) { - t0->bond_sw_if_index = *vec_elt_at_index (bif->active_members, 0); - } - else - { - t0->bond_sw_if_index = - *vec_elt_at_index (bif->active_members, h[0]); - h++; + bond_packet_trace_t *t0; + ethernet_header_t *eth; + + vlib_set_trace_count (vm, node, --n_trace); + t0 = vlib_add_trace (vm, node, b[0], sizeof (*t0)); + eth = vlib_buffer_get_current (b[0]); + t0->ethernet = *eth; + t0->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_TX]; + if (!h) + { + t0->bond_sw_if_index = + *vec_elt_at_index (bif->active_members, 0); + } + else + { + t0->bond_sw_if_index = + *vec_elt_at_index (bif->active_members, h[0]); + h++; + } } b++; n_left--; diff --git a/src/vnet/devices/af_packet/node.c b/src/vnet/devices/af_packet/node.c index 196c0882bde..61d4ce2d1f5 100644 --- a/src/vnet/devices/af_packet/node.c +++ b/src/vnet/devices/af_packet/node.c @@ -310,11 +310,11 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, /* trace */ VLIB_BUFFER_TRACE_TRAJECTORY_INIT (first_b0); - if (PREDICT_FALSE (n_trace > 0)) + if (PREDICT_FALSE + (n_trace > 0 && vlib_trace_buffer (vm, node, next0, first_b0, + /* follow_chain */ 0))) { af_packet_input_trace_t *tr; - vlib_trace_buffer (vm, node, next0, first_b0, /* follow_chain */ - 0); vlib_set_trace_count (vm, node, --n_trace); tr = vlib_add_trace (vm, node, first_b0, sizeof (*tr)); tr->next_index = next0; diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c index 94bf097df55..91e788e4d28 100644 --- a/src/vnet/devices/virtio/node.c +++ b/src/vnet/devices/virtio/node.c @@ -388,11 +388,10 @@ virtio_device_input_gso_inline (vlib_main_t * vm, vlib_node_runtime_t * node, /* trace */ VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - if (PREDICT_FALSE (n_trace > 0)) + if (PREDICT_FALSE (n_trace > 0 && vlib_trace_buffer (vm, node, next0, b0, /* follow_chain */ + 1))) { virtio_input_trace_t *tr; - vlib_trace_buffer (vm, node, next0, b0, - /* follow_chain */ 1); vlib_set_trace_count (vm, node, --n_trace); tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); tr->next_index = next0; diff --git a/src/vnet/devices/virtio/vhost_user_input.c b/src/vnet/devices/virtio/vhost_user_input.c index da4937b733c..53230a61bc7 100644 --- a/src/vnet/devices/virtio/vhost_user_input.c +++ b/src/vnet/devices/virtio/vhost_user_input.c @@ -540,10 +540,10 @@ vhost_user_if_input (vlib_main_t * vm, b_head->total_length_not_including_first_buffer = 0; b_head->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID; - if (PREDICT_FALSE (n_trace)) + if (PREDICT_FALSE + (n_trace > 0 && vlib_trace_buffer (vm, node, next_index, b_head, + /* follow_chain */ 0))) { - vlib_trace_buffer (vm, node, next_index, b_head, - /* follow_chain */ 0); vhost_trace_t *t0 = vlib_add_trace (vm, node, b_head, sizeof (t0[0])); vhost_user_rx_trace (t0, vui, qid, b_head, txvq, last_avail_idx); @@ -1362,17 +1362,19 @@ vhost_user_if_input_packed (vlib_main_t * vm, vhost_user_main_t * vum, b = cpu->rx_buffers_pdesc; while (n_trace && left) { - vhost_trace_t *t0; - - vlib_trace_buffer (vm, node, next_index, b[0], - /* follow_chain */ 0); - t0 = vlib_add_trace (vm, node, b[0], sizeof (t0[0])); - b++; - vhost_user_rx_trace_packed (t0, vui, qid, txvq, last_used_idx); - last_used_idx = (last_used_idx + 1) & mask; - n_trace--; + if (PREDICT_TRUE + (vlib_trace_buffer + (vm, node, next_index, b[0], /* follow_chain */ 0))) + { + vhost_trace_t *t0; + t0 = vlib_add_trace (vm, node, b[0], sizeof (t0[0])); + vhost_user_rx_trace_packed (t0, vui, qid, txvq, last_used_idx); + last_used_idx = (last_used_idx + 1) & mask; + n_trace--; + vlib_set_trace_count (vm, node, n_trace); + } left--; - vlib_set_trace_count (vm, node, n_trace); + b++; } } diff --git a/src/vnet/ethernet/p2p_ethernet_input.c b/src/vnet/ethernet/p2p_ethernet_input.c index 7e5f7cadc0d..3e9589e0e19 100644 --- a/src/vnet/ethernet/p2p_ethernet_input.c +++ b/src/vnet/ethernet/p2p_ethernet_input.c @@ -119,11 +119,12 @@ VLIB_NODE_FN (p2p_ethernet_input_node) (vlib_main_t * vm, vnet_buffer (b0)->sw_if_index[VLIB_RX] = rx0; n_p2p_ethernet_packets += 1; - if (PREDICT_FALSE (n_trace > 0)) + if (PREDICT_FALSE + (n_trace > 0 + && vlib_trace_buffer (vm, node, next_index, b0, + 1 /* follow_chain */ ))) { p2p_ethernet_trace_t *t0; - vlib_trace_buffer (vm, node, next_index, b0, - 1 /* follow_chain */ ); vlib_set_trace_count (vm, node, --n_trace); t0 = vlib_add_trace (vm, node, b0, sizeof (*t0)); t0->sw_if_index = sw_if_index0; @@ -140,11 +141,12 @@ VLIB_NODE_FN (p2p_ethernet_input_node) (vlib_main_t * vm, vnet_buffer (b1)->sw_if_index[VLIB_RX] = rx1; n_p2p_ethernet_packets += 1; - if (PREDICT_FALSE (n_trace > 0)) + if (PREDICT_FALSE + (n_trace > 0 + && vlib_trace_buffer (vm, node, next_index, b1, + 1 /* follow_chain */ ))) { p2p_ethernet_trace_t *t1; - vlib_trace_buffer (vm, node, next_index, b1, - 1 /* follow_chain */ ); vlib_set_trace_count (vm, node, --n_trace); t1 = vlib_add_trace (vm, node, b1, sizeof (*t1)); t1->sw_if_index = sw_if_index1; @@ -195,11 +197,12 @@ VLIB_NODE_FN (p2p_ethernet_input_node) (vlib_main_t * vm, vnet_buffer (b0)->sw_if_index[VLIB_RX] = rx0; n_p2p_ethernet_packets += 1; - if (PREDICT_FALSE (n_trace > 0)) + if (PREDICT_FALSE + (n_trace > 0 + && vlib_trace_buffer (vm, node, next_index, b0, + 1 /* follow_chain */ ))) { p2p_ethernet_trace_t *t0; - vlib_trace_buffer (vm, node, next_index, b0, - 1 /* follow_chain */ ); vlib_set_trace_count (vm, node, --n_trace); t0 = vlib_add_trace (vm, node, b0, sizeof (*t0)); t0->sw_if_index = sw_if_index0; @@ -228,6 +231,7 @@ VLIB_NODE_FN (p2p_ethernet_input_node) (vlib_main_t * vm, vlib_node_increment_counter (vm, p2p_ethernet_input_node.index, P2PE_ERROR_HITS, n_p2p_ethernet_packets); + return frame->n_vectors; } diff --git a/src/vnet/interface_output.c b/src/vnet/interface_output.c index 52c07accc4a..65bc4a4b7ec 100644 --- a/src/vnet/interface_output.c +++ b/src/vnet/interface_output.c @@ -800,19 +800,21 @@ interface_drop_punt (vlib_main_t * vm, node->flags |= VLIB_NODE_FLAG_TRACE; while (n_trace && n_left) { - vlib_trace_buffer (vm, node, 0 /* next_index */ , - b[0], 0 /* follow chain */ ); - /* - * Here we have a wireshark dissector problem. - * Packets may be well-formed, or not. We - * must not blow chunks in any case. - * - * Try to produce trace records which will help - * folks understand what's going on. - */ - drop_catchup_trace (vm, node, b[0]); - - n_trace--; + if (PREDICT_TRUE + (vlib_trace_buffer (vm, node, 0 /* next_index */ , b[0], + 0 /* follow chain */ ))) + { + /* + * Here we have a wireshark dissector problem. + * Packets may be well-formed, or not. We + * must not blow chunks in any case. + * + * Try to produce trace records which will help + * folks understand what's going on. + */ + drop_catchup_trace (vm, node, b[0]); + n_trace--; + } n_left--; b++; } diff --git a/src/vnet/ip/punt_node.c b/src/vnet/ip/punt_node.c index 23c4cc453ea..90953e63704 100644 --- a/src/vnet/ip/punt_node.c +++ b/src/vnet/ip/punt_node.c @@ -573,10 +573,11 @@ punt_socket_rx_fd (vlib_main_t * vm, vlib_node_runtime_t * node, u32 fd) goto error; } - if (PREDICT_FALSE (n_trace > 0)) + if (PREDICT_FALSE + (n_trace > 0 + && vlib_trace_buffer (vm, node, next_index, b, 1 /* follow_chain */ ))) { punt_trace_t *t; - vlib_trace_buffer (vm, node, next_index, b, 1 /* follow_chain */ ); vlib_set_trace_count (vm, node, --n_trace); t = vlib_add_trace (vm, node, b, sizeof (*t)); t->sw_if_index = packetdesc.sw_if_index; @@ -590,6 +591,7 @@ punt_socket_rx_fd (vlib_main_t * vm, vlib_node_runtime_t * node, u32 fd) vlib_validate_buffer_enqueue_x1 (vm, node, next, to_next, n_left_to_next, bi, next_index); vlib_put_next_frame (vm, node, next, n_left_to_next); + return 1; error: diff --git a/src/vnet/pg/input.c b/src/vnet/pg/input.c index c8f3d9f01d8..d5cf929331a 100644 --- a/src/vnet/pg/input.c +++ b/src/vnet/pg/input.c @@ -1454,15 +1454,16 @@ format_pg_input_trace (u8 * s, va_list * va) return s; } -static void +static int pg_input_trace (pg_main_t * pg, vlib_node_runtime_t * node, u32 stream_index, u32 next_index, - u32 * buffers, u32 n_buffers) + u32 * buffers, const u32 n_buffers, const u32 n_trace) { vlib_main_t *vm = vlib_get_main (); u32 *b, n_left; + u32 n_trace0 = 0, n_trace1 = 0; - n_left = n_buffers; + n_left = clib_min (n_buffers, n_trace); b = buffers; while (n_left >= 2) @@ -1479,8 +1480,10 @@ pg_input_trace (pg_main_t * pg, b0 = vlib_get_buffer (vm, bi0); b1 = vlib_get_buffer (vm, bi1); - vlib_trace_buffer (vm, node, next_index, b0, /* follow_chain */ 1); - vlib_trace_buffer (vm, node, next_index, b1, /* follow_chain */ 1); + n_trace0 += + vlib_trace_buffer (vm, node, next_index, b0, /* follow_chain */ 1); + n_trace1 += + vlib_trace_buffer (vm, node, next_index, b1, /* follow_chain */ 1); t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0])); t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0])); @@ -1517,7 +1520,8 @@ pg_input_trace (pg_main_t * pg, b0 = vlib_get_buffer (vm, bi0); - vlib_trace_buffer (vm, node, next_index, b0, /* follow_chain */ 1); + n_trace0 += + vlib_trace_buffer (vm, node, next_index, b0, /* follow_chain */ 1); t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0])); t0->stream_index = stream_index; @@ -1528,6 +1532,8 @@ pg_input_trace (pg_main_t * pg, clib_memcpy_fast (t0->buffer.pre_data, b0->data, sizeof (t0->buffer.pre_data)); } + + return n_trace - n_trace0 - n_trace1; } static_always_inline void @@ -1714,11 +1720,12 @@ pg_generate_packets (vlib_node_runtime_t * node, } n_trace = vlib_get_trace_count (vm, node); - if (n_trace > 0) + if (PREDICT_FALSE (n_trace > 0)) { - u32 n = clib_min (n_trace, n_this_frame); - pg_input_trace (pg, node, s - pg->streams, next_index, to_next, n); - vlib_set_trace_count (vm, node, n_trace - n); + n_trace = + pg_input_trace (pg, node, s - pg->streams, next_index, to_next, + n_this_frame, n_trace); + vlib_set_trace_count (vm, node, n_trace); } n_packets_to_generate -= n_this_frame; n_packets_generated += n_this_frame; diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c index ec2f936ba60..8a350d4549f 100644 --- a/src/vnet/session/session_node.c +++ b/src/vnet/session/session_node.c @@ -569,19 +569,23 @@ session_tx_trace_frame (vlib_main_t * vm, vlib_node_runtime_t * node, u32 next_index, u32 * to_next, u16 n_segs, session_t * s, u32 n_trace) { - session_queue_trace_t *t; - vlib_buffer_t *b; - int i; - - for (i = 0; i < clib_min (n_trace, n_segs); i++) + while (n_trace && n_segs) { - b = vlib_get_buffer (vm, to_next[i]); - vlib_trace_buffer (vm, node, next_index, b, 1 /* follow_chain */ ); - t = vlib_add_trace (vm, node, b, sizeof (*t)); - t->session_index = s->session_index; - t->server_thread_index = s->thread_index; + vlib_buffer_t *b = vlib_get_buffer (vm, to_next[0]); + if (PREDICT_TRUE + (vlib_trace_buffer + (vm, node, next_index, b, 1 /* follow_chain */ ))) + { + session_queue_trace_t *t = + vlib_add_trace (vm, node, b, sizeof (*t)); + t->session_index = s->session_index; + t->server_thread_index = s->thread_index; + n_trace--; + } + to_next++; + n_segs--; } - vlib_set_trace_count (vm, node, n_trace - i); + vlib_set_trace_count (vm, node, n_trace); } always_inline void diff --git a/src/vnet/unix/tuntap.c b/src/vnet/unix/tuntap.c index 72c4f73e6df..6834ee88c99 100644 --- a/src/vnet/unix/tuntap.c +++ b/src/vnet/unix/tuntap.c @@ -378,11 +378,9 @@ tuntap_rx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) vlib_set_next_frame_buffer (vm, node, next_index, bi); - if (n_trace > 0) - { - vlib_trace_buffer (vm, node, next_index, b, /* follow_chain */ 1); - vlib_set_trace_count (vm, node, n_trace - 1); - } + if (PREDICT_FALSE (n_trace > 0 && vlib_trace_buffer (vm, node, next_index, b, /* follow_chain */ + 1))) + vlib_set_trace_count (vm, node, n_trace - 1); } return 1; -- cgit 1.2.3-korg