Currently, IPC API will silently ignore unsupported IPC.
Fix the API call and its callers to explicitly handle
unsupported IPC cases.
For primary processes, it is OK to not have IPC because
there may not be any secondary processes in the first place,
and there are valid use cases that disable IPC support, so
all primary process usages are fixed up to ignore IPC
failures.
For secondary processes, IPC will be crucial, so leave all
of the error handling as is.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
if (rte_mp_action_register(VDEV_MP_KEY, vdev_action) < 0 &&
rte_errno != EEXIST) {
+ /* for primary, unsupported IPC is not an error */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
+ rte_errno == ENOTSUP)
+ goto scan;
VDEV_LOG(ERR, "Failed to add vdev mp action");
return -1;
}
/* Fall through to allow private vdevs in secondary process */
}
+scan:
/* call custom scan callbacks if any */
rte_spinlock_lock(&vdev_custom_scan_lock);
TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) {
{
struct mlx4_shared_data *sd;
struct mlx4_local_data *ld = &mlx4_local_data;
+ int ret = 0;
if (mlx4_init_shared_data())
return -rte_errno;
rte_rwlock_init(&sd->mem_event_rwlock);
rte_mem_event_callback_register("MLX4_MEM_EVENT_CB",
mlx4_mr_mem_event_cb, NULL);
- mlx4_mp_init_primary();
+ ret = mlx4_mp_init_primary();
+ if (ret)
+ goto out;
sd->init_done = true;
break;
case RTE_PROC_SECONDARY:
if (ld->init_done)
break;
- mlx4_mp_init_secondary();
+ ret = mlx4_mp_init_secondary();
+ if (ret)
+ goto out;
++sd->secondary_cnt;
ld->init_done = true;
break;
default:
break;
}
+out:
rte_spinlock_unlock(&sd->lock);
- return 0;
+ return ret;
}
/**
void mlx4_mp_req_stop_rxtx(struct rte_eth_dev *dev);
int mlx4_mp_req_mr_create(struct rte_eth_dev *dev, uintptr_t addr);
int mlx4_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev);
-void mlx4_mp_init_primary(void);
+int mlx4_mp_init_primary(void);
void mlx4_mp_uninit_primary(void);
-void mlx4_mp_init_secondary(void);
+int mlx4_mp_init_secondary(void);
void mlx4_mp_uninit_secondary(void);
#endif /* RTE_PMD_MLX4_H_ */
/**
* Initialize by primary process.
*/
-void
+int
mlx4_mp_init_primary(void)
{
+ int ret;
+
assert(rte_eal_process_type() == RTE_PROC_PRIMARY);
- rte_mp_action_register(MLX4_MP_NAME, mp_primary_handle);
+
+ /* primary is allowed to not support IPC */
+ ret = rte_mp_action_register(MLX4_MP_NAME, mp_primary_handle);
+ if (ret && rte_errno != ENOTSUP)
+ return -1;
+ return 0;
}
/**
/**
* Initialize by secondary process.
*/
-void
+int
mlx4_mp_init_secondary(void)
{
assert(rte_eal_process_type() == RTE_PROC_SECONDARY);
- rte_mp_action_register(MLX4_MP_NAME, mp_secondary_handle);
+ return rte_mp_action_register(MLX4_MP_NAME, mp_secondary_handle);
}
/**
{
struct mlx5_shared_data *sd;
struct mlx5_local_data *ld = &mlx5_local_data;
+ int ret = 0;
if (mlx5_init_shared_data())
return -rte_errno;
rte_rwlock_init(&sd->mem_event_rwlock);
rte_mem_event_callback_register("MLX5_MEM_EVENT_CB",
mlx5_mr_mem_event_cb, NULL);
- mlx5_mp_init_primary();
+ ret = mlx5_mp_init_primary();
+ if (ret)
+ goto out;
sd->init_done = true;
break;
case RTE_PROC_SECONDARY:
if (ld->init_done)
break;
- mlx5_mp_init_secondary();
+ ret = mlx5_mp_init_secondary();
+ if (ret)
+ goto out;
++sd->secondary_cnt;
ld->init_done = true;
break;
default:
break;
}
+out:
rte_spinlock_unlock(&sd->lock);
- return 0;
+ return ret;
}
/**
void mlx5_mp_req_stop_rxtx(struct rte_eth_dev *dev);
int mlx5_mp_req_mr_create(struct rte_eth_dev *dev, uintptr_t addr);
int mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev);
-void mlx5_mp_init_primary(void);
+int mlx5_mp_init_primary(void);
void mlx5_mp_uninit_primary(void);
-void mlx5_mp_init_secondary(void);
+int mlx5_mp_init_secondary(void);
void mlx5_mp_uninit_secondary(void);
/* mlx5_nl.c */
/**
* Initialize by primary process.
*/
-void
+int
mlx5_mp_init_primary(void)
{
+ int ret;
+
assert(rte_eal_process_type() == RTE_PROC_PRIMARY);
- rte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);
+
+ /* primary is allowed to not support IPC */
+ ret = rte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);
+ if (ret && rte_errno != ENOTSUP)
+ return -1;
+ return 0;
}
/**
/**
* Initialize by secondary process.
*/
-void
+int
mlx5_mp_init_secondary(void)
{
assert(rte_eal_process_type() == RTE_PROC_SECONDARY);
- rte_mp_action_register(MLX5_MP_NAME, mp_secondary_handle);
+ return rte_mp_action_register(MLX5_MP_NAME, mp_secondary_handle);
}
/**
/* Register IPC feed callback */
if (!tap_devices_count) {
ret = rte_mp_action_register(TAP_MP_KEY, tap_mp_sync_queues);
- if (ret < 0) {
+ if (ret < 0 && rte_errno != ENOTSUP) {
TAP_LOG(ERR, "tap: Failed to register IPC callback: %s",
strerror(rte_errno));
goto leave;
if (validate_action_name(name) != 0)
return -1;
+ if (internal_config.no_shconf) {
+ RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n");
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
entry = malloc(sizeof(struct action_entry));
if (entry == NULL) {
rte_errno = ENOMEM;
#include <string.h>
#include <rte_eal.h>
+#include <rte_errno.h>
#include <rte_alarm.h>
#include <rte_string_fns.h>
#include <rte_devargs.h>
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
ret = rte_mp_action_register(EAL_DEV_MP_ACTION_REQUEST,
handle_secondary_request);
- if (ret != 0) {
+ /* primary is allowed to not support IPC */
+ if (ret != 0 && rte_errno != ENOTSUP) {
RTE_LOG(ERR, EAL, "Couldn't register '%s' action\n",
EAL_DEV_MP_ACTION_REQUEST);
return ret;
* to response the messages from the corresponding component in its primary
* process or secondary processes.
*
+ * @note IPC may be unsupported in certain circumstances, so caller should check
+ * for ENOTSUP error.
+ *
* @param name
* The name argument plays as the nonredundant key to find the action.
*
register_mp_requests(void)
{
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- if (rte_mp_action_register(MP_ACTION_REQUEST, handle_request)) {
+ /* it's OK for primary to not support IPC */
+ if (rte_mp_action_register(MP_ACTION_REQUEST, handle_request) &&
+ rte_errno != ENOTSUP) {
RTE_LOG(ERR, EAL, "Couldn't register '%s' action\n",
MP_ACTION_REQUEST);
return -1;
#include <string.h>
#include <rte_compat.h>
+#include <rte_errno.h>
#include <rte_log.h>
#include <rte_vfio.h>
#include <rte_eal.h>
int
vfio_mp_sync_setup(void)
{
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
- return rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ int ret = rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);
+ if (ret && rte_errno != ENOTSUP)
+ return -1;
+ }
return 0;
}
int
rte_pdump_init(void)
{
- return rte_mp_action_register(PDUMP_MP, pdump_server);
+ int ret = rte_mp_action_register(PDUMP_MP, pdump_server);
+ if (ret && rte_errno != ENOTSUP)
+ return -1;
+ return 0;
}
int