diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 49cd04dbb..5be9da0fa 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -553,6 +553,9 @@ rte_dpaa_bus_probe(void)
 			if (ret)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (!drv->probe ||
 			    (dev->device.devargs &&
 			    dev->device.devargs->policy == RTE_DEV_BLACKLISTED))
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index bfe81e236..9011eb74c 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -384,6 +384,9 @@ rte_fslmc_probe(void)
 			if (!drv->probe)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (dev->device.devargs &&
 			  dev->device.devargs->policy == RTE_DEV_BLACKLISTED) {
 				DPAA2_BUS_LOG(DEBUG, "%s Blacklisted, skipping",
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 5ce886d13..a10f54f7b 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -5,6 +5,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
@@ -272,16 +273,22 @@ ifpga_probe_one_driver(struct rte_afu_driver *drv,
 			struct rte_afu_device *afu_dev)
 {
 	int ret;
+	bool already_probed;
 
 	if (!rte_afu_match(drv, afu_dev))
 		/* Match of device and driver failed */
 		return 1;
 
+	already_probed = rte_dev_is_probed(&afu_dev->device);
+
 	/* reference driver structure */
-	afu_dev->driver = drv;
+	if (!already_probed)
+		afu_dev->driver = drv;
 
 	/* call the driver probe() function */
 	ret = drv->probe(afu_dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret)
 		afu_dev->driver = NULL;
 	else
@@ -299,10 +306,6 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 	if (afu_dev == NULL)
 		return -1;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&afu_dev->device))
-		return 0;
-
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
 		if (ifpga_probe_one_driver(drv, afu_dev)) {
 			ret = -1;
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index d95410e19..46f65b415 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
@@ -123,6 +124,7 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			 struct rte_pci_device *dev)
 {
 	int ret;
+	bool already_probed;
 	struct rte_pci_addr *loc;
 
 	if ((dr == NULL) || (dev == NULL))
@@ -153,6 +155,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 		dev->device.numa_node = 0;
 	}
 
+	already_probed = rte_dev_is_probed(&dev->device);
+
 	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
 		dev->id.device_id, dr->driver.name);
 
@@ -161,9 +165,10 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * This needs to be before rte_pci_map_device(), as it enables to use
 	 * driver flags for adjusting configuration.
 	 */
-	dev->driver = dr;
+	if (!already_probed)
+		dev->driver = dr;
 
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+	if (!already_probed && (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
@@ -174,6 +179,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 
 	/* call the driver probe() function */
 	ret = dr->probe(dr, dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret) {
 		dev->driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
@@ -244,10 +251,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 	if (dev == NULL)
 		return -1;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&dev->device))
-		return 0;
-
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
 		rc = rte_pci_probe_one_driver(dr, dev);
 		if (rc < 0)
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 514d9d5c6..05a006d15 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -225,6 +225,11 @@ insert_vdev(const char *name, const char *args, struct rte_vdev_device **p_dev)
 	dev->device.name = devargs->name;
 
 	if (find_vdev(name)) {
+		/*
+		 * A vdev is expected to have only one port.
+		 * So there is no reason to try probing again,
+		 * even with new arguments.
+		 */
 		ret = -EEXIST;
 		goto fail;
 	}
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index 48a219f73..eff5c01f5 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -3,6 +3,7 @@
  * All Rights Reserved.
  */
 
+#include <stdbool.h>
 #include <string.h>
 #include <unistd.h>
 #include <dirent.h>
@@ -93,6 +94,7 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 		       struct rte_vmbus_device *dev)
 {
 	char guid[RTE_UUID_STRLEN];
+	bool already_probed;
 	int ret;
 
 	if (!vmbus_match(dr, dev))
@@ -104,13 +106,16 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 
 	/* TODO add blacklisted */
 
-	/* map resources for device */
-	ret = rte_vmbus_map_device(dev);
-	if (ret != 0)
-		return ret;
+	already_probed = rte_dev_is_probed(&dev->device);
+	if (!already_probed) {
+		/* map resources for device */
+		ret = rte_vmbus_map_device(dev);
+		if (ret != 0)
+			return ret;
 
-	/* reference driver structure */
-	dev->driver = dr;
+		/* reference driver structure */
+		dev->driver = dr;
+	}
 
 	if (dev->device.numa_node < 0) {
 		VMBUS_LOG(WARNING, "  Invalid NUMA socket, default to 0");
@@ -120,6 +125,8 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 	/* call the driver probe() function */
 	VMBUS_LOG(INFO, "  probe driver: %s", dr->driver.name);
 	ret = dr->probe(dr, dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret) {
 		dev->driver = NULL;
 		rte_vmbus_unmap_device(dev);
@@ -142,12 +149,6 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	struct rte_vmbus_driver *dr;
 	int rc;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&dev->device)) {
-		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
-		return 0;
-	}
-
 	FOREACH_DRIVER_ON_VMBUS(dr) {
 		rc = vmbus_probe_one_driver(dr, dev);
 		if (rc < 0) /* negative is an error */
diff --git a/drivers/common/qat/Makefile b/drivers/common/qat/Makefile
index c68a032a5..294da4927 100644
--- a/drivers/common/qat/Makefile
+++ b/drivers/common/qat/Makefile
@@ -8,6 +8,8 @@ QAT_CRYPTO_DIR := $(RTE_SDK)/drivers/crypto/qat
 QAT_COMPRESS_DIR := $(RTE_SDK)/drivers/compress/qat
 VPATH=$(QAT_CRYPTO_DIR):$(QAT_COMPRESS_DIR)
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
 # external library include paths
 CFLAGS += -I$(SRCDIR)/qat_adf
 CFLAGS += -I$(SRCDIR)
@@ -16,7 +18,6 @@ CFLAGS += -I$(QAT_COMPRESS_DIR)
 
 
 ifeq ($(CONFIG_RTE_LIBRTE_COMPRESSDEV),y)
-	CFLAGS += -DALLOW_EXPERIMENTAL_API
 	LDLIBS += -lrte_compressdev
 	SRCS-y += qat_comp.c
 	SRCS-y += qat_comp_pmd.c
diff --git a/drivers/common/qat/meson.build b/drivers/common/qat/meson.build
index 80b6b25a8..584642917 100644
--- a/drivers/common/qat/meson.build
+++ b/drivers/common/qat/meson.build
@@ -12,3 +12,4 @@ qat_sources = files('qat_common.c',
 qat_includes = [include_directories('.', 'qat_adf')]
 qat_ext_deps = []
 qat_cflags = []
+allow_experimental_apis = true
diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c
index f32d72358..da33faa9e 100644
--- a/drivers/common/qat/qat_device.c
+++ b/drivers/common/qat/qat_device.c
@@ -194,6 +194,9 @@ static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 			pci_dev->addr.devid,
 			pci_dev->addr.function);
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	qat_pci_dev = qat_pci_device_allocate(pci_dev);
 	if (qat_pci_dev == NULL)
 		return -ENODEV;
diff --git a/drivers/compress/octeontx/otx_zip_pmd.c b/drivers/compress/octeontx/otx_zip_pmd.c
index 9d13f9331..9894bb97c 100644
--- a/drivers/compress/octeontx/otx_zip_pmd.c
+++ b/drivers/compress/octeontx/otx_zip_pmd.c
@@ -569,6 +569,9 @@ zip_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 			(unsigned int)pci_dev->id.vendor_id,
 			(unsigned int)pci_dev->id.device_id);
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	rte_pci_device_name(&pci_dev->addr, compressdev_name,
 			    sizeof(compressdev_name));
 
diff --git a/drivers/crypto/virtio/Makefile b/drivers/crypto/virtio/Makefile
index be7b828fe..26c4edc2c 100644
--- a/drivers/crypto/virtio/Makefile
+++ b/drivers/crypto/virtio/Makefile
@@ -14,6 +14,7 @@ LIB = librte_pmd_virtio_crypto.a
 CFLAGS += -I$(RTE_SDK)/lib/librte_vhost
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_pmd_virtio_crypto_version.map
 
diff --git a/drivers/crypto/virtio/meson.build b/drivers/crypto/virtio/meson.build
index b15b3f9fa..cb7b5ab99 100644
--- a/drivers/crypto/virtio/meson.build
+++ b/drivers/crypto/virtio/meson.build
@@ -6,3 +6,4 @@ deps += 'bus_pci'
 name = 'virtio_crypto'
 sources = files('virtio_cryptodev.c', 'virtio_pci.c',
 		'virtio_rxtx.c', 'virtqueue.c')
+allow_experimental_apis = true
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 568b5a406..f0fb2fe1e 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -1439,6 +1439,9 @@ crypto_virtio_pci_probe(
 			pci_dev->addr.devid,
 			pci_dev->addr.function);
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
 
 	return crypto_virtio_create(name, pci_dev, &init_params);
diff --git a/drivers/event/octeontx/ssovf_probe.c b/drivers/event/octeontx/ssovf_probe.c
index b3db596d4..602012024 100644
--- a/drivers/event/octeontx/ssovf_probe.c
+++ b/drivers/event/octeontx/ssovf_probe.c
@@ -150,6 +150,9 @@ ssowvf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->mem_resource[0].addr == NULL ||
 			pci_dev->mem_resource[2].addr == NULL ||
 			pci_dev->mem_resource[4].addr == NULL) {
@@ -230,6 +233,9 @@ ssovf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->mem_resource[0].addr == NULL ||
 			pci_dev->mem_resource[2].addr == NULL) {
 		mbox_log_err("Empty bars %p %p",
diff --git a/drivers/event/skeleton/Makefile b/drivers/event/skeleton/Makefile
index 0f7f07eaf..fd75b1dd6 100644
--- a/drivers/event/skeleton/Makefile
+++ b/drivers/event/skeleton/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_skeleton_event.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_eventdev
 LDLIBS += -lrte_pci -lrte_bus_pci
diff --git a/drivers/event/skeleton/meson.build b/drivers/event/skeleton/meson.build
index acfe15653..773bed4ae 100644
--- a/drivers/event/skeleton/meson.build
+++ b/drivers/event/skeleton/meson.build
@@ -3,3 +3,4 @@
 
 sources = files('skeleton_eventdev.c')
 deps += ['bus_pci', 'bus_vdev']
+allow_experimental_apis = true
diff --git a/drivers/mempool/octeontx/Makefile b/drivers/mempool/octeontx/Makefile
index a3e1dce88..b9c9e0268 100644
--- a/drivers/mempool/octeontx/Makefile
+++ b/drivers/mempool/octeontx/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_mempool_octeontx.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx/
 EXPORT_MAP := rte_mempool_octeontx_version.map
diff --git a/drivers/mempool/octeontx/meson.build b/drivers/mempool/octeontx/meson.build
index 3baaf7db2..cdf5bbe24 100644
--- a/drivers/mempool/octeontx/meson.build
+++ b/drivers/mempool/octeontx/meson.build
@@ -5,4 +5,6 @@ sources = files('octeontx_fpavf.c',
 		'rte_mempool_octeontx.c'
 )
 
+allow_experimental_apis = true
+
 deps += ['mbuf', 'bus_pci', 'common_octeontx']
diff --git a/drivers/mempool/octeontx/octeontx_fpavf.c b/drivers/mempool/octeontx/octeontx_fpavf.c
index 4cf387e8f..a9998f8c3 100644
--- a/drivers/mempool/octeontx/octeontx_fpavf.c
+++ b/drivers/mempool/octeontx/octeontx_fpavf.c
@@ -764,6 +764,9 @@ fpavf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->mem_resource[0].addr == NULL) {
 		fpavf_log_err("Empty bars %p ", pci_dev->mem_resource[0].addr);
 		return -ENODEV;
diff --git a/drivers/net/ark/Makefile b/drivers/net/ark/Makefile
index 2e232be85..a873a774a 100644
--- a/drivers/net/ark/Makefile
+++ b/drivers/net/ark/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_ark.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3 -I./
 CFLAGS += $(WERROR_FLAGS) -Werror
 
diff --git a/drivers/net/ark/meson.build b/drivers/net/ark/meson.build
index 99151bba1..a5886cd01 100644
--- a/drivers/net/ark/meson.build
+++ b/drivers/net/ark/meson.build
@@ -11,3 +11,4 @@ sources = files('ark_ddm.c',
 	'ark_pktgen.c',
 	'ark_rqp.c',
 	'ark_udm.c')
+allow_experimental_apis = true
diff --git a/drivers/net/avf/Makefile b/drivers/net/avf/Makefile
index 3f815bbc4..fec88ea38 100644
--- a/drivers/net/avf/Makefile
+++ b/drivers/net/avf/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_avf.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
diff --git a/drivers/net/avp/Makefile b/drivers/net/avp/Makefile
index c9db667f3..6fcdc05f5 100644
--- a/drivers/net/avp/Makefile
+++ b/drivers/net/avp/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_avp.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/avp/meson.build b/drivers/net/avp/meson.build
index 6076c31b9..4c282ebe2 100644
--- a/drivers/net/avp/meson.build
+++ b/drivers/net/avp/meson.build
@@ -3,3 +3,4 @@
 
 sources = files('avp_ethdev.c')
 install_headers('rte_avp_common.h', 'rte_avp_fifo.h')
+allow_experimental_apis = true
diff --git a/drivers/net/axgbe/Makefile b/drivers/net/axgbe/Makefile
index 72215aeda..1bc0412b4 100644
--- a/drivers/net/axgbe/Makefile
+++ b/drivers/net/axgbe/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_axgbe.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
diff --git a/drivers/net/axgbe/meson.build b/drivers/net/axgbe/meson.build
index 548ffff7a..c865b739f 100644
--- a/drivers/net/axgbe/meson.build
+++ b/drivers/net/axgbe/meson.build
@@ -17,3 +17,5 @@ cflags += '-Wno-cast-qual'
 if arch_subdir == 'x86'
 	sources += files('axgbe_rxtx_vec_sse.c')
 endif
+
+allow_experimental_apis = true
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile
index 55d1ad6e0..82ad0ead9 100644
--- a/drivers/net/bnx2x/Makefile
+++ b/drivers/net/bnx2x/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_bnx2x.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -DZLIB_CONST
diff --git a/drivers/net/bnx2x/meson.build b/drivers/net/bnx2x/meson.build
index e3c688869..734499ceb 100644
--- a/drivers/net/bnx2x/meson.build
+++ b/drivers/net/bnx2x/meson.build
@@ -12,3 +12,4 @@ sources = files('bnx2x.c',
 	'bnx2x_vfpf.c',
 	'ecore_sp.c',
 	'elink.c')
+allow_experimental_apis = true
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 8be3cb0e4..ce84ec64d 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -15,6 +15,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 
 LIBABIVER := 2
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build
index e130f2712..d1f50cb6d 100644
--- a/drivers/net/bnxt/meson.build
+++ b/drivers/net/bnxt/meson.build
@@ -18,3 +18,4 @@ sources = files('bnxt_cpr.c',
 	'bnxt_util.c',
 	'bnxt_vnic.c',
 	'rte_pmd_bnxt.c')
+allow_experimental_apis = true
diff --git a/drivers/net/cxgbe/Makefile b/drivers/net/cxgbe/Makefile
index 68466f13e..36388a746 100644
--- a/drivers/net/cxgbe/Makefile
+++ b/drivers/net/cxgbe/Makefile
@@ -13,6 +13,7 @@ CFLAGS += -I$(SRCDIR)/base/
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_pmd_cxgbe_version.map
 
diff --git a/drivers/net/cxgbe/meson.build b/drivers/net/cxgbe/meson.build
index c51af26e9..d8c3b9e5c 100644
--- a/drivers/net/cxgbe/meson.build
+++ b/drivers/net/cxgbe/meson.build
@@ -14,3 +14,5 @@ sources = files('cxgbe_ethdev.c',
 	'base/t4_hw.c',
 	'base/t4vf_hw.c')
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
index 9c87e883b..825234dc8 100644
--- a/drivers/net/e1000/Makefile
+++ b/drivers/net/e1000/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_e1000.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/e1000/meson.build b/drivers/net/e1000/meson.build
index cf456995c..997013de3 100644
--- a/drivers/net/e1000/meson.build
+++ b/drivers/net/e1000/meson.build
@@ -15,3 +15,5 @@ sources = files(
 )
 
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 7c6c29cc0..bebed0dd5 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -13,6 +13,7 @@ EXPORT_MAP := rte_pmd_enic_version.map
 
 LIBABIVER := 1
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -I$(SRCDIR)/base/
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -O3
diff --git a/drivers/net/enic/meson.build b/drivers/net/enic/meson.build
index bfd4e2373..4df6bd457 100644
--- a/drivers/net/enic/meson.build
+++ b/drivers/net/enic/meson.build
@@ -17,3 +17,5 @@ sources = files(
 	)
 deps += ['hash']
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/net/fm10k/Makefile b/drivers/net/fm10k/Makefile
index d657dff8a..a53a3ece6 100644
--- a/drivers/net/fm10k/Makefile
+++ b/drivers/net/fm10k/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_fm10k.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
diff --git a/drivers/net/fm10k/meson.build b/drivers/net/fm10k/meson.build
index 2772ea4df..a99aecfa7 100644
--- a/drivers/net/fm10k/meson.build
+++ b/drivers/net/fm10k/meson.build
@@ -14,3 +14,5 @@ if arch_subdir == 'x86'
 endif
 
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24d73f2ff..67f29f282 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -633,6 +633,9 @@ eth_i40e_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };
 	int i, retval;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->device.devargs) {
 		retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
 				&eth_da);
diff --git a/drivers/net/ifc/ifcvf_vdpa.c b/drivers/net/ifc/ifcvf_vdpa.c
index 88d814037..192368395 100644
--- a/drivers/net/ifc/ifcvf_vdpa.c
+++ b/drivers/net/ifc/ifcvf_vdpa.c
@@ -682,6 +682,9 @@ ifcvf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	list = rte_zmalloc("ifcvf", sizeof(*list), 0);
 	if (list == NULL)
 		goto error;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index cee886754..8a6d5f972 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1735,6 +1735,9 @@ eth_ixgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_eth_devargs eth_da;
 	int i, retval;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->device.devargs) {
 		retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
 				&eth_da);
diff --git a/drivers/net/liquidio/Makefile b/drivers/net/liquidio/Makefile
index f1092851a..19a9f8fe6 100644
--- a/drivers/net/liquidio/Makefile
+++ b/drivers/net/liquidio/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_lio.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)/base -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/liquidio/meson.build b/drivers/net/liquidio/meson.build
index 9ae48e213..091114349 100644
--- a/drivers/net/liquidio/meson.build
+++ b/drivers/net/liquidio/meson.build
@@ -6,3 +6,4 @@ sources = files('base/lio_23xx_vf.c',
 	'lio_ethdev.c',
 	'lio_rxtx.c')
 includes += include_directories('base')
+allow_experimental_apis = true
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 3de7bc53e..c3acb469a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -523,6 +523,10 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 
 	(void)pci_drv;
 	assert(pci_drv == &mlx4_driver);
+
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	list = mlx4_glue->get_device_list(&i);
 	if (list == NULL) {
 		rte_errno = errno;
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index f5f3a3d19..b488910a8 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1296,6 +1296,10 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 
 	assert(pci_drv == &mlx5_driver);
 	errno = 0;
+
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	ibv_list = mlx5_glue->get_device_list(&ret);
 	if (!ibv_list) {
 		rte_errno = errno ? errno : ENOSYS;
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index b67cce1ba..991a1a91a 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -75,9 +75,6 @@ eth_dev_vmbus_allocate(struct rte_vmbus_device *dev, size_t private_data_size)
 	struct rte_eth_dev *eth_dev;
 	const char *name;
 
-	if (!dev)
-		return NULL;
-
 	name = dev->device.name;
 
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
@@ -824,6 +821,12 @@ static int eth_hn_probe(struct rte_vmbus_driver *drv __rte_unused,
 
 	PMD_INIT_FUNC_TRACE();
 
+	if (!dev)
+		return -EINVAL;
+
+	if (rte_dev_is_probed(&dev->device))
+		return -EEXIST;
+
 	eth_dev = eth_dev_vmbus_allocate(dev, sizeof(struct hn_data));
 	if (!eth_dev)
 		return -ENOMEM;
diff --git a/drivers/net/nfp/Makefile b/drivers/net/nfp/Makefile
index ab4e0a7d9..0188144da 100644
--- a/drivers/net/nfp/Makefile
+++ b/drivers/net/nfp/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_nfp.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 3ba37e279..1cae381fa 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -14,3 +14,4 @@ sources = files('nfpcore/nfp_cpp_pcie_ops.c',
 	'nfpcore/nfp_nsp_eth.c',
 	'nfpcore/nfp_hwinfo.c',
 	'nfp_net.c')
+allow_experimental_apis = true
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 168088c6d..c9438f655 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -3121,6 +3121,9 @@ static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	if (!dev)
 		return ret;
 
+	if (rte_dev_is_probed(&dev->device))
+		return -EEXIST;
+
 	/*
 	 * When device bound to UIO, the device could be used, by mistake,
 	 * by two DPDK apps, and the UIO driver does not avoid it. This
diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile
index 885f17684..060ba873d 100644
--- a/drivers/net/octeontx/Makefile
+++ b/drivers/net/octeontx/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_octeontx.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
@@ -44,8 +45,6 @@ else
 CFLAGS_octeontx_rxtx.o += -O3 -Ofast
 endif
 
-CFLAGS_octeontx_ethdev.o += -DALLOW_EXPERIMENTAL_API
-
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_common_octeontx
 LDLIBS += -lrte_mempool_octeontx
diff --git a/drivers/net/octeontx/base/meson.build b/drivers/net/octeontx/base/meson.build
index 09f657abb..738164beb 100644
--- a/drivers/net/octeontx/base/meson.build
+++ b/drivers/net/octeontx/base/meson.build
@@ -14,7 +14,7 @@ foreach d: depends
 endforeach
 
 base_lib = static_library('octeontx_base', sources,
-	c_args: cflags,
+	c_args: cflags + ['-DALLOW_EXPERIMENTAL_API'],
 	dependencies: static_objs,
 )
 
diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c b/drivers/net/octeontx/base/octeontx_pkivf.c
index 1babea0e8..4c8a0a345 100644
--- a/drivers/net/octeontx/base/octeontx_pkivf.c
+++ b/drivers/net/octeontx/base/octeontx_pkivf.c
@@ -120,6 +120,9 @@ pkivf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	return 0;
 }
 
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.c b/drivers/net/octeontx/base/octeontx_pkovf.c
index 0a6d64b8e..19b1f3c65 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.c
+++ b/drivers/net/octeontx/base/octeontx_pkovf.c
@@ -536,6 +536,9 @@ pkovf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->mem_resource[0].addr == NULL ||
 	    pci_dev->mem_resource[2].addr == NULL) {
 		octeontx_log_err("Empty bars %p %p",
diff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile
index 488ca1d92..455f076f9 100644
--- a/drivers/net/qede/Makefile
+++ b/drivers/net/qede/Makefile
@@ -10,6 +10,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_qede.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/qede/meson.build b/drivers/net/qede/meson.build
index 6280073a5..1978c0b51 100644
--- a/drivers/net/qede/meson.build
+++ b/drivers/net/qede/meson.build
@@ -10,3 +10,5 @@ sources = files(
 	'qede_main.c',
 	'qede_rxtx.c',
 )
+
+allow_experimental_apis = true
diff --git a/drivers/net/szedata2/Makefile b/drivers/net/szedata2/Makefile
index b77fae16d..6a9198bfd 100644
--- a/drivers/net/szedata2/Makefile
+++ b/drivers/net/szedata2/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_szedata2.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lsze2
diff --git a/drivers/net/szedata2/meson.build b/drivers/net/szedata2/meson.build
index da3733743..157b32e15 100644
--- a/drivers/net/szedata2/meson.build
+++ b/drivers/net/szedata2/meson.build
@@ -5,3 +5,4 @@ dep = cc.find_library('sze2', required: false)
 build = dep.found()
 ext_deps += dep
 sources = files('rte_eth_szedata2.c')
+allow_experimental_apis = true
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 8f92e72f2..0adc0ff4c 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1804,6 +1804,9 @@ static int szedata2_eth_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 
 	PMD_INIT_FUNC_TRACE();
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	ret = get_port_info(pci_dev, &port_count, port_info,
 			SZEDATA2_MAX_PORTS);
 	if (ret != 0)
diff --git a/drivers/net/thunderx/Makefile b/drivers/net/thunderx/Makefile
index e6bf49752..c08ef9277 100644
--- a/drivers/net/thunderx/Makefile
+++ b/drivers/net/thunderx/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_thunderx_nicvf.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS)
 
 LDLIBS += -lm
diff --git a/drivers/net/thunderx/meson.build b/drivers/net/thunderx/meson.build
index 69819a97f..bcba1489f 100644
--- a/drivers/net/thunderx/meson.build
+++ b/drivers/net/thunderx/meson.build
@@ -18,3 +18,5 @@ if cc.has_argument('-Wno-maybe-uninitialized')
 endif
 
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
index 3fed05781..cfaa0d39e 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
@@ -378,6 +378,9 @@ ifpga_rawdev_create(struct rte_pci_device *pci_dev,
 		goto cleanup;
 	}
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	memset(name, 0, sizeof(name));
 	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 907c5c481..cbd7a3419 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -191,11 +191,6 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (rte_dev_is_probed(dev)) {
-		RTE_LOG(ERR, EAL, "Device is already plugged\n");
-		return -EEXIST;
-	}
-
 	ret = da->bus->plug(dev);
 	if (ret) {
 		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5b16ee27b..6ba16f8b3 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -158,7 +158,7 @@ struct rte_device {
 	const char *name;             /**< Device name */
 	const struct rte_driver *driver; /**< Driver associated after probing */
 	int numa_node;                /**< NUMA node connection */
-	struct rte_devargs *devargs;  /**< Device user arguments */
+	struct rte_devargs *devargs;  /**< Arguments for latest probing */
 };
 
 /**
diff --git a/lib/librte_ethdev/rte_ethdev_pci.h b/lib/librte_ethdev/rte_ethdev_pci.h
index f652596f4..4080fa6f5 100644
--- a/lib/librte_ethdev/rte_ethdev_pci.h
+++ b/lib/librte_ethdev/rte_ethdev_pci.h
@@ -167,6 +167,9 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
 	struct rte_eth_dev *eth_dev;
 	int ret;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	eth_dev = rte_eth_dev_pci_allocate(pci_dev, private_data_size);
 	if (!eth_dev)
 		return -ENOMEM;
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index 8fb61386f..97fa2cc97 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,9 @@ rte_event_pmd_pci_probe(struct rte_pci_driver *pci_drv,
 	if (devinit == NULL)
 		return -EINVAL;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	rte_pci_device_name(&pci_dev->addr, eventdev_name,
 			sizeof(eventdev_name));
 
