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/plugins/af_xdp/input.c b/src/plugins/af_xdp/input.c
index c164c25..2cf121f 100644
--- a/src/plugins/af_xdp/input.c
+++ b/src/plugins/af_xdp/input.c
@@ -46,23 +46,23 @@
u32 n_left, const u32 * bi, u32 next_index,
u32 hw_if_index)
{
- u32 n_trace;
+ u32 n_trace = vlib_get_trace_count (vm, node);
- if (PREDICT_TRUE (0 == (n_trace = vlib_get_trace_count (vm, node))))
+ if (PREDICT_TRUE (0 == n_trace))
return;
while (n_trace && n_left)
{
- vlib_buffer_t *b;
- af_xdp_input_trace_t *tr;
- b = vlib_get_buffer (vm, bi[0]);
- vlib_trace_buffer (vm, node, next_index, b,
- /* follow_chain */ 0);
- tr = vlib_add_trace (vm, node, b, sizeof (*tr));
- tr->next_index = next_index;
- tr->hw_if_index = hw_if_index;
-
- n_trace--;
+ vlib_buffer_t *b = vlib_get_buffer (vm, bi[0]);
+ if (PREDICT_TRUE
+ (vlib_trace_buffer (vm, node, next_index, b, /* follow_chain */ 0)))
+ {
+ af_xdp_input_trace_t *tr =
+ vlib_add_trace (vm, node, b, sizeof (*tr));
+ tr->next_index = next_index;
+ tr->hw_if_index = hw_if_index;
+ n_trace--;
+ }
n_left--;
bi++;
}
diff --git a/src/plugins/avf/input.c b/src/plugins/avf/input.c
index 9d677ab..4e4f116 100644
--- a/src/plugins/avf/input.c
+++ b/src/plugins/avf/input.c
@@ -383,20 +383,24 @@
while (n_trace && n_left)
{
- vlib_buffer_t *b;
- avf_input_trace_t *tr;
- b = vlib_get_buffer (vm, bi[0]);
- vlib_trace_buffer (vm, node, next_index, b, /* follow_chain */ 0);
- tr = vlib_add_trace (vm, node, b, sizeof (*tr));
- tr->next_index = next_index;
- tr->qid = qid;
- tr->hw_if_index = ad->hw_if_index;
- tr->qw1s[0] = ptd->qw1s[i];
- for (j = 1; j < AVF_RX_MAX_DESC_IN_CHAIN; j++)
- tr->qw1s[j] = ptd->tails[i].qw1s[j - 1];
+ vlib_buffer_t *b = vlib_get_buffer (vm, bi[0]);
+ if (PREDICT_TRUE
+ (vlib_trace_buffer
+ (vm, node, next_index, b, /* follow_chain */ 0)))
+ {
+ avf_input_trace_t *tr =
+ vlib_add_trace (vm, node, b, sizeof (*tr));
+ tr->next_index = next_index;
+ tr->qid = qid;
+ tr->hw_if_index = ad->hw_if_index;
+ tr->qw1s[0] = ptd->qw1s[i];
+ for (j = 1; j < AVF_RX_MAX_DESC_IN_CHAIN; j++)
+ tr->qw1s[j] = ptd->tails[i].qw1s[j - 1];
+
+ n_trace--;
+ }
/* next */
- n_trace--;
n_left--;
bi++;
i++;
diff --git a/src/plugins/dpdk/device/node.c b/src/plugins/dpdk/device/node.c
index 256c399..e7d836f 100644
--- a/src/plugins/dpdk/device/node.c
+++ b/src/plugins/dpdk/device/node.c
@@ -417,21 +417,28 @@
b0 = vlib_get_buffer (vm, buffers[0]);
if (single_next == 0)
next_index = next[0];
- vlib_trace_buffer (vm, node, next_index, b0, /* follow_chain */ 0);
- dpdk_rx_trace_t *t0 = vlib_add_trace (vm, node, b0, sizeof t0[0]);
- t0->queue_index = queue_id;
- t0->device_index = xd->device_index;
- t0->buffer_index = vlib_get_buffer_index (vm, b0);
+ if (PREDICT_TRUE
+ (vlib_trace_buffer
+ (vm, node, next_index, b0, /* follow_chain */ 0)))
+ {
- clib_memcpy_fast (&t0->mb, mb[0], sizeof t0->mb);
- clib_memcpy_fast (&t0->buffer, b0,
- sizeof b0[0] - sizeof b0->pre_data);
- clib_memcpy_fast (t0->buffer.pre_data, b0->data,
- sizeof t0->buffer.pre_data);
- clib_memcpy_fast (&t0->data, mb[0]->buf_addr + mb[0]->data_off,
- sizeof t0->data);
- n_trace--;
+ dpdk_rx_trace_t *t0 =
+ vlib_add_trace (vm, node, b0, sizeof t0[0]);
+ t0->queue_index = queue_id;
+ t0->device_index = xd->device_index;
+ t0->buffer_index = vlib_get_buffer_index (vm, b0);
+
+ clib_memcpy_fast (&t0->mb, mb[0], sizeof t0->mb);
+ clib_memcpy_fast (&t0->buffer, b0,
+ sizeof b0[0] - sizeof b0->pre_data);
+ clib_memcpy_fast (t0->buffer.pre_data, b0->data,
+ sizeof t0->buffer.pre_data);
+ clib_memcpy_fast (&t0->data, mb[0]->buf_addr + mb[0]->data_off,
+ sizeof t0->data);
+ n_trace--;
+ }
+
n_left--;
buffers++;
mb++;
diff --git a/src/plugins/dpdk/ipsec/crypto_node.c b/src/plugins/dpdk/ipsec/crypto_node.c
index 76e57a3..893848c 100644
--- a/src/plugins/dpdk/ipsec/crypto_node.c
+++ b/src/plugins/dpdk/ipsec/crypto_node.c
@@ -106,14 +106,16 @@
b0 = vlib_get_buffer (vm, bi);
- vlib_trace_buffer (vm, node, next, b0, /* follow_chain */ 0);
+ if (PREDICT_TRUE
+ (vlib_trace_buffer (vm, node, next, b0, /* follow_chain */ 0)))
+ {
+ dpdk_crypto_input_trace_t *tr =
+ vlib_add_trace (vm, node, b0, sizeof (*tr));
+ tr->dev_id = dev_id;
+ tr->next_index = next;
+ n_trace--;
+ }
- dpdk_crypto_input_trace_t *tr =
- vlib_add_trace (vm, node, b0, sizeof (*tr));
- tr->dev_id = dev_id;
- tr->next_index = next;
-
- n_trace--;
n_left--;
nexts++;
bis++;
diff --git a/src/plugins/memif/node.c b/src/plugins/memif/node.c
index 82a7cbc..506d88a 100644
--- a/src/plugins/memif/node.c
+++ b/src/plugins/memif/node.c
@@ -92,10 +92,10 @@
{
VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
- if (PREDICT_TRUE (b != 0))
+ if (PREDICT_TRUE
+ (b != 0 && vlib_trace_buffer (vm, node, next, b, /* follow_chain */ 0)))
{
memif_input_trace_t *tr;
- vlib_trace_buffer (vm, node, next, b, /* follow_chain */ 0);
vlib_set_trace_count (vm, node, --(*n_tracep));
tr = vlib_add_trace (vm, node, b, sizeof (*tr));
tr->next_index = next;
@@ -484,14 +484,17 @@
if (mode != MEMIF_INTERFACE_MODE_ETHERNET)
ni = next[0];
b = vlib_get_buffer (vm, bi[0]);
- vlib_trace_buffer (vm, node, ni, b, /* follow_chain */ 0);
- tr = vlib_add_trace (vm, node, b, sizeof (*tr));
- tr->next_index = ni;
- tr->hw_if_index = mif->hw_if_index;
- tr->ring = qid;
+ if (PREDICT_TRUE
+ (vlib_trace_buffer (vm, node, ni, b, /* follow_chain */ 0)))
+ {
+ tr = vlib_add_trace (vm, node, b, sizeof (*tr));
+ tr->next_index = ni;
+ tr->hw_if_index = mif->hw_if_index;
+ tr->ring = qid;
+ n_trace--;
+ }
/* next */
- n_trace--;
n_left--;
bi++;
next++;
diff --git a/src/plugins/rdma/input.c b/src/plugins/rdma/input.c
index 1d267ad..52e921d 100644
--- a/src/plugins/rdma/input.c
+++ b/src/plugins/rdma/input.c
@@ -225,30 +225,27 @@
const u32 * bi, u32 next_index, u16 * cqe_flags,
int is_mlx5dv)
{
- u32 n_trace, i;
+ u32 n_trace = vlib_get_trace_count (vm, node);
- if (PREDICT_TRUE (0 == (n_trace = vlib_get_trace_count (vm, node))))
+ if (PREDICT_TRUE (0 == n_trace))
return;
- i = 0;
while (n_trace && n_left)
{
- vlib_buffer_t *b;
- rdma_input_trace_t *tr;
- b = vlib_get_buffer (vm, bi[0]);
- vlib_trace_buffer (vm, node, next_index, b,
- /* follow_chain */ 0);
- tr = vlib_add_trace (vm, node, b, sizeof (*tr));
- tr->next_index = next_index;
- tr->hw_if_index = rd->hw_if_index;
- tr->cqe_flags = is_mlx5dv ? clib_net_to_host_u16 (cqe_flags[0]) : 0;
-
+ vlib_buffer_t *b = vlib_get_buffer (vm, bi[0]);
+ if (PREDICT_TRUE
+ (vlib_trace_buffer (vm, node, next_index, b, /* follow_chain */ 0)))
+ {
+ rdma_input_trace_t *tr = vlib_add_trace (vm, node, b, sizeof (*tr));
+ tr->next_index = next_index;
+ tr->hw_if_index = rd->hw_if_index;
+ tr->cqe_flags = is_mlx5dv ? clib_net_to_host_u16 (cqe_flags[0]) : 0;
+ n_trace--;
+ }
/* next */
- n_trace--;
n_left--;
cqe_flags++;
bi++;
- i++;
}
vlib_set_trace_count (vm, node, n_trace);
}
diff --git a/src/plugins/vmxnet3/input.c b/src/plugins/vmxnet3/input.c
index f182409..bed4c1e 100644
--- a/src/plugins/vmxnet3/input.c
+++ b/src/plugins/vmxnet3/input.c
@@ -418,17 +418,18 @@
next = nexts;
while (n_trace && n_left)
{
- vlib_buffer_t *b;
- vmxnet3_input_trace_t *tr;
-
- b = vlib_get_buffer (vm, bi[0]);
- vlib_trace_buffer (vm, node, next[0], b, /* follow_chain */ 0);
- tr = vlib_add_trace (vm, node, b, sizeof (*tr));
- tr->next_index = next[0];
- tr->hw_if_index = vd->hw_if_index;
- tr->buffer = *b;
-
- n_trace--;
+ vlib_buffer_t *b = vlib_get_buffer (vm, bi[0]);
+ if (PREDICT_TRUE
+ (vlib_trace_buffer
+ (vm, node, next[0], b, /* follow_chain */ 0)))
+ {
+ vmxnet3_input_trace_t *tr =
+ vlib_add_trace (vm, node, b, sizeof (*tr));
+ tr->next_index = next[0];
+ tr->hw_if_index = vd->hw_if_index;
+ tr->buffer = *b;
+ n_trace--;
+ }
n_left--;
bi++;
next++;
diff --git a/src/vlib/handoff_trace.c b/src/vlib/handoff_trace.c
index d268b56..964c095 100644
--- a/src/vlib/handoff_trace.c
+++ b/src/vlib/handoff_trace.c
@@ -96,7 +96,7 @@
};
/* *INDENT-ON* */
-void
+int
vlib_add_handoff_trace (vlib_main_t * vm, vlib_buffer_t * b)
{
u32 prev_thread = vlib_buffer_get_trace_thread (b);
@@ -105,13 +105,15 @@
vlib_node_runtime_t *node
= vlib_node_get_runtime (vm, handoff_trace_node.index);
- vlib_trace_buffer (vm, node, 0 /* fake next frame index */ ,
- b, 1 /* folllow chain */ );
+ if (PREDICT_FALSE
+ (!vlib_trace_buffer
+ (vm, node, 0 /* fake next frame index */ , b, 1 /* follow chain */ )))
+ return 0;
t = vlib_add_trace (vm, node, b, sizeof (*t));
-
t->prev_thread = prev_thread;
t->prev_trace_index = prev_trace_index;
+ return 1;
}
diff --git a/src/vlib/trace_funcs.h b/src/vlib/trace_funcs.h
index fba55bf..8dd5310 100644
--- a/src/vlib/trace_funcs.h
+++ b/src/vlib/trace_funcs.h
@@ -49,7 +49,7 @@
vlib_buffer_get_trace_index (b)));
}
-void vlib_add_handoff_trace (vlib_main_t * vm, vlib_buffer_t * b);
+int vlib_add_handoff_trace (vlib_main_t * vm, vlib_buffer_t * b);
always_inline void *
vlib_add_trace_inline (vlib_main_t * vm,
@@ -80,7 +80,8 @@
/* Are we trying to trace a handoff case? */
if (PREDICT_FALSE (vlib_buffer_get_trace_thread (b) != vm->thread_index))
- vlib_add_handoff_trace (vm, b);
+ if (PREDICT_FALSE (!vlib_add_handoff_trace (vm, b)))
+ return vnet_trace_placeholder;
vlib_validate_trace (tm, b);
@@ -131,8 +132,13 @@
u32 classify_table_index, int func);
-/* Mark buffer as traced and allocate trace buffer. */
-always_inline void
+/*
+ * Mark buffer as traced and allocate trace buffer.
+ * return 1 if the buffer is successfully traced, 0 if not
+ * A buffer might not be traced if tracing is off or if the packet did not
+ * match the filter.
+ */
+always_inline __clib_warn_unused_result int
vlib_trace_buffer (vlib_main_t * vm,
vlib_node_runtime_t * r,
u32 next_index, vlib_buffer_t * b, int follow_chain)
@@ -141,7 +147,7 @@
vlib_trace_header_t **h;
if (PREDICT_FALSE (tm->trace_enable == 0))
- return;
+ return 0;
/* Classifier filter in use? */
if (PREDICT_FALSE (vlib_global_main.trace_filter.trace_filter_enable))
@@ -150,7 +156,7 @@
if (vnet_is_packet_traced
(b, vlib_global_main.trace_filter.trace_classify_table_index,
0 /* full classify */ ) != 1)
- return;
+ return 0;
}
/*
@@ -178,6 +184,8 @@
(vm->thread_index, h - tm->trace_buffer_pool);
}
while (follow_chain && (b = vlib_get_next_buffer (vm, b)));
+
+ return 1;
}
always_inline void
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;