af_xdp: refill rx rings when interface goes up 78/32278/7
authorBenoît Ganne <bganne@cisco.com>
Tue, 11 May 2021 11:19:56 +0000 (13:19 +0200)
committerDamjan Marion <dmarion@me.com>
Fri, 21 May 2021 21:07:02 +0000 (21:07 +0000)
If interrupt mode is configured through startup.conf exec script, the
input function will not be polled and the rx ring will never be filled.
Always refill the ring when interface goes up so it is ready to receive
packets.

Type: fix

Change-Id: I4cf22c8ae00638679f2e8650303a6fe916c1319b
Signed-off-by: Benoît Ganne <bganne@cisco.com>
src/plugins/af_xdp/af_xdp.h
src/plugins/af_xdp/device.c
src/plugins/af_xdp/input.c

index 91895ce..825a3fb 100644 (file)
@@ -164,6 +164,8 @@ typedef struct
 void af_xdp_create_if (vlib_main_t * vm, af_xdp_create_if_args_t * args);
 void af_xdp_delete_if (vlib_main_t * vm, af_xdp_device_t * ad);
 
+void af_xdp_device_input_refill (af_xdp_device_t *ad);
+
 extern vlib_node_registration_t af_xdp_input_node;
 extern vnet_device_class_t af_xdp_device_class;
 
index 5bc7e30..03a3053 100644 (file)
@@ -550,6 +550,7 @@ af_xdp_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
       vnet_hw_interface_set_flags (vnm, ad->hw_if_index,
                                   VNET_HW_INTERFACE_FLAG_LINK_UP);
       ad->flags |= AF_XDP_DEVICE_F_ADMIN_UP;
+      af_xdp_device_input_refill (ad);
     }
   else
     {
index dcbf5a4..98d841b 100644 (file)
@@ -83,8 +83,9 @@ af_xdp_device_input_refill_db (vlib_main_t * vm,
       !xsk_ring_prod__needs_wakeup (&rxq->fq))
     return;
 
-  vlib_error_count (vm, node->node_index, AF_XDP_INPUT_ERROR_SYSCALL_REQUIRED,
-                   1);
+  if (node)
+    vlib_error_count (vm, node->node_index,
+                     AF_XDP_INPUT_ERROR_SYSCALL_REQUIRED, 1);
 
   if (clib_spinlock_trylock_if_init (&rxq->syscall_lock))
     {
@@ -94,18 +95,19 @@ af_xdp_device_input_refill_db (vlib_main_t * vm,
       if (PREDICT_FALSE (ret < 0))
        {
          /* something bad is happening */
-         vlib_error_count (vm, node->node_index,
-                           AF_XDP_INPUT_ERROR_SYSCALL_FAILURES, 1);
+         if (node)
+           vlib_error_count (vm, node->node_index,
+                             AF_XDP_INPUT_ERROR_SYSCALL_FAILURES, 1);
          af_xdp_device_error (ad, "rx poll() failed");
        }
     }
 }
 
 static_always_inline void
-af_xdp_device_input_refill (vlib_main_t * vm,
-                           const vlib_node_runtime_t * node,
-                           af_xdp_device_t * ad, af_xdp_rxq_t * rxq,
-                           const int copy)
+af_xdp_device_input_refill_inline (vlib_main_t *vm,
+                                  const vlib_node_runtime_t *node,
+                                  af_xdp_device_t *ad, af_xdp_rxq_t *rxq,
+                                  const int copy)
 {
   __u64 *fill;
   const u32 size = rxq->fq.size;
@@ -313,7 +315,7 @@ af_xdp_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
      ad->hw_if_index, n_rx_packets, n_rx_bytes);
 
 refill:
-  af_xdp_device_input_refill (vm, node, ad, rxq, copy);
+  af_xdp_device_input_refill_inline (vm, node, ad, rxq, copy);
 
   return n_rx_packets;
 }
@@ -343,6 +345,18 @@ VLIB_NODE_FN (af_xdp_input_node) (vlib_main_t * vm,
   return n_rx;
 }
 
+#ifndef CLIB_MARCH_VARIANT
+void
+af_xdp_device_input_refill (af_xdp_device_t *ad)
+{
+  vlib_main_t *vm = vlib_get_main ();
+  af_xdp_rxq_t *rxq;
+  vec_foreach (rxq, ad->rxqs)
+    af_xdp_device_input_refill_inline (
+      vm, 0, ad, rxq, 0 == (ad->flags & AF_XDP_DEVICE_F_ZEROCOPY));
+}
+#endif /* CLIB_MARCH_VARIANT */
+
 /* *INDENT-OFF* */
 VLIB_REGISTER_NODE (af_xdp_input_node) = {
   .name = "af_xdp-input",