diff options
author | Mohammed Hawari <mohammed@hawari.fr> | 2021-09-06 11:48:17 +0200 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2021-09-07 17:14:36 +0000 |
commit | eed6fc9a98e2574a9f39caec512a072e60b0bdb5 (patch) | |
tree | 219e45be5232c491ffe8faee6d13962ac503008f | |
parent | 0b42ac565b970c186a9ad734f980b440f56fb25b (diff) |
devices: restore regular af-packet tx path
This change restores the af_packet tx path prior
in use prior to Change
Idf0bdd88990254a614962c2f7bc3e0292ccfd61a but
fixes the stalling issue by ensuring that the next
tx frame pointer is only incremented when a new tx
frame is used. This change also enables the
af_packet PACKET_QDISC_BYPASS option, for better
performance.
Change-Id: I65dde648ed66d21654847a900ceda5a8980ae6ec
Type: improvement
Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
-rw-r--r-- | src/vnet/devices/af_packet/af_packet.c | 9 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/device.c | 40 |
2 files changed, 28 insertions, 21 deletions
diff --git a/src/vnet/devices/af_packet/af_packet.c b/src/vnet/devices/af_packet/af_packet.c index 76677a43092..cace3450e3e 100644 --- a/src/vnet/devices/af_packet/af_packet.c +++ b/src/vnet/devices/af_packet/af_packet.c @@ -192,6 +192,15 @@ create_packet_v2_sock (int host_if_index, tpacket_req_t * rx_req, goto error; } + if (setsockopt (*fd, SOL_PACKET, PACKET_QDISC_BYPASS, &opt, sizeof (opt)) < + 0) + { + vlib_log_debug (apm->log_class, + "Failed to set qdisc bypass error " + "handling option: %s (errno %d)", + strerror (errno), errno); + } + if (setsockopt (*fd, SOL_PACKET, PACKET_RX_RING, rx_req, req_sz) < 0) { vlib_log_debug (apm->log_class, diff --git a/src/vnet/devices/af_packet/device.c b/src/vnet/devices/af_packet/device.c index b6b99a0465c..8a6ff1de649 100644 --- a/src/vnet/devices/af_packet/device.c +++ b/src/vnet/devices/af_packet/device.c @@ -149,17 +149,12 @@ VNET_DEVICE_CLASS_TX_FN (af_packet_device_class) (vlib_main_t * vm, u32 bi = buffers[0]; buffers++; - nextframe: tph = (struct tpacket2_hdr *) (block_start + tx_frame * frame_size); if (PREDICT_FALSE (tph->tp_status & (TP_STATUS_SEND_REQUEST | TP_STATUS_SENDING))) { - tx_frame = (tx_frame + 1) % frame_num; frame_not_ready++; - /* check if we've exhausted the ring */ - if (PREDICT_FALSE (frame_not_ready + n_sent == frame_num)) - break; - goto nextframe; + goto next; } do @@ -180,6 +175,7 @@ VNET_DEVICE_CLASS_TX_FN (af_packet_device_class) (vlib_main_t * vm, tx_frame = (tx_frame + 1) % frame_num; + next: /* check if we've exhausted the ring */ if (PREDICT_FALSE (frame_not_ready + n_sent == frame_num)) break; @@ -187,22 +183,24 @@ VNET_DEVICE_CLASS_TX_FN (af_packet_device_class) (vlib_main_t * vm, CLIB_MEMORY_BARRIER (); - apif->next_tx_frame = tx_frame; - if (PREDICT_TRUE (n_sent)) - if (PREDICT_FALSE (sendto (apif->fd, NULL, 0, MSG_DONTWAIT, NULL, 0) == - -1)) - { - /* Uh-oh, drop & move on, but count whether it was fatal or not. - * Note that we have no reliable way to properly determine the - * disposition of the packets we just enqueued for delivery. - */ - vlib_error_count (vm, node->node_index, - unix_error_is_fatal (errno) ? - AF_PACKET_TX_ERROR_TXRING_FATAL : - AF_PACKET_TX_ERROR_TXRING_EAGAIN, - n_sent); - } + { + apif->next_tx_frame = tx_frame; + + if (PREDICT_FALSE (sendto (apif->fd, NULL, 0, MSG_DONTWAIT, NULL, 0) == + -1)) + { + /* Uh-oh, drop & move on, but count whether it was fatal or not. + * Note that we have no reliable way to properly determine the + * disposition of the packets we just enqueued for delivery. + */ + vlib_error_count (vm, node->node_index, + unix_error_is_fatal (errno) ? + AF_PACKET_TX_ERROR_TXRING_FATAL : + AF_PACKET_TX_ERROR_TXRING_EAGAIN, + n_sent); + } + } clib_spinlock_unlock_if_init (&apif->lockp); |