while (cqe->phase != phase)
{
- vlib_process_suspend (vm, suspend_time);
+ vnet_dev_process_suspend (vm, suspend_time);
suspend_time *= 2;
if (suspend_time > 1e-3)
{
break;
if (i++ == 20)
return ena_err (dev, VNET_DEV_ERR_BUS, "failed to initiate reset");
- vlib_process_suspend (vm, 0.001);
+ vnet_dev_process_suspend (vm, 0.001);
}
ena_reg_write (dev, ENA_REG_DEV_CTL, &(ena_reg_dev_ctl_t){});
break;
if (i++ == 20)
return ena_err (dev, VNET_DEV_ERR_BUS, "failed to complete reset");
- vlib_process_suspend (vm, 0.001);
+ vnet_dev_process_suspend (vm, 0.001);
}
ena_reg_read (dev, ENA_REG_VERSION, &ver);
return VNET_DEV_ERR_TIMEOUT;
}
- vlib_process_suspend (vm, suspend_time);
+ vnet_dev_process_suspend (vm, suspend_time);
suspend_time *= 2;
}
}
if (vlib_time_now (vm) - t0 > timeout)
return 0;
- vlib_process_suspend (vm, suspend_time);
+ vnet_dev_process_suspend (vm, suspend_time);
suspend_time *= 2;
}
{
if (n_tries-- == 0)
return VNET_DEV_ERR_TIMEOUT;
- vlib_process_suspend (vm, 0.02);
+ vnet_dev_process_suspend (vm, 0.02);
}
while ((iavf_reg_read (ad, IAVF_VFGEN_RSTAT) & 3) != 2);
return err;
}
-uword
-dev_config_process_node_fn (vlib_main_t *vm, vlib_node_runtime_t *rt,
- vlib_frame_t *f)
+static clib_error_t *
+devices_config (vlib_main_t *vm, unformat_input_t *input)
{
- vnet_dev_main_t *dm = &vnet_dev_main;
vnet_dev_driver_name_t driver_name;
- unformat_input_t input;
clib_error_t *err = 0;
- if (dm->startup_config == 0)
- return 0;
-
- unformat_init_vector (&input, dm->startup_config);
- dm->startup_config = 0;
-
- while (!err && unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
+ while (!err && unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
unformat_input_t sub_input;
vnet_dev_device_id_t device_id;
- if (unformat (&input, "dev %U %U", unformat_c_string_array, device_id,
+ if (unformat (input, "dev %U %U", unformat_c_string_array, device_id,
sizeof (device_id), unformat_vlib_cli_sub_input,
&sub_input))
{
err = vnet_dev_config_one_device (vm, &sub_input, device_id);
unformat_free (&sub_input);
}
- else if (unformat (&input, "dev %U", unformat_c_string_array, device_id,
+ else if (unformat (input, "dev %U", unformat_c_string_array, device_id,
sizeof (device_id)))
{
unformat_input_t no_input = {};
err = vnet_dev_config_one_device (vm, &no_input, device_id);
unformat_free (&no_input);
}
- else if (unformat (&input, "driver %U %U", unformat_c_string_array,
+ else if (unformat (input, "driver %U %U", unformat_c_string_array,
driver_name, sizeof (driver_name),
unformat_vlib_cli_sub_input, &sub_input))
{
format_unformat_error, &input);
}
- unformat_free (&input);
-
- if (err)
- {
- log_err (0, "%U", format_clib_error, err);
- clib_error_free (err);
- }
-
- vlib_node_set_state (vm, rt->node_index, VLIB_NODE_STATE_DISABLED);
- vlib_node_rename (vm, rt->node_index, "deleted-%u", rt->node_index);
- vec_add1 (dm->free_process_node_indices, rt->node_index);
- return 0;
-}
+ unformat_free (input);
-VLIB_REGISTER_NODE (dev_config_process_node) = {
- .function = dev_config_process_node_fn,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "dev-config",
-};
-
-static clib_error_t *
-devices_config (vlib_main_t *vm, unformat_input_t *input)
-{
- vnet_dev_main_t *dm = &vnet_dev_main;
- uword c;
-
- while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
- vec_add1 (dm->startup_config, c);
-
- return 0;
+ return err;
}
VLIB_CONFIG_FUNCTION (devices_config, "devices");
temp_space_sz = r->runtime_temp_space_sz;
}
- if (dm->startup_config)
- log_debug (0, "startup config: %v", dm->startup_config);
-
vec_free (drv);
if (temp_space_sz > 0)
u32 *free_rx_node_indices;
uword *device_index_by_id;
- u8 *startup_config;
u16 next_rx_queue_thread;
u8 eth_port_rx_feature_arc_index;
+ u8 main_loop_running;
} vnet_dev_main_t;
extern vnet_dev_main_t vnet_dev_main;
static_always_inline void
vnet_dev_validate (vlib_main_t *vm, vnet_dev_t *dev)
{
- ASSERT (dev->process_node_index == vlib_get_current_process_node_index (vm));
+ vnet_dev_main_t *dm = &vnet_dev_main;
+ ASSERT (!dm->main_loop_running ||
+ dev->process_node_index == vlib_get_current_process_node_index (vm));
ASSERT (vm->thread_index == 0);
}
static_always_inline void
vnet_dev_port_validate (vlib_main_t *vm, vnet_dev_port_t *port)
{
- ASSERT (port->dev->process_node_index ==
- vlib_get_current_process_node_index (vm));
+ vnet_dev_main_t *dm = &vnet_dev_main;
+ ASSERT (!dm->main_loop_running ||
+ port->dev->process_node_index ==
+ vlib_get_current_process_node_index (vm));
ASSERT (vm->thread_index == 0);
}
return arg->val_set ? arg->val.string : arg->default_val.string;
}
+static_always_inline void
+vnet_dev_process_suspend (vlib_main_t *vm, f64 t)
+{
+ if (!vnet_dev_main.main_loop_running)
+ {
+ t += vlib_time_now (vm);
+
+ while (vlib_time_now (vm) < t)
+ CLIB_PAUSE ();
+ }
+ else
+ vlib_process_suspend (vm, t);
+}
+
+static_always_inline void
+vnet_dev_process_yield (vlib_main_t *vm, f64 t)
+{
+ if (vnet_dev_main.main_loop_running)
+ vlib_process_yield (vm);
+}
+
#endif /* _VNET_DEV_FUNCS_H_ */
vnet_dev_process_event_send_and_wait (vlib_main_t *vm, vnet_dev_t *dev,
vnet_dev_event_data_t *ed)
{
- ed->calling_process_index = vlib_get_current_process_node_index (vm);
+ vnet_dev_main_t *dm = &vnet_dev_main;
vnet_dev_rv_t rv = VNET_DEV_ERR_PROCESS_REPLY;
ed->reply_needed = 1;
+ if (!dm->main_loop_running)
+ {
+ vnet_dev_process_one_event (vm, dev, ed);
+ rv = ed->rv;
+ goto done;
+ }
+
+ ed->calling_process_index = vlib_get_current_process_node_index (vm);
+
if (ed->calling_process_index == dev->process_node_index)
{
vnet_dev_process_one_event (vm, dev, ed);
vnet_dev_process_event_send (vm, port->dev, ed);
}
+
+static clib_error_t *
+vnet_dev_main_loop_init (vlib_main_t *vm)
+{
+ vnet_dev_main_t *dm = &vnet_dev_main;
+ dm->main_loop_running = 1;
+ return 0;
+}
+
+VLIB_MAIN_LOOP_ENTER_FUNCTION (vnet_dev_main_loop_init);