[19.08,2/6] ipc: handle unsupported ipc in action register

Message ID 425d28112308bc9a026d2de0b2844f1487d1d6e1.1556195690.git.anatoly.burakov@intel.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers
Series [19.08,1/6] ipc: handle unsupported ipc in init |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Anatoly Burakov April 25, 2019, 12:45 p.m. UTC
  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>
---
 drivers/bus/vdev/vdev.c                     |  5 +++++
 drivers/net/mlx4/mlx4.c                     | 12 +++++++++---
 drivers/net/mlx4/mlx4.h                     |  4 ++--
 drivers/net/mlx4/mlx4_mp.c                  | 15 +++++++++++----
 drivers/net/mlx5/mlx5.c                     | 12 +++++++++---
 drivers/net/mlx5/mlx5.h                     |  4 ++--
 drivers/net/mlx5/mlx5_mp.c                  | 15 +++++++++++----
 drivers/net/tap/rte_eth_tap.c               |  2 +-
 lib/librte_eal/common/eal_common_proc.c     |  6 ++++++
 lib/librte_eal/common/hotplug_mp.c          |  4 +++-
 lib/librte_eal/common/include/rte_eal.h     |  3 +++
 lib/librte_eal/common/malloc_mp.c           |  4 +++-
 lib/librte_eal/linux/eal/eal_vfio_mp_sync.c |  8 ++++++--
 lib/librte_pdump/rte_pdump.c                |  5 ++++-
 14 files changed, 75 insertions(+), 24 deletions(-)
  

Patch

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 04f76a63f..a89ea2353 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 17dfcd5a3..3cfa07de3 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -693,6 +693,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;
@@ -707,21 +708,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 6224b3be1..d0769bbc9 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -239,9 +239,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 183622453..ebc57a99e 100644
--- a/drivers/net/mlx4/mlx4_mp.c
+++ b/drivers/net/mlx4/mlx4_mp.c
@@ -316,11 +316,18 @@  mlx4_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
 /**
  * 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 46ca08a4d..271d79d8f 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -990,6 +990,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;
@@ -1004,21 +1005,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 0a6d7f1d5..0b3418b4a 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -540,9 +540,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 cea74adb6..dc99231fe 100644
--- a/drivers/net/mlx5/mlx5_mp.c
+++ b/drivers/net/mlx5/mlx5_mp.c
@@ -320,11 +320,18 @@  mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
 /**
  * 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 7f74b5dc9..3e82f5138 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -2273,7 +2273,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 a4581e3b4..a40aa2c1b 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))
 		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 4052a5c7f..60cd1402d 100644
--- a/lib/librte_eal/common/hotplug_mp.c
+++ b/lib/librte_eal/common/hotplug_mp.c
@@ -4,6 +4,7 @@ 
 #include <string.h>
 
 #include <rte_eal.h>
+#include <rte_errno.h>
 #include <rte_alarm.h>
 #include <rte_string_fns.h>
 #include <rte_devargs.h>
@@ -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 f9288666e..7f807aa8e 100644
--- a/lib/librte_eal/common/include/rte_eal.h
+++ b/lib/librte_eal/common/include/rte_eal.h
@@ -248,6 +248,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 b470565e0..1374eabc2 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 2a47f29d5..5f2a5fc1d 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 <string.h>
 
 #include <rte_compat.h>
+#include <rte_errno.h>
 #include <rte_log.h>
 #include <rte_vfio.h>
 #include <rte_eal.h>
@@ -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 14744b9ff..cd24dd010 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