vlib: fix trace number accounting
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 <bganne@cisco.com>
diff --git a/src/vnet/bonding/device.c b/src/vnet/bonding/device.c
index bc18586..7ce5ad8 100644
--- a/src/vnet/bonding/device.c
+++ b/src/vnet/bonding/device.c
@@ -651,25 +651,28 @@
while (n_trace > 0 && n_left > 0)
{
- bond_packet_trace_t *t0;
- ethernet_header_t *eth;
- u32 next0 = 0;
+ if (PREDICT_TRUE
+ (vlib_trace_buffer (vm, node, 0, b[0], 0 /* follow_chain */ )))
+ {
+ bond_packet_trace_t *t0;
+ ethernet_header_t *eth;
- 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)
- {
- 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++;
+ 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 196c088..61d4ce2 100644
--- a/src/vnet/devices/af_packet/node.c
+++ b/src/vnet/devices/af_packet/node.c
@@ -310,11 +310,11 @@
/* 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 94bf097..91e788e 100644
--- a/src/vnet/devices/virtio/node.c
+++ b/src/vnet/devices/virtio/node.c
@@ -388,11 +388,10 @@
/* 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 da4937b..53230a6 100644
--- a/src/vnet/devices/virtio/vhost_user_input.c
+++ b/src/vnet/devices/virtio/vhost_user_input.c
@@ -540,10 +540,10 @@
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 @@
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 7e5f7ca..3e9589e 100644
--- a/src/vnet/ethernet/p2p_ethernet_input.c
+++ b/src/vnet/ethernet/p2p_ethernet_input.c
@@ -119,11 +119,12 @@
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 @@
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 @@
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_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 52c07ac..65bc4a4 100644
--- a/src/vnet/interface_output.c
+++ b/src/vnet/interface_output.c
@@ -800,19 +800,21 @@
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 23c4cc4..90953e6 100644
--- a/src/vnet/ip/punt_node.c
+++ b/src/vnet/ip/punt_node.c
@@ -573,10 +573,11 @@
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 @@
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 c8f3d9f..d5cf929 100644
--- a/src/vnet/pg/input.c
+++ b/src/vnet/pg/input.c
@@ -1454,15 +1454,16 @@
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 @@
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 @@
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 @@
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 @@
}
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 ec2f936..8a350d4 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -569,19 +569,23 @@
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 72c4f73..6834ee8 100644
--- a/src/vnet/unix/tuntap.c
+++ b/src/vnet/unix/tuntap.c
@@ -378,11 +378,9 @@
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;