[dpdk-stable] patch 'vfio: allow secondary process to query IOMMU type' has been queued to LTS release 18.11.1

Kevin Traynor ktraynor at redhat.com
Thu Feb 7 14:25:49 CET 2019


Hi,

FYI, your patch has been queued to LTS release 18.11.1

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 02/14/19. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Thanks.

Kevin Traynor

---
>From 09be2373eaf624acef3c235e8e2b3b09c83e273a Mon Sep 17 00:00:00 2001
From: Anatoly Burakov <anatoly.burakov at intel.com>
Date: Fri, 18 Jan 2019 10:24:41 +0000
Subject: [PATCH] vfio: allow secondary process to query IOMMU type

[ upstream commit 47f4fe0595fda08e0e4b8a26ad249dd52b95186f ]

It is only possible to know IOMMU type of a given VFIO container
by attempting to initialize it. Since secondary process never
attempts to set up VFIO container itself (because they're shared
between primary and secondary), it never knows which IOMMU type
the container is using, and never sets up the appropriate config
structures. This results in inability to perform DMA mappings in
secondary process.

Fix this by allowing secondary process to query IOMMU type of
primary's default container at device initialization.

Note that this fix is assuming we're only interested in default
container.

Bugzilla ID: 174
Fixes: 6bcb7c95fe14 ("vfio: share default container in multi-process")

Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk at intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_vfio.c        | 88 +++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_vfio.h        | 12 ++-
 .../linuxapp/eal/eal_vfio_mp_sync.c           | 16 ++++
 3 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.c b/lib/librte_eal/linuxapp/eal/eal_vfio.c
index 72cc65151..c821e8382 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.c
@@ -550,4 +550,63 @@ next:
 }
 
+static int
+vfio_sync_default_container(void)
+{
+	struct rte_mp_msg mp_req, *mp_rep;
+	struct rte_mp_reply mp_reply;
+	struct timespec ts = {.tv_sec = 5, .tv_nsec = 0};
+	struct vfio_mp_param *p = (struct vfio_mp_param *)mp_req.param;
+	int iommu_type_id;
+	unsigned int i;
+
+	/* cannot be called from primary */
+	if (rte_eal_process_type() != RTE_PROC_SECONDARY)
+		return -1;
+
+	/* default container fd should have been opened in rte_vfio_enable() */
+	if (!default_vfio_cfg->vfio_enabled ||
+			default_vfio_cfg->vfio_container_fd < 0) {
+		RTE_LOG(ERR, EAL, "VFIO support is not initialized\n");
+		return -1;
+	}
+
+	/* find default container's IOMMU type */
+	p->req = SOCKET_REQ_IOMMU_TYPE;
+	strcpy(mp_req.name, EAL_VFIO_MP);
+	mp_req.len_param = sizeof(*p);
+	mp_req.num_fds = 0;
+
+	iommu_type_id = -1;
+	if (rte_mp_request_sync(&mp_req, &mp_reply, &ts) == 0 &&
+			mp_reply.nb_received == 1) {
+		mp_rep = &mp_reply.msgs[0];
+		p = (struct vfio_mp_param *)mp_rep->param;
+		if (p->result == SOCKET_OK)
+			iommu_type_id = p->iommu_type_id;
+		free(mp_reply.msgs);
+	}
+	if (iommu_type_id < 0) {
+		RTE_LOG(ERR, EAL, "Could not get IOMMU type for default container\n");
+		return -1;
+	}
+
+	/* we now have an fd for default container, as well as its IOMMU type.
+	 * now, set up default VFIO container config to match.
+	 */
+	for (i = 0; i < RTE_DIM(iommu_types); i++) {
+		const struct vfio_iommu_type *t = &iommu_types[i];
+		if (t->type_id != iommu_type_id)
+			continue;
+
+		/* we found our IOMMU type */
+		default_vfio_cfg->vfio_iommu_type = t;
+
+		return 0;
+	}
+	RTE_LOG(ERR, EAL, "Could not find IOMMU type id (%i)\n",
+			iommu_type_id);
+	return -1;
+}
+
 int
 rte_vfio_clear_group(int vfio_group_fd)
@@ -746,4 +805,24 @@ rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr,
 				RTE_LOG(DEBUG, EAL, "Installed memory event callback for VFIO\n");
 		}
+	} else if (rte_eal_process_type() != RTE_PROC_PRIMARY &&
+			vfio_cfg == default_vfio_cfg &&
+			vfio_cfg->vfio_iommu_type == NULL) {
+		/* if we're not a primary process, we do not set up the VFIO
+		 * container because it's already been set up by the primary
+		 * process. instead, we simply ask the primary about VFIO type
+		 * we are using, and set the VFIO config up appropriately.
+		 */
+		ret = vfio_sync_default_container();
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "Could not sync default VFIO container\n");
+			close(vfio_group_fd);
+			rte_vfio_clear_group(vfio_group_fd);
+			return -1;
+		}
+		/* we have successfully initialized VFIO, notify user */
+		const struct vfio_iommu_type *t =
+				default_vfio_cfg->vfio_iommu_type;
+		RTE_LOG(NOTICE, EAL, "  using IOMMU type %d (%s)\n",
+				t->type_id, t->name);
 	}
 
@@ -979,4 +1058,13 @@ vfio_get_default_container_fd(void)
 }
 
+int
+vfio_get_iommu_type(void)
+{
+	if (default_vfio_cfg->vfio_iommu_type == NULL)
+		return -1;
+
+	return default_vfio_cfg->vfio_iommu_type->type_id;
+}
+
 const struct vfio_iommu_type *
 vfio_set_iommu_type(int vfio_container_fd)
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h
index 63ae115c3..cb2d35fb1 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.h
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h
@@ -6,4 +6,6 @@
 #define EAL_VFIO_H_
 
+#include <rte_common.h>
+
 /*
  * determine if VFIO is present on the system
@@ -123,4 +125,7 @@ const struct vfio_iommu_type *
 vfio_set_iommu_type(int vfio_container_fd);
 
+int
+vfio_get_iommu_type(void);
+
 /* check if we have any supported extensions */
 int
@@ -134,4 +139,5 @@ int vfio_mp_sync_setup(void);
 #define SOCKET_REQ_GROUP 0x200
 #define SOCKET_REQ_DEFAULT_CONTAINER 0x400
+#define SOCKET_REQ_IOMMU_TYPE 0x800
 #define SOCKET_OK 0x0
 #define SOCKET_NO_FD 0x1
@@ -141,5 +147,9 @@ struct vfio_mp_param {
 	int req;
 	int result;
-	int group_num;
+	RTE_STD_C11
+	union {
+		int group_num;
+		int iommu_type_id;
+	};
 };
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
index a1e8c834f..2a47f29d5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
@@ -78,4 +78,20 @@ vfio_mp_primary(const struct rte_mp_msg *msg, const void *peer)
 		}
 		break;
+	case SOCKET_REQ_IOMMU_TYPE:
+	{
+		int iommu_type_id;
+
+		r->req = SOCKET_REQ_IOMMU_TYPE;
+
+		iommu_type_id = vfio_get_iommu_type();
+
+		if (iommu_type_id < 0)
+			r->result = SOCKET_ERR;
+		else {
+			r->iommu_type_id = iommu_type_id;
+			r->result = SOCKET_OK;
+		}
+		break;
+	}
 	default:
 		RTE_LOG(ERR, EAL, "vfio received invalid message!\n");
-- 
2.19.0

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2019-02-07 13:19:56.547157449 +0000
+++ 0043-vfio-allow-secondary-process-to-query-IOMMU-type.patch	2019-02-07 13:19:55.000000000 +0000
@@ -1,8 +1,10 @@
-From 47f4fe0595fda08e0e4b8a26ad249dd52b95186f Mon Sep 17 00:00:00 2001
+From 09be2373eaf624acef3c235e8e2b3b09c83e273a Mon Sep 17 00:00:00 2001
 From: Anatoly Burakov <anatoly.burakov at intel.com>
 Date: Fri, 18 Jan 2019 10:24:41 +0000
 Subject: [PATCH] vfio: allow secondary process to query IOMMU type
 
+[ upstream commit 47f4fe0595fda08e0e4b8a26ad249dd52b95186f ]
+
 It is only possible to know IOMMU type of a given VFIO container
 by attempting to initialize it. Since secondary process never
 attempts to set up VFIO container itself (because they're shared
@@ -19,7 +21,6 @@
 
 Bugzilla ID: 174
 Fixes: 6bcb7c95fe14 ("vfio: share default container in multi-process")
-Cc: stable at dpdk.org
 
 Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
 Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk at intel.com>


More information about the stable mailing list