From: Anatoly Burakov Date: Thu, 25 Apr 2019 12:45:15 +0000 (+0100) Subject: ipc: handle unsupported IPC in action register X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=edf73dd330729d9892add288da5e73c171553dd8;p=dpdk.git ipc: handle unsupported IPC in action register 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 --- diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c index 04f76a63f1..a89ea23530 100644 --- a/drivers/bus/vdev/vdev.c +++ b/drivers/bus/vdev/vdev.c @@ -409,6 +409,10 @@ vdev_scan(void) 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; } @@ -436,6 +440,7 @@ vdev_scan(void) /* 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) { diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index f7cd0c9207..aa4d43fad7 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -697,6 +697,7 @@ mlx4_init_once(void) { struct mlx4_shared_data *sd; struct mlx4_local_data *ld = &mlx4_local_data; + int ret = 0; if (mlx4_init_shared_data()) return -rte_errno; @@ -711,21 +712,26 @@ mlx4_init_once(void) 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; } /** diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index d4e56e879e..cd0d637ac2 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -242,9 +242,9 @@ void mlx4_mp_req_start_rxtx(struct rte_eth_dev *dev); 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_ */ diff --git a/drivers/net/mlx4/mlx4_mp.c b/drivers/net/mlx4/mlx4_mp.c index 183622453c..ebc57a99e8 100644 --- a/drivers/net/mlx4/mlx4_mp.c +++ b/drivers/net/mlx4/mlx4_mp.c @@ -316,11 +316,18 @@ exit: /** * 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; } /** @@ -336,11 +343,11 @@ mlx4_mp_uninit_primary(void) /** * 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); } /** diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 96c6c4be4d..daadf4a7a7 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1015,6 +1015,7 @@ mlx5_init_once(void) { struct mlx5_shared_data *sd; struct mlx5_local_data *ld = &mlx5_local_data; + int ret = 0; if (mlx5_init_shared_data()) return -rte_errno; @@ -1029,21 +1030,26 @@ mlx5_init_once(void) 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; } /** diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 6738a50676..21b445a402 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -542,9 +542,9 @@ void mlx5_mp_req_start_rxtx(struct rte_eth_dev *dev); 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 */ diff --git a/drivers/net/mlx5/mlx5_mp.c b/drivers/net/mlx5/mlx5_mp.c index cea74adb63..dc99231fe8 100644 --- a/drivers/net/mlx5/mlx5_mp.c +++ b/drivers/net/mlx5/mlx5_mp.c @@ -320,11 +320,18 @@ exit: /** * 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; } /** @@ -340,11 +347,11 @@ mlx5_mp_uninit_primary(void) /** * 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); } /** diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 074b3e82df..9dd77311b4 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -2287,7 +2287,7 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) /* 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; diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c index 395161c565..7f86c12e98 100644 --- a/lib/librte_eal/common/eal_common_proc.c +++ b/lib/librte_eal/common/eal_common_proc.c @@ -205,6 +205,12 @@ rte_mp_action_register(const char *name, rte_mp_t action) 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; diff --git a/lib/librte_eal/common/hotplug_mp.c b/lib/librte_eal/common/hotplug_mp.c index 04616519cd..2275cac414 100644 --- a/lib/librte_eal/common/hotplug_mp.c +++ b/lib/librte_eal/common/hotplug_mp.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -440,7 +441,8 @@ int rte_mp_dev_hotplug_init(void) 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; diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h index 73754aaf29..4820298cfc 100644 --- a/lib/librte_eal/common/include/rte_eal.h +++ b/lib/librte_eal/common/include/rte_eal.h @@ -262,6 +262,9 @@ typedef int (*rte_mp_async_reply_t)(const struct rte_mp_msg *request, * 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. * diff --git a/lib/librte_eal/common/malloc_mp.c b/lib/librte_eal/common/malloc_mp.c index b470565e0d..1374eabc29 100644 --- a/lib/librte_eal/common/malloc_mp.c +++ b/lib/librte_eal/common/malloc_mp.c @@ -722,7 +722,9 @@ int 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; diff --git a/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c index 2a47f29d5a..5f2a5fc1d9 100644 --- a/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c +++ b/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -110,8 +111,11 @@ vfio_mp_primary(const struct rte_mp_msg *msg, const void *peer) 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; } diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c index 14744b9ff0..cd24dd0109 100644 --- a/lib/librte_pdump/rte_pdump.c +++ b/lib/librte_pdump/rte_pdump.c @@ -408,7 +408,10 @@ pdump_server(const struct rte_mp_msg *mp_msg, const void *peer) 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