* [PATCH v6 0/4] allow pmdinfo to be inserted and parsed using MSVC
@ 2025-06-10 10:09 David Marchand
2025-06-10 10:09 ` [PATCH v6 1/4] dev: hide driver export macros David Marchand
` (4 more replies)
0 siblings, 5 replies; 17+ messages in thread
From: David Marchand @ 2025-06-10 10:09 UTC (permalink / raw)
To: dev
This is a rework of Andre v5, trying to hide the ugly details in a
driver only macro not exposed publicly.
--
David Marchand
Changes since v5:
- moved details in dev_driver.h,
- renamed RTE_INCLUDE as RTE_PMD_EXPORT_SYMBOL,
Andre Muezerie (3):
dev: export driver information with MSVC
buildtools: embed driver information with MSVC
usertools: enable pmdinfo with MSVC
David Marchand (1):
dev: hide driver export macros
buildtools/gen-pmdinfo-cfile.py | 25 +++++++--
buildtools/meson.build | 2 +
buildtools/pmdinfogen.py | 11 ++--
drivers/bus/auxiliary/bus_auxiliary_driver.h | 2 +-
drivers/bus/cdx/bus_cdx_driver.h | 5 +-
drivers/bus/dpaa/bus_dpaa_driver.h | 2 +-
drivers/bus/fslmc/bus_fslmc_driver.h | 4 +-
drivers/bus/ifpga/bus_ifpga_driver.h | 2 +-
drivers/bus/pci/bus_pci_driver.h | 2 +-
drivers/bus/platform/bus_platform_driver.h | 2 +-
drivers/bus/uacce/bus_uacce_driver.h | 2 +-
drivers/bus/vdev/bus_vdev_driver.h | 2 +-
drivers/bus/vmbus/bus_vmbus_driver.h | 2 +-
drivers/common/mlx5/mlx5_common.c | 2 +-
drivers/common/mlx5/mlx5_common_pci.c | 2 +-
drivers/common/nitrox/nitrox_device.c | 1 +
drivers/compress/mlx5/mlx5_compress.c | 2 +-
drivers/crypto/mlx5/mlx5_crypto.c | 2 +-
drivers/event/octeontx/ssovf_evdev.c | 1 +
drivers/net/mlx4/mlx4.c | 2 +-
drivers/net/mlx5/mlx5.c | 2 +-
drivers/net/virtio/virtio_pci_ethdev.c | 2 +-
drivers/regex/mlx5/mlx5_regex.c | 2 +-
drivers/vdpa/mlx5/mlx5_vdpa.c | 2 +-
lib/eal/common/eal_common_options.c | 2 +-
lib/eal/include/dev_driver.h | 45 +++++++++++++++++
lib/eal/include/rte_dev.h | 41 ---------------
usertools/dpdk-pmdinfo.py | 53 ++++++++++++++++----
28 files changed, 140 insertions(+), 84 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v6 1/4] dev: hide driver export macros
2025-06-10 10:09 [PATCH v6 0/4] allow pmdinfo to be inserted and parsed using MSVC David Marchand
@ 2025-06-10 10:09 ` David Marchand
2025-06-10 10:09 ` [PATCH v6 2/4] dev: export driver information with MSVC David Marchand
` (3 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2025-06-10 10:09 UTC (permalink / raw)
To: dev; +Cc: Tyler Retzlaff
The macros for tagging/exporting informations about a driver do not need
to be exported in the public API.
Move this to driver only header.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
lib/eal/include/dev_driver.h | 41 ++++++++++++++++++++++++++++++++++++
lib/eal/include/rte_dev.h | 41 ------------------------------------
2 files changed, 41 insertions(+), 41 deletions(-)
diff --git a/lib/eal/include/dev_driver.h b/lib/eal/include/dev_driver.h
index c07d83a43a..22e48226f9 100644
--- a/lib/eal/include/dev_driver.h
+++ b/lib/eal/include/dev_driver.h
@@ -30,4 +30,45 @@ struct rte_device {
struct rte_devargs *devargs; /**< Arguments for latest probing */
};
+#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
+
+#define RTE_PMD_EXPORT_NAME(name, idx) \
+static const char RTE_PMD_EXPORT_NAME_ARRAY(this_pmd_name, idx) \
+__rte_used = RTE_STR(name)
+
+#define DRV_EXP_TAG(name, tag) __##name##_##tag
+
+#define RTE_PMD_REGISTER_PCI_TABLE(name, table) \
+static const char DRV_EXP_TAG(name, pci_tbl_export)[] __rte_used = \
+RTE_STR(table)
+
+#define RTE_PMD_REGISTER_PARAM_STRING(name, str) \
+static const char DRV_EXP_TAG(name, param_string_export)[] \
+__rte_used = str
+
+/**
+ * Advertise the list of kernel modules required to run this driver
+ *
+ * This string lists the kernel modules required for the devices
+ * associated to a PMD. The format of each line of the string is:
+ * "<device-pattern> <kmod-expression>".
+ *
+ * The possible formats for the device pattern are:
+ * "*" all devices supported by this driver
+ * "pci:*" all PCI devices supported by this driver
+ * "pci:v8086:d*:sv*:sd*" all PCI devices supported by this driver
+ * whose vendor id is 0x8086.
+ *
+ * The format of the kernel modules list is a parenthesized expression
+ * containing logical-and (&) and logical-or (|).
+ *
+ * The device pattern and the kmod expression are separated by a space.
+ *
+ * Example:
+ * - "* igb_uio | uio_pci_generic | vfio"
+ */
+#define RTE_PMD_REGISTER_KMOD_DEP(name, str) \
+static const char DRV_EXP_TAG(name, kmod_dep_export)[] \
+__rte_used = str
+
#endif /* DEV_DRIVER_H */
diff --git a/lib/eal/include/rte_dev.h b/lib/eal/include/rte_dev.h
index 738400e8d1..7eca5e8cf2 100644
--- a/lib/eal/include/rte_dev.h
+++ b/lib/eal/include/rte_dev.h
@@ -232,47 +232,6 @@ int rte_dev_remove(struct rte_device *dev);
*/
typedef int (*rte_dev_cmp_t)(const struct rte_device *dev, const void *data);
-#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
-
-#define RTE_PMD_EXPORT_NAME(name, idx) \
-static const char RTE_PMD_EXPORT_NAME_ARRAY(this_pmd_name, idx) \
-__rte_used = RTE_STR(name)
-
-#define DRV_EXP_TAG(name, tag) __##name##_##tag
-
-#define RTE_PMD_REGISTER_PCI_TABLE(name, table) \
-static const char DRV_EXP_TAG(name, pci_tbl_export)[] __rte_used = \
-RTE_STR(table)
-
-#define RTE_PMD_REGISTER_PARAM_STRING(name, str) \
-static const char DRV_EXP_TAG(name, param_string_export)[] \
-__rte_used = str
-
-/**
- * Advertise the list of kernel modules required to run this driver
- *
- * This string lists the kernel modules required for the devices
- * associated to a PMD. The format of each line of the string is:
- * "<device-pattern> <kmod-expression>".
- *
- * The possible formats for the device pattern are:
- * "*" all devices supported by this driver
- * "pci:*" all PCI devices supported by this driver
- * "pci:v8086:d*:sv*:sd*" all PCI devices supported by this driver
- * whose vendor id is 0x8086.
- *
- * The format of the kernel modules list is a parenthesized expression
- * containing logical-and (&) and logical-or (|).
- *
- * The device pattern and the kmod expression are separated by a space.
- *
- * Example:
- * - "* igb_uio | uio_pci_generic | vfio"
- */
-#define RTE_PMD_REGISTER_KMOD_DEP(name, str) \
-static const char DRV_EXP_TAG(name, kmod_dep_export)[] \
-__rte_used = str
-
/**
* Iteration context.
*
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v6 2/4] dev: export driver information with MSVC
2025-06-10 10:09 [PATCH v6 0/4] allow pmdinfo to be inserted and parsed using MSVC David Marchand
2025-06-10 10:09 ` [PATCH v6 1/4] dev: hide driver export macros David Marchand
@ 2025-06-10 10:09 ` David Marchand
2025-06-10 12:13 ` David Marchand
2025-06-10 10:09 ` [PATCH v6 3/4] buildtools: embed " David Marchand
` (2 subsequent siblings)
4 siblings, 1 reply; 17+ messages in thread
From: David Marchand @ 2025-06-10 10:09 UTC (permalink / raw)
To: dev
Cc: Andre Muezerie, Parav Pandit, Xueming Li, Nipun Gupta,
Nikhil Agarwal, Hemant Agrawal, Sachin Saxena, Rosen Xu,
Chenbo Xia, Tomasz Duszynski, Chengwen Feng, Long Li, Wei Hu,
Dariusz Sosnowski, Viacheslav Ovsiienko, Bing Zhao, Ori Kam,
Suanming Mou, Matan Azrad, Nagadheeraj Rottela, Srikanth Jampala,
Fan Zhang, Ashish Gupta, Jerin Jacob, Maxime Coquelin,
Tyler Retzlaff
From: Andre Muezerie <andremue@linux.microsoft.com>
DPDK uses GCC attribute "used" through macro __rte_used to indicate
that a variable not referenced in the code should be assumed being
used and therefore not be optimized away. This technique is used to embed
information in the binaries, by having crafted information stored in
them.
MSVC offers similar functionality, but it differs significantly: MSVC
requires a pragma to be used to send a command to the linker telling it
explicitly the name of the symbol that should be included (even if not
referenced). As a side-effect, variables called out to be included cannot
be static, otherwise their symbols are not "seen" by the linker. This
restriction requires some DPDK code to be refactored.
To assimilate these requirements/restrictions, a new macro
RTE_PMD_EXPORT_SYMBOL is added in this patch to ensure these special
variables make it to the final binaries.
The elimination of "static" for some of these variables caused name
clashes when __COUNTER__ predefined macro was used. As a workaround,
predefined macro __LINE__ was used instead.
Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
drivers/bus/auxiliary/bus_auxiliary_driver.h | 2 +-
drivers/bus/cdx/bus_cdx_driver.h | 5 ++---
drivers/bus/dpaa/bus_dpaa_driver.h | 2 +-
drivers/bus/fslmc/bus_fslmc_driver.h | 4 ++--
drivers/bus/ifpga/bus_ifpga_driver.h | 2 +-
drivers/bus/pci/bus_pci_driver.h | 2 +-
drivers/bus/platform/bus_platform_driver.h | 2 +-
drivers/bus/uacce/bus_uacce_driver.h | 2 +-
drivers/bus/vdev/bus_vdev_driver.h | 2 +-
drivers/bus/vmbus/bus_vmbus_driver.h | 2 +-
drivers/common/mlx5/mlx5_common.c | 2 +-
drivers/common/mlx5/mlx5_common_pci.c | 2 +-
drivers/common/nitrox/nitrox_device.c | 1 +
drivers/compress/mlx5/mlx5_compress.c | 2 +-
drivers/crypto/mlx5/mlx5_crypto.c | 2 +-
drivers/event/octeontx/ssovf_evdev.c | 1 +
drivers/net/mlx4/mlx4.c | 2 +-
drivers/net/mlx5/mlx5.c | 2 +-
drivers/net/virtio/virtio_pci_ethdev.c | 2 +-
drivers/regex/mlx5/mlx5_regex.c | 2 +-
drivers/vdpa/mlx5/mlx5_vdpa.c | 2 +-
lib/eal/common/eal_common_options.c | 2 +-
lib/eal/include/dev_driver.h | 22 ++++++++++++--------
23 files changed, 37 insertions(+), 32 deletions(-)
diff --git a/drivers/bus/auxiliary/bus_auxiliary_driver.h b/drivers/bus/auxiliary/bus_auxiliary_driver.h
index 40ab1f0912..5a91ddbe2e 100644
--- a/drivers/bus/auxiliary/bus_auxiliary_driver.h
+++ b/drivers/bus/auxiliary/bus_auxiliary_driver.h
@@ -168,7 +168,7 @@ void rte_auxiliary_register(struct rte_auxiliary_driver *driver);
(auxiliary_drv).driver.name = RTE_STR(nm); \
rte_auxiliary_register(&(auxiliary_drv)); \
} \
- RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+ RTE_PMD_EXPORT_NAME(nm, __LINE__)
/**
* Unregister an auxiliary driver.
diff --git a/drivers/bus/cdx/bus_cdx_driver.h b/drivers/bus/cdx/bus_cdx_driver.h
index d390e7b5a1..a89207dbbc 100644
--- a/drivers/bus/cdx/bus_cdx_driver.h
+++ b/drivers/bus/cdx/bus_cdx_driver.h
@@ -35,8 +35,7 @@ struct rte_cdx_bus;
#define RTE_CDX_ANY_ID (0xffff)
#define RTE_PMD_REGISTER_CDX_TABLE(name, table) \
-static const char DRV_EXP_TAG(name, cdx_tbl_export)[] __rte_used = \
-RTE_STR(table)
+RTE_PMD_EXPORT_SYMBOL(const char, DRV_EXP_TAG(name, cdx_tbl_export))[] = RTE_STR(table)
/** Device needs resource mapping */
#define RTE_CDX_DRV_NEED_MAPPING 0x0001
@@ -153,7 +152,7 @@ void rte_cdx_register(struct rte_cdx_driver *driver);
(cdx_drv).driver.name = RTE_STR(nm);\
rte_cdx_register(&cdx_drv); \
} \
- RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+ RTE_PMD_EXPORT_NAME(nm, __LINE__)
/**
* Enables VFIO Interrupts for CDX bus devices.
diff --git a/drivers/bus/dpaa/bus_dpaa_driver.h b/drivers/bus/dpaa/bus_dpaa_driver.h
index 26a83b2cdf..9ccc353523 100644
--- a/drivers/bus/dpaa/bus_dpaa_driver.h
+++ b/drivers/bus/dpaa/bus_dpaa_driver.h
@@ -245,7 +245,7 @@ RTE_INIT(dpaainitfn_ ##nm) \
(dpaa_drv).driver.name = RTE_STR(nm);\
rte_dpaa_driver_register(&dpaa_drv); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm, __LINE__)
__rte_internal
struct fm_eth_port_cfg *dpaa_get_eth_port_cfg(int dev_id);
diff --git a/drivers/bus/fslmc/bus_fslmc_driver.h b/drivers/bus/fslmc/bus_fslmc_driver.h
index 1d4ce4785f..33d28e5aa4 100644
--- a/drivers/bus/fslmc/bus_fslmc_driver.h
+++ b/drivers/bus/fslmc/bus_fslmc_driver.h
@@ -205,7 +205,7 @@ RTE_INIT(dpaa2initfn_ ##nm) \
(dpaa2_drv).driver.name = RTE_STR(nm);\
rte_fslmc_driver_register(&dpaa2_drv); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm, __LINE__)
/**
* Register a DPAA2 MC Object driver.
@@ -236,7 +236,7 @@ RTE_INIT(dpaa2objinitfn_ ##nm) \
(dpaa2_obj).name = RTE_STR(nm);\
rte_fslmc_object_register(&dpaa2_obj); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm, __LINE__)
#ifdef __cplusplus
}
diff --git a/drivers/bus/ifpga/bus_ifpga_driver.h b/drivers/bus/ifpga/bus_ifpga_driver.h
index 56ce34c91d..b792f8e866 100644
--- a/drivers/bus/ifpga/bus_ifpga_driver.h
+++ b/drivers/bus/ifpga/bus_ifpga_driver.h
@@ -154,7 +154,7 @@ RTE_INIT(afudrvinitfn_ ##afudrv)\
(afudrv).driver.alias = afudrvinit_ ## nm ## _alias;\
rte_ifpga_driver_register(&afudrv);\
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm, __LINE__)
#define RTE_PMD_REGISTER_AFU_ALIAS(nm, alias)\
static const char *afudrvinit_ ## nm ## _alias = RTE_STR(alias)
diff --git a/drivers/bus/pci/bus_pci_driver.h b/drivers/bus/pci/bus_pci_driver.h
index 2cc1119072..9863ae22ed 100644
--- a/drivers/bus/pci/bus_pci_driver.h
+++ b/drivers/bus/pci/bus_pci_driver.h
@@ -171,7 +171,7 @@ RTE_INIT(pciinitfn_ ##nm) \
(pci_drv).driver.name = RTE_STR(nm);\
rte_pci_register(&pci_drv); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm, __LINE__)
/**
* Unregister a PCI driver.
diff --git a/drivers/bus/platform/bus_platform_driver.h b/drivers/bus/platform/bus_platform_driver.h
index a6f246f7c4..0a2743900f 100644
--- a/drivers/bus/platform/bus_platform_driver.h
+++ b/drivers/bus/platform/bus_platform_driver.h
@@ -138,7 +138,7 @@ RTE_INIT(pdrvinitfn_ ##nm) \
(platform_drv).driver.alias = pdrvinit_ ## nm ## _alias; \
rte_platform_register(&(platform_drv)); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm, __LINE__)
/** Helper for setting platform driver alias. */
#define RTE_PMD_REGISTER_ALIAS(nm, alias) \
diff --git a/drivers/bus/uacce/bus_uacce_driver.h b/drivers/bus/uacce/bus_uacce_driver.h
index c8e177d44f..2401401322 100644
--- a/drivers/bus/uacce/bus_uacce_driver.h
+++ b/drivers/bus/uacce/bus_uacce_driver.h
@@ -245,7 +245,7 @@ void rte_uacce_unregister(struct rte_uacce_driver *driver);
(uacce_drv).driver.name = RTE_STR(nm);\
rte_uacce_register(&uacce_drv); \
} \
- RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+ RTE_PMD_EXPORT_NAME(nm, __LINE__)
#ifdef __cplusplus
}
diff --git a/drivers/bus/vdev/bus_vdev_driver.h b/drivers/bus/vdev/bus_vdev_driver.h
index cba1fb5269..d46f45386e 100644
--- a/drivers/bus/vdev/bus_vdev_driver.h
+++ b/drivers/bus/vdev/bus_vdev_driver.h
@@ -139,7 +139,7 @@ RTE_INIT(vdrvinitfn_ ##vdrv)\
(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
rte_vdev_register(&vdrv);\
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm, __LINE__)
#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
diff --git a/drivers/bus/vmbus/bus_vmbus_driver.h b/drivers/bus/vmbus/bus_vmbus_driver.h
index 0a56275437..3bd93b95d1 100644
--- a/drivers/bus/vmbus/bus_vmbus_driver.h
+++ b/drivers/bus/vmbus/bus_vmbus_driver.h
@@ -101,7 +101,7 @@ void rte_vmbus_unregister(struct rte_vmbus_driver *driver);
(vmbus_drv).driver.name = RTE_STR(nm); \
rte_vmbus_register(&vmbus_drv); \
} \
- RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+ RTE_PMD_EXPORT_NAME(nm, __LINE__)
#ifdef __cplusplus
}
diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c
index 4f25127582..ebe327a950 100644
--- a/drivers/common/mlx5/mlx5_common.c
+++ b/drivers/common/mlx5/mlx5_common.c
@@ -1452,4 +1452,4 @@ mlx5_devx_uar_prepare(struct mlx5_common_device *cdev, struct mlx5_uar *uar)
return 0;
}
-RTE_PMD_EXPORT_NAME(mlx5_common_driver, __COUNTER__);
+RTE_PMD_EXPORT_NAME(mlx5_common_driver, __LINE__);
diff --git a/drivers/common/mlx5/mlx5_common_pci.c b/drivers/common/mlx5/mlx5_common_pci.c
index 819b799bb8..22de17ae67 100644
--- a/drivers/common/mlx5/mlx5_common_pci.c
+++ b/drivers/common/mlx5/mlx5_common_pci.c
@@ -245,4 +245,4 @@ RTE_FINI(mlx5_common_pci_finish)
}
}
-RTE_PMD_EXPORT_NAME(mlx5_common_pci, __COUNTER__);
+RTE_PMD_EXPORT_NAME(mlx5_common_pci, __LINE__);
diff --git a/drivers/common/nitrox/nitrox_device.c b/drivers/common/nitrox/nitrox_device.c
index 74c7a859a4..22c5d64446 100644
--- a/drivers/common/nitrox/nitrox_device.c
+++ b/drivers/common/nitrox/nitrox_device.c
@@ -144,5 +144,6 @@ static struct rte_pci_driver nitrox_pmd = {
.remove = nitrox_pci_remove,
};
+/* Blank line to get unique ID */
RTE_PMD_REGISTER_PCI(nitrox, nitrox_pmd);
RTE_PMD_REGISTER_PCI_TABLE(nitrox, pci_id_nitrox_map);
diff --git a/drivers/compress/mlx5/mlx5_compress.c b/drivers/compress/mlx5/mlx5_compress.c
index 82105bfebd..17017863a4 100644
--- a/drivers/compress/mlx5/mlx5_compress.c
+++ b/drivers/compress/mlx5/mlx5_compress.c
@@ -937,6 +937,6 @@ RTE_INIT(rte_mlx5_compress_init)
}
RTE_LOG_REGISTER_DEFAULT(mlx5_compress_logtype, NOTICE)
-RTE_PMD_EXPORT_NAME(MLX5_COMPRESS_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_COMPRESS_DRIVER_NAME, __LINE__);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_COMPRESS_DRIVER_NAME, mlx5_compress_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_COMPRESS_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/drivers/crypto/mlx5/mlx5_crypto.c b/drivers/crypto/mlx5/mlx5_crypto.c
index 2319c6920d..4fb7060bd0 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.c
+++ b/drivers/crypto/mlx5/mlx5_crypto.c
@@ -514,6 +514,6 @@ RTE_PMD_REGISTER_CRYPTO_DRIVER(mlx5_cryptodev_driver, mlx5_drv,
mlx5_crypto_driver_id);
RTE_LOG_REGISTER_DEFAULT(mlx5_crypto_logtype, NOTICE)
-RTE_PMD_EXPORT_NAME(MLX5_CRYPTO_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_CRYPTO_DRIVER_NAME, __LINE__);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_CRYPTO_DRIVER_NAME, mlx5_crypto_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_CRYPTO_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/drivers/event/octeontx/ssovf_evdev.c b/drivers/event/octeontx/ssovf_evdev.c
index 957fcab04e..c8881f5375 100644
--- a/drivers/event/octeontx/ssovf_evdev.c
+++ b/drivers/event/octeontx/ssovf_evdev.c
@@ -971,4 +971,5 @@ static struct rte_vdev_driver vdev_ssovf_pmd = {
.remove = ssovf_vdev_remove
};
+/* Blank line to get unique ID */
RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_OCTEONTX_PMD, vdev_ssovf_pmd);
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 9c2872429f..0e7d8cdd6c 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -1385,7 +1385,7 @@ RTE_INIT(rte_mlx4_pmd_init)
rte_pci_register(&mlx4_driver);
}
-RTE_PMD_EXPORT_NAME(net_mlx4, __COUNTER__);
+RTE_PMD_EXPORT_NAME(net_mlx4, __LINE__);
RTE_PMD_REGISTER_PCI_TABLE(net_mlx4, mlx4_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(net_mlx4,
"* ib_uverbs & mlx4_en & mlx4_core & mlx4_ib");
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b4bd43aae2..03a75fc0ec 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -3819,6 +3819,6 @@ RTE_INIT(rte_mlx5_pmd_init)
mlx5_class_driver_register(&mlx5_net_driver);
}
-RTE_PMD_EXPORT_NAME(MLX5_ETH_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_ETH_DRIVER_NAME, __LINE__);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_ETH_DRIVER_NAME, mlx5_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_ETH_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
index 9b4b846f8a..a0ba770901 100644
--- a/drivers/net/virtio/virtio_pci_ethdev.c
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -239,4 +239,4 @@ RTE_INIT(rte_virtio_net_pci_pmd_init)
RTE_PMD_REGISTER_PCI_TABLE(net_virtio, pci_id_virtio_map);
RTE_PMD_REGISTER_KMOD_DEP(net_virtio, "* igb_uio | uio_pci_generic | vfio-pci");
-RTE_PMD_EXPORT_NAME(net_virtio, __COUNTER__);
+RTE_PMD_EXPORT_NAME(net_virtio, __LINE__);
diff --git a/drivers/regex/mlx5/mlx5_regex.c b/drivers/regex/mlx5/mlx5_regex.c
index 4ed62b538b..238676586c 100644
--- a/drivers/regex/mlx5/mlx5_regex.c
+++ b/drivers/regex/mlx5/mlx5_regex.c
@@ -183,6 +183,6 @@ RTE_INIT(rte_mlx5_regex_init)
}
RTE_LOG_REGISTER_DEFAULT(mlx5_regex_logtype, NOTICE)
-RTE_PMD_EXPORT_NAME(MLX5_REGEX_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_REGEX_DRIVER_NAME, __LINE__);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_REGEX_DRIVER_NAME, mlx5_regex_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_REGEX_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c
index 98c39a5e64..3450634ea9 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa.c
@@ -1003,6 +1003,6 @@ RTE_INIT(rte_mlx5_vdpa_init)
mlx5_class_driver_register(&mlx5_vdpa_driver);
}
-RTE_PMD_EXPORT_NAME(MLX5_VDPA_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_VDPA_DRIVER_NAME, __LINE__);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_VDPA_DRIVER_NAME, mlx5_vdpa_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_VDPA_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
index b4f0e23a9c..83b6fc7e89 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -137,7 +137,7 @@ static const char *default_solib_dir = RTE_EAL_PMD_PATH;
* Note: PLEASE DO NOT ALTER THIS without making a corresponding
* change to usertools/dpdk-pmdinfo.py
*/
-static const char dpdk_solib_path[] __rte_used =
+RTE_PMD_EXPORT_SYMBOL(const char, dpdk_solib_path)[] =
"DPDK_PLUGIN_PATH=" RTE_EAL_PMD_PATH;
TAILQ_HEAD(device_option_list, device_option);
diff --git a/lib/eal/include/dev_driver.h b/lib/eal/include/dev_driver.h
index 22e48226f9..3846025e63 100644
--- a/lib/eal/include/dev_driver.h
+++ b/lib/eal/include/dev_driver.h
@@ -30,21 +30,26 @@ struct rte_device {
struct rte_devargs *devargs; /**< Arguments for latest probing */
};
-#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
+#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx
+
+#ifdef RTE_TOOLCHAIN_MSVC
+#define RTE_PMD_EXPORT_SYMBOL(type, name) \
+__pragma(comment(linker, "/include:" RTE_STR(name))) type name
+#else
+#define RTE_PMD_EXPORT_SYMBOL(type, name) \
+__attribute__((used)) type name
+#endif
#define RTE_PMD_EXPORT_NAME(name, idx) \
-static const char RTE_PMD_EXPORT_NAME_ARRAY(this_pmd_name, idx) \
-__rte_used = RTE_STR(name)
+RTE_PMD_EXPORT_SYMBOL(const char, RTE_PMD_EXPORT_NAME_ARRAY(this_pmd_name, idx))[] = RTE_STR(name)
#define DRV_EXP_TAG(name, tag) __##name##_##tag
#define RTE_PMD_REGISTER_PCI_TABLE(name, table) \
-static const char DRV_EXP_TAG(name, pci_tbl_export)[] __rte_used = \
-RTE_STR(table)
+RTE_PMD_EXPORT_SYMBOL(const char, DRV_EXP_TAG(name, pci_tbl_export))[] = RTE_STR(table)
#define RTE_PMD_REGISTER_PARAM_STRING(name, str) \
-static const char DRV_EXP_TAG(name, param_string_export)[] \
-__rte_used = str
+RTE_PMD_EXPORT_SYMBOL(const char, DRV_EXP_TAG(name, param_string_export))[] = str
/**
* Advertise the list of kernel modules required to run this driver
@@ -68,7 +73,6 @@ __rte_used = str
* - "* igb_uio | uio_pci_generic | vfio"
*/
#define RTE_PMD_REGISTER_KMOD_DEP(name, str) \
-static const char DRV_EXP_TAG(name, kmod_dep_export)[] \
-__rte_used = str
+RTE_PMD_EXPORT_SYMBOL(const char, DRV_EXP_TAG(name, kmod_dep_export))[] = str
#endif /* DEV_DRIVER_H */
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v6 3/4] buildtools: embed driver information with MSVC
2025-06-10 10:09 [PATCH v6 0/4] allow pmdinfo to be inserted and parsed using MSVC David Marchand
2025-06-10 10:09 ` [PATCH v6 1/4] dev: hide driver export macros David Marchand
2025-06-10 10:09 ` [PATCH v6 2/4] dev: export driver information with MSVC David Marchand
@ 2025-06-10 10:09 ` David Marchand
2025-06-10 10:09 ` [PATCH v6 4/4] usertools: enable pmdinfo " David Marchand
2025-06-11 9:45 ` [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC David Marchand
4 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2025-06-10 10:09 UTC (permalink / raw)
To: dev; +Cc: Andre Muezerie, Dmitry Kozlyuk
From: Andre Muezerie <andremue@linux.microsoft.com>
The archiver tool from the MSVC toolset is lib.exe. It has different
parameters then it's GNU counterpart "ar".
buildtools\meson.build was updated to use lib.exe when MSVC compiler is
used. This is to allow the code to be built without requiring GNU "ar"
to be installed in that scenario.
Script gen-pmdinfo-cfile.py was updated to use the correct parameters
when using lib.exe.
Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
---
buildtools/gen-pmdinfo-cfile.py | 25 ++++++++++++++++++++-----
buildtools/meson.build | 2 ++
buildtools/pmdinfogen.py | 11 ++++++-----
3 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/buildtools/gen-pmdinfo-cfile.py b/buildtools/gen-pmdinfo-cfile.py
index 8ffc192c40..5d2e8e076e 100644
--- a/buildtools/gen-pmdinfo-cfile.py
+++ b/buildtools/gen-pmdinfo-cfile.py
@@ -6,16 +6,31 @@
import subprocess
import sys
-_, ar, tmp_dir, archive, output, *pmdinfogen = sys.argv
+_, archiver, tmp_dir, archive, output, *pmdinfogen = sys.argv
paths = []
-for name in subprocess.run([ar, "t", archive], stdout=subprocess.PIPE,
- check=True).stdout.decode().splitlines():
+if archiver == "lib":
+ archiver_options = ["/LIST", "/NOLOGO"]
+else:
+ archiver_options = ["t"]
+
+for name in (
+ subprocess.run(
+ [archiver] + archiver_options + [archive],
+ stdout=subprocess.PIPE,
+ check=True,
+ )
+ .stdout.decode()
+ .splitlines()
+):
if os.path.exists(name):
paths.append(name)
else:
if not os.path.exists(tmp_dir):
os.makedirs(tmp_dir)
- subprocess.run([ar, "x", os.path.abspath(archive), name],
- check=True, cwd=tmp_dir)
+ if archiver == "lib":
+ run_args = [archiver, f"/EXTRACT:{name}", os.path.abspath(archive)]
+ else:
+ run_args = [archiver, "x", os.path.abspath(archive), name]
+ subprocess.run(run_args, check=True, cwd=tmp_dir)
paths.append(os.path.join(tmp_dir, name))
subprocess.run(pmdinfogen + paths + [output], check=True)
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 822e79502a..7b5e449cdb 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -44,6 +44,8 @@ pmdinfogen = py3 + files('pmdinfogen.py')
if host_machine.system() == 'windows'
if cc.get_id() == 'gcc'
pmdinfo += 'ar'
+ elif cc.get_id() == 'msvc'
+ pmdinfo += 'lib'
else
pmdinfo += 'llvm-ar'
endif
diff --git a/buildtools/pmdinfogen.py b/buildtools/pmdinfogen.py
index dfb89500c0..68db9e5fb6 100755
--- a/buildtools/pmdinfogen.py
+++ b/buildtools/pmdinfogen.py
@@ -87,7 +87,7 @@ def get_value(self, offset, size):
@property
def string_value(self):
value = self._symbol.get_value(0)
- return coff.decode_asciiz(value) if value else ''
+ return coff.decode_asciiz(value) if value else ""
class COFFImage:
@@ -192,7 +192,7 @@ def dump(self, file):
dumped = json.dumps(self.__dict__)
escaped = dumped.replace('"', '\\"')
print(
- 'const char %s_pmd_info[] __attribute__((used)) = "PMD_INFO_STRING= %s";'
+ 'RTE_PMD_EXPORT_SYMBOL(const char, %s_pmd_info)[] = "PMD_INFO_STRING= %s";'
% (self.name, escaped),
file=file,
)
@@ -215,7 +215,7 @@ def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("format", help="object file format, 'elf' or 'coff'")
parser.add_argument(
- "input", nargs='+', help="input object file path or '-' for stdin"
+ "input", nargs="+", help="input object file path or '-' for stdin"
)
parser.add_argument("output", help="output C file path or '-' for stdout")
return parser.parse_args()
@@ -252,13 +252,14 @@ def open_output(path):
def write_header(output):
output.write(
- "static __attribute__((unused)) const char *generator = \"%s\";\n" % sys.argv[0]
+ "#include <dev_driver.h>\n"
+ 'static __rte_unused const char *generator = "%s";\n' % sys.argv[0]
)
def main():
args = parse_args()
- if args.input.count('-') > 1:
+ if args.input.count("-") > 1:
raise Exception("'-' input cannot be used multiple times")
if args.format == "elf" and "ELFFile" not in globals():
raise Exception("elftools module not found")
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v6 4/4] usertools: enable pmdinfo with MSVC
2025-06-10 10:09 [PATCH v6 0/4] allow pmdinfo to be inserted and parsed using MSVC David Marchand
` (2 preceding siblings ...)
2025-06-10 10:09 ` [PATCH v6 3/4] buildtools: embed " David Marchand
@ 2025-06-10 10:09 ` David Marchand
2025-06-10 10:17 ` Robin Jarry
2025-06-11 9:45 ` [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC David Marchand
4 siblings, 1 reply; 17+ messages in thread
From: David Marchand @ 2025-06-10 10:09 UTC (permalink / raw)
To: dev; +Cc: Andre Muezerie, Dmitry Kozlyuk, Robin Jarry
From: Andre Muezerie <andremue@linux.microsoft.com>
Script usertools\dpdk-pmdinfo.py was enhanced to also be able to parse
symbols from sections in PE images.
Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
---
usertools/dpdk-pmdinfo.py | 53 +++++++++++++++++++++++++++++++--------
1 file changed, 43 insertions(+), 10 deletions(-)
diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index 9189a2fdbc..9251c69db9 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -37,8 +37,11 @@
from pathlib import Path
from typing import Iterable, Iterator, List, Union
-import elftools
-from elftools.elf.elffile import ELFError, ELFFile
+if os.name == "nt":
+ import pefile
+else:
+ import elftools
+ from elftools.elf.elffile import ELFError, ELFFile
# ----------------------------------------------------------------------------
@@ -114,18 +117,23 @@ def parse_pmdinfo(paths: Iterable[Path], search_plugins: bool) -> List[dict]:
A list of DPDK drivers info dictionaries.
"""
binaries = set(paths)
- for p in paths:
- binaries.update(get_needed_libs(p))
- if search_plugins:
- # cast to list to avoid errors with update while iterating
- binaries.update(list(get_plugin_libs(binaries)))
+
+ if os.name == "nt":
+ section_name = ".rdata"
+ else:
+ section_name = ".rodata"
+ for p in paths:
+ binaries.update(get_needed_libs(p))
+ if search_plugins:
+ # cast to list to avoid errors with update while iterating
+ binaries.update(list(get_plugin_libs(binaries)))
drivers = []
for b in binaries:
logging.debug("analyzing %s", b)
try:
- for s in get_elf_strings(b, ".rodata", "PMD_INFO_STRING="):
+ for s in get_section_strings(b, section_name, "PMD_INFO_STRING="):
try:
info = json.loads(s)
scrub_pci_ids(info)
@@ -214,7 +222,7 @@ def find_strings(buf: bytes, prefix: str) -> Iterator[str]:
# end of string
s = view[start:i].tobytes().decode("ascii")
if s.startswith(prefix):
- yield s[len(prefix):]
+ yield s[len(prefix) :]
# There can be byte sequences where a non-printable byte
# follows a printable one. Ignore that.
start = None
@@ -233,7 +241,8 @@ def elftools_version():
return (int(match[1]), int(match[2]))
-ELFTOOLS_VERSION = elftools_version()
+if os.name != "nt":
+ ELFTOOLS_VERSION = elftools_version()
def from_elftools(s: Union[bytes, str]) -> str:
@@ -269,6 +278,30 @@ def get_elf_strings(path: Path, section: str, prefix: str) -> Iterator[str]:
yield from find_strings(sec.data(), prefix)
+# ----------------------------------------------------------------------------
+def get_pe_strings(path: Path, section: str, prefix: str) -> Iterator[str]:
+ """
+ Extract strings from a named PE section in a file.
+ """
+ pe = pefile.PE(path)
+ for sec in pe.sections:
+ section_name = sec.Name.decode().strip("\x00")
+ if section_name != section:
+ continue
+ yield from find_strings(sec.get_data(), prefix)
+
+
+# ----------------------------------------------------------------------------
+def get_section_strings(path: Path, section: str, prefix: str) -> Iterator[str]:
+ """
+ Extract strings from a named section in an ELF or PE file.
+ """
+ if os.name == "nt":
+ yield from get_pe_strings(path, section, prefix)
+ else:
+ yield from get_elf_strings(path, section, prefix)
+
+
# ----------------------------------------------------------------------------
LDD_LIB_RE = re.compile(
r"""
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v6 4/4] usertools: enable pmdinfo with MSVC
2025-06-10 10:09 ` [PATCH v6 4/4] usertools: enable pmdinfo " David Marchand
@ 2025-06-10 10:17 ` Robin Jarry
0 siblings, 0 replies; 17+ messages in thread
From: Robin Jarry @ 2025-06-10 10:17 UTC (permalink / raw)
To: David Marchand, dev; +Cc: Andre Muezerie, Dmitry Kozlyuk
David Marchand, Jun 10, 2025 at 12:09:
> From: Andre Muezerie <andremue@linux.microsoft.com>
>
> Script usertools\dpdk-pmdinfo.py was enhanced to also be able to parse
> symbols from sections in PE images.
>
> Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
> ---
Acked-by: Robin Jarry <rjarry@redhat.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v6 2/4] dev: export driver information with MSVC
2025-06-10 10:09 ` [PATCH v6 2/4] dev: export driver information with MSVC David Marchand
@ 2025-06-10 12:13 ` David Marchand
0 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2025-06-10 12:13 UTC (permalink / raw)
To: Andre Muezerie, Thomas Monjalon
Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
Hemant Agrawal, Sachin Saxena, Rosen Xu, Chenbo Xia,
Tomasz Duszynski, Chengwen Feng, Long Li, Wei Hu,
Dariusz Sosnowski, Viacheslav Ovsiienko, Bing Zhao, Ori Kam,
Suanming Mou, Matan Azrad, Nagadheeraj Rottela, Srikanth Jampala,
Fan Zhang, Ashish Gupta, Jerin Jacob, Maxime Coquelin,
Tyler Retzlaff
On Tue, Jun 10, 2025 at 12:10 PM David Marchand
<david.marchand@redhat.com> wrote:
>
> From: Andre Muezerie <andremue@linux.microsoft.com>
>
> DPDK uses GCC attribute "used" through macro __rte_used to indicate
> that a variable not referenced in the code should be assumed being
> used and therefore not be optimized away. This technique is used to embed
> information in the binaries, by having crafted information stored in
> them.
>
> MSVC offers similar functionality, but it differs significantly: MSVC
> requires a pragma to be used to send a command to the linker telling it
> explicitly the name of the symbol that should be included (even if not
> referenced). As a side-effect, variables called out to be included cannot
> be static, otherwise their symbols are not "seen" by the linker. This
> restriction requires some DPDK code to be refactored.
>
> To assimilate these requirements/restrictions, a new macro
> RTE_PMD_EXPORT_SYMBOL is added in this patch to ensure these special
> variables make it to the final binaries.
>
> The elimination of "static" for some of these variables caused name
> clashes when __COUNTER__ predefined macro was used. As a workaround,
> predefined macro __LINE__ was used instead.
We only need unique symbol names, and the driver name itself is unique.
It is probably more robust than __LINE__ (that is likely to change..).
I'll send a followup patch on this topic for rc2.
>
> Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
--
David Marchand
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC
2025-06-10 10:09 [PATCH v6 0/4] allow pmdinfo to be inserted and parsed using MSVC David Marchand
` (3 preceding siblings ...)
2025-06-10 10:09 ` [PATCH v6 4/4] usertools: enable pmdinfo " David Marchand
@ 2025-06-11 9:45 ` David Marchand
2025-06-11 9:45 ` [PATCH v7 1/5] dev: hide driver export macros David Marchand
` (4 more replies)
4 siblings, 5 replies; 17+ messages in thread
From: David Marchand @ 2025-06-11 9:45 UTC (permalink / raw)
To: dev
This is a rework of Andre v5, trying to hide the ugly details in a
driver only macro not exposed publicly.
--
David Marchand
Changes since v6:
- changed this_pmd_name symbols construction,
Changes since v5:
- moved details in dev_driver.h,
- renamed RTE_INCLUDE as RTE_PMD_EXPORT_SYMBOL,
Andre Muezerie (3):
dev: export driver information with MSVC
buildtools: embed driver information with MSVC
usertools: enable pmdinfo with MSVC
David Marchand (2):
dev: hide driver export macros
dev: rename pmdinfo internal symbols
buildtools/gen-pmdinfo-cfile.py | 25 +++++++--
buildtools/meson.build | 2 +
buildtools/pmdinfogen.py | 13 ++---
drivers/bus/auxiliary/bus_auxiliary_driver.h | 2 +-
drivers/bus/cdx/bus_cdx_driver.h | 5 +-
drivers/bus/dpaa/bus_dpaa_driver.h | 2 +-
drivers/bus/fslmc/bus_fslmc_driver.h | 4 +-
drivers/bus/ifpga/bus_ifpga_driver.h | 2 +-
drivers/bus/pci/bus_pci_driver.h | 2 +-
drivers/bus/platform/bus_platform_driver.h | 2 +-
drivers/bus/uacce/bus_uacce_driver.h | 2 +-
drivers/bus/vdev/bus_vdev_driver.h | 2 +-
drivers/bus/vmbus/bus_vmbus_driver.h | 2 +-
drivers/common/mlx5/mlx5_common.c | 2 +-
drivers/common/mlx5/mlx5_common_pci.c | 2 +-
drivers/compress/mlx5/mlx5_compress.c | 2 +-
drivers/crypto/mlx5/mlx5_crypto.c | 2 +-
drivers/net/mlx4/mlx4.c | 2 +-
drivers/net/mlx5/mlx5.c | 2 +-
drivers/net/virtio/virtio_pci_ethdev.c | 2 +-
drivers/regex/mlx5/mlx5_regex.c | 2 +-
drivers/vdpa/mlx5/mlx5_vdpa.c | 2 +-
lib/eal/common/eal_common_options.c | 2 +-
lib/eal/include/dev_driver.h | 43 ++++++++++++++++
lib/eal/include/rte_dev.h | 41 ---------------
usertools/dpdk-pmdinfo.py | 53 ++++++++++++++++----
26 files changed, 137 insertions(+), 85 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v7 1/5] dev: hide driver export macros
2025-06-11 9:45 ` [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC David Marchand
@ 2025-06-11 9:45 ` David Marchand
2025-06-11 13:24 ` Andre Muezerie
2025-06-11 9:45 ` [PATCH v7 2/5] dev: rename pmdinfo internal symbols David Marchand
` (3 subsequent siblings)
4 siblings, 1 reply; 17+ messages in thread
From: David Marchand @ 2025-06-11 9:45 UTC (permalink / raw)
To: dev; +Cc: Tyler Retzlaff
The macros for tagging/exporting informations about a driver do not need
to be exported in the public API.
Move this to driver only header.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
lib/eal/include/dev_driver.h | 41 ++++++++++++++++++++++++++++++++++++
lib/eal/include/rte_dev.h | 41 ------------------------------------
2 files changed, 41 insertions(+), 41 deletions(-)
diff --git a/lib/eal/include/dev_driver.h b/lib/eal/include/dev_driver.h
index c07d83a43a..22e48226f9 100644
--- a/lib/eal/include/dev_driver.h
+++ b/lib/eal/include/dev_driver.h
@@ -30,4 +30,45 @@ struct rte_device {
struct rte_devargs *devargs; /**< Arguments for latest probing */
};
+#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
+
+#define RTE_PMD_EXPORT_NAME(name, idx) \
+static const char RTE_PMD_EXPORT_NAME_ARRAY(this_pmd_name, idx) \
+__rte_used = RTE_STR(name)
+
+#define DRV_EXP_TAG(name, tag) __##name##_##tag
+
+#define RTE_PMD_REGISTER_PCI_TABLE(name, table) \
+static const char DRV_EXP_TAG(name, pci_tbl_export)[] __rte_used = \
+RTE_STR(table)
+
+#define RTE_PMD_REGISTER_PARAM_STRING(name, str) \
+static const char DRV_EXP_TAG(name, param_string_export)[] \
+__rte_used = str
+
+/**
+ * Advertise the list of kernel modules required to run this driver
+ *
+ * This string lists the kernel modules required for the devices
+ * associated to a PMD. The format of each line of the string is:
+ * "<device-pattern> <kmod-expression>".
+ *
+ * The possible formats for the device pattern are:
+ * "*" all devices supported by this driver
+ * "pci:*" all PCI devices supported by this driver
+ * "pci:v8086:d*:sv*:sd*" all PCI devices supported by this driver
+ * whose vendor id is 0x8086.
+ *
+ * The format of the kernel modules list is a parenthesized expression
+ * containing logical-and (&) and logical-or (|).
+ *
+ * The device pattern and the kmod expression are separated by a space.
+ *
+ * Example:
+ * - "* igb_uio | uio_pci_generic | vfio"
+ */
+#define RTE_PMD_REGISTER_KMOD_DEP(name, str) \
+static const char DRV_EXP_TAG(name, kmod_dep_export)[] \
+__rte_used = str
+
#endif /* DEV_DRIVER_H */
diff --git a/lib/eal/include/rte_dev.h b/lib/eal/include/rte_dev.h
index 738400e8d1..7eca5e8cf2 100644
--- a/lib/eal/include/rte_dev.h
+++ b/lib/eal/include/rte_dev.h
@@ -232,47 +232,6 @@ int rte_dev_remove(struct rte_device *dev);
*/
typedef int (*rte_dev_cmp_t)(const struct rte_device *dev, const void *data);
-#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
-
-#define RTE_PMD_EXPORT_NAME(name, idx) \
-static const char RTE_PMD_EXPORT_NAME_ARRAY(this_pmd_name, idx) \
-__rte_used = RTE_STR(name)
-
-#define DRV_EXP_TAG(name, tag) __##name##_##tag
-
-#define RTE_PMD_REGISTER_PCI_TABLE(name, table) \
-static const char DRV_EXP_TAG(name, pci_tbl_export)[] __rte_used = \
-RTE_STR(table)
-
-#define RTE_PMD_REGISTER_PARAM_STRING(name, str) \
-static const char DRV_EXP_TAG(name, param_string_export)[] \
-__rte_used = str
-
-/**
- * Advertise the list of kernel modules required to run this driver
- *
- * This string lists the kernel modules required for the devices
- * associated to a PMD. The format of each line of the string is:
- * "<device-pattern> <kmod-expression>".
- *
- * The possible formats for the device pattern are:
- * "*" all devices supported by this driver
- * "pci:*" all PCI devices supported by this driver
- * "pci:v8086:d*:sv*:sd*" all PCI devices supported by this driver
- * whose vendor id is 0x8086.
- *
- * The format of the kernel modules list is a parenthesized expression
- * containing logical-and (&) and logical-or (|).
- *
- * The device pattern and the kmod expression are separated by a space.
- *
- * Example:
- * - "* igb_uio | uio_pci_generic | vfio"
- */
-#define RTE_PMD_REGISTER_KMOD_DEP(name, str) \
-static const char DRV_EXP_TAG(name, kmod_dep_export)[] \
-__rte_used = str
-
/**
* Iteration context.
*
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v7 2/5] dev: rename pmdinfo internal symbols
2025-06-11 9:45 ` [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC David Marchand
2025-06-11 9:45 ` [PATCH v7 1/5] dev: hide driver export macros David Marchand
@ 2025-06-11 9:45 ` David Marchand
2025-06-11 13:26 ` Andre Muezerie
2025-06-11 9:45 ` [PATCH v7 3/5] dev: export driver information with MSVC David Marchand
` (2 subsequent siblings)
4 siblings, 1 reply; 17+ messages in thread
From: David Marchand @ 2025-06-11 9:45 UTC (permalink / raw)
To: dev
Cc: Dmitry Kozlyuk, Parav Pandit, Xueming Li, Nipun Gupta,
Nikhil Agarwal, Hemant Agrawal, Sachin Saxena, Rosen Xu,
Chenbo Xia, Tomasz Duszynski, Chengwen Feng, Long Li, Wei Hu,
Dariusz Sosnowski, Viacheslav Ovsiienko, Bing Zhao, Ori Kam,
Suanming Mou, Matan Azrad, Fan Zhang, Ashish Gupta,
Maxime Coquelin, Tyler Retzlaff
__COUNTER__ is not supported by MSVC.
Plus the this_pmd_name* symbols will become global (again for MSVC) in a
next commit.
Prefer the driver name to generate a unique symbol.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
buildtools/pmdinfogen.py | 2 +-
drivers/bus/auxiliary/bus_auxiliary_driver.h | 2 +-
drivers/bus/cdx/bus_cdx_driver.h | 2 +-
drivers/bus/dpaa/bus_dpaa_driver.h | 2 +-
drivers/bus/fslmc/bus_fslmc_driver.h | 4 ++--
drivers/bus/ifpga/bus_ifpga_driver.h | 2 +-
drivers/bus/pci/bus_pci_driver.h | 2 +-
drivers/bus/platform/bus_platform_driver.h | 2 +-
drivers/bus/uacce/bus_uacce_driver.h | 2 +-
drivers/bus/vdev/bus_vdev_driver.h | 2 +-
drivers/bus/vmbus/bus_vmbus_driver.h | 2 +-
drivers/common/mlx5/mlx5_common.c | 2 +-
drivers/common/mlx5/mlx5_common_pci.c | 2 +-
drivers/compress/mlx5/mlx5_compress.c | 2 +-
drivers/crypto/mlx5/mlx5_crypto.c | 2 +-
drivers/net/mlx4/mlx4.c | 2 +-
drivers/net/mlx5/mlx5.c | 2 +-
drivers/net/virtio/virtio_pci_ethdev.c | 2 +-
drivers/regex/mlx5/mlx5_regex.c | 2 +-
drivers/vdpa/mlx5/mlx5_vdpa.c | 2 +-
lib/eal/include/dev_driver.h | 7 ++-----
21 files changed, 23 insertions(+), 26 deletions(-)
diff --git a/buildtools/pmdinfogen.py b/buildtools/pmdinfogen.py
index dfb89500c0..7be2e39dd2 100755
--- a/buildtools/pmdinfogen.py
+++ b/buildtools/pmdinfogen.py
@@ -200,7 +200,7 @@ def dump(self, file):
def load_drivers(image):
drivers = []
- for symbol in image.find_by_pattern("^this_pmd_name[0-9]+$"):
+ for symbol in image.find_by_pattern("^this_pmd_name[0-9a-zA-Z_]+$"):
drivers.append(Driver.load(image, symbol))
return drivers
diff --git a/drivers/bus/auxiliary/bus_auxiliary_driver.h b/drivers/bus/auxiliary/bus_auxiliary_driver.h
index 40ab1f0912..1dc814151e 100644
--- a/drivers/bus/auxiliary/bus_auxiliary_driver.h
+++ b/drivers/bus/auxiliary/bus_auxiliary_driver.h
@@ -168,7 +168,7 @@ void rte_auxiliary_register(struct rte_auxiliary_driver *driver);
(auxiliary_drv).driver.name = RTE_STR(nm); \
rte_auxiliary_register(&(auxiliary_drv)); \
} \
- RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+ RTE_PMD_EXPORT_NAME(nm)
/**
* Unregister an auxiliary driver.
diff --git a/drivers/bus/cdx/bus_cdx_driver.h b/drivers/bus/cdx/bus_cdx_driver.h
index d390e7b5a1..4febf1fd3b 100644
--- a/drivers/bus/cdx/bus_cdx_driver.h
+++ b/drivers/bus/cdx/bus_cdx_driver.h
@@ -153,7 +153,7 @@ void rte_cdx_register(struct rte_cdx_driver *driver);
(cdx_drv).driver.name = RTE_STR(nm);\
rte_cdx_register(&cdx_drv); \
} \
- RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+ RTE_PMD_EXPORT_NAME(nm)
/**
* Enables VFIO Interrupts for CDX bus devices.
diff --git a/drivers/bus/dpaa/bus_dpaa_driver.h b/drivers/bus/dpaa/bus_dpaa_driver.h
index 26a83b2cdf..325071dc0f 100644
--- a/drivers/bus/dpaa/bus_dpaa_driver.h
+++ b/drivers/bus/dpaa/bus_dpaa_driver.h
@@ -245,7 +245,7 @@ RTE_INIT(dpaainitfn_ ##nm) \
(dpaa_drv).driver.name = RTE_STR(nm);\
rte_dpaa_driver_register(&dpaa_drv); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm)
__rte_internal
struct fm_eth_port_cfg *dpaa_get_eth_port_cfg(int dev_id);
diff --git a/drivers/bus/fslmc/bus_fslmc_driver.h b/drivers/bus/fslmc/bus_fslmc_driver.h
index 1d4ce4785f..442de1a3fb 100644
--- a/drivers/bus/fslmc/bus_fslmc_driver.h
+++ b/drivers/bus/fslmc/bus_fslmc_driver.h
@@ -205,7 +205,7 @@ RTE_INIT(dpaa2initfn_ ##nm) \
(dpaa2_drv).driver.name = RTE_STR(nm);\
rte_fslmc_driver_register(&dpaa2_drv); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm)
/**
* Register a DPAA2 MC Object driver.
@@ -236,7 +236,7 @@ RTE_INIT(dpaa2objinitfn_ ##nm) \
(dpaa2_obj).name = RTE_STR(nm);\
rte_fslmc_object_register(&dpaa2_obj); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm)
#ifdef __cplusplus
}
diff --git a/drivers/bus/ifpga/bus_ifpga_driver.h b/drivers/bus/ifpga/bus_ifpga_driver.h
index 56ce34c91d..d34ab8cec1 100644
--- a/drivers/bus/ifpga/bus_ifpga_driver.h
+++ b/drivers/bus/ifpga/bus_ifpga_driver.h
@@ -154,7 +154,7 @@ RTE_INIT(afudrvinitfn_ ##afudrv)\
(afudrv).driver.alias = afudrvinit_ ## nm ## _alias;\
rte_ifpga_driver_register(&afudrv);\
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm)
#define RTE_PMD_REGISTER_AFU_ALIAS(nm, alias)\
static const char *afudrvinit_ ## nm ## _alias = RTE_STR(alias)
diff --git a/drivers/bus/pci/bus_pci_driver.h b/drivers/bus/pci/bus_pci_driver.h
index 2cc1119072..54e25c8c2a 100644
--- a/drivers/bus/pci/bus_pci_driver.h
+++ b/drivers/bus/pci/bus_pci_driver.h
@@ -171,7 +171,7 @@ RTE_INIT(pciinitfn_ ##nm) \
(pci_drv).driver.name = RTE_STR(nm);\
rte_pci_register(&pci_drv); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm)
/**
* Unregister a PCI driver.
diff --git a/drivers/bus/platform/bus_platform_driver.h b/drivers/bus/platform/bus_platform_driver.h
index a6f246f7c4..ef4b27c0c0 100644
--- a/drivers/bus/platform/bus_platform_driver.h
+++ b/drivers/bus/platform/bus_platform_driver.h
@@ -138,7 +138,7 @@ RTE_INIT(pdrvinitfn_ ##nm) \
(platform_drv).driver.alias = pdrvinit_ ## nm ## _alias; \
rte_platform_register(&(platform_drv)); \
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm)
/** Helper for setting platform driver alias. */
#define RTE_PMD_REGISTER_ALIAS(nm, alias) \
diff --git a/drivers/bus/uacce/bus_uacce_driver.h b/drivers/bus/uacce/bus_uacce_driver.h
index c8e177d44f..618e0f9b76 100644
--- a/drivers/bus/uacce/bus_uacce_driver.h
+++ b/drivers/bus/uacce/bus_uacce_driver.h
@@ -245,7 +245,7 @@ void rte_uacce_unregister(struct rte_uacce_driver *driver);
(uacce_drv).driver.name = RTE_STR(nm);\
rte_uacce_register(&uacce_drv); \
} \
- RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+ RTE_PMD_EXPORT_NAME(nm)
#ifdef __cplusplus
}
diff --git a/drivers/bus/vdev/bus_vdev_driver.h b/drivers/bus/vdev/bus_vdev_driver.h
index cba1fb5269..17efec51a3 100644
--- a/drivers/bus/vdev/bus_vdev_driver.h
+++ b/drivers/bus/vdev/bus_vdev_driver.h
@@ -139,7 +139,7 @@ RTE_INIT(vdrvinitfn_ ##vdrv)\
(vdrv).driver.alias = vdrvinit_ ## nm ## _alias;\
rte_vdev_register(&vdrv);\
} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+RTE_PMD_EXPORT_NAME(nm)
#define RTE_PMD_REGISTER_ALIAS(nm, alias)\
static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias)
diff --git a/drivers/bus/vmbus/bus_vmbus_driver.h b/drivers/bus/vmbus/bus_vmbus_driver.h
index 0a56275437..485bfde720 100644
--- a/drivers/bus/vmbus/bus_vmbus_driver.h
+++ b/drivers/bus/vmbus/bus_vmbus_driver.h
@@ -101,7 +101,7 @@ void rte_vmbus_unregister(struct rte_vmbus_driver *driver);
(vmbus_drv).driver.name = RTE_STR(nm); \
rte_vmbus_register(&vmbus_drv); \
} \
- RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+ RTE_PMD_EXPORT_NAME(nm)
#ifdef __cplusplus
}
diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c
index 4f25127582..0c95aa2993 100644
--- a/drivers/common/mlx5/mlx5_common.c
+++ b/drivers/common/mlx5/mlx5_common.c
@@ -1452,4 +1452,4 @@ mlx5_devx_uar_prepare(struct mlx5_common_device *cdev, struct mlx5_uar *uar)
return 0;
}
-RTE_PMD_EXPORT_NAME(mlx5_common_driver, __COUNTER__);
+RTE_PMD_EXPORT_NAME(mlx5_common_driver);
diff --git a/drivers/common/mlx5/mlx5_common_pci.c b/drivers/common/mlx5/mlx5_common_pci.c
index 819b799bb8..8bd43bc166 100644
--- a/drivers/common/mlx5/mlx5_common_pci.c
+++ b/drivers/common/mlx5/mlx5_common_pci.c
@@ -245,4 +245,4 @@ RTE_FINI(mlx5_common_pci_finish)
}
}
-RTE_PMD_EXPORT_NAME(mlx5_common_pci, __COUNTER__);
+RTE_PMD_EXPORT_NAME(mlx5_common_pci);
diff --git a/drivers/compress/mlx5/mlx5_compress.c b/drivers/compress/mlx5/mlx5_compress.c
index 82105bfebd..e5325c6150 100644
--- a/drivers/compress/mlx5/mlx5_compress.c
+++ b/drivers/compress/mlx5/mlx5_compress.c
@@ -937,6 +937,6 @@ RTE_INIT(rte_mlx5_compress_init)
}
RTE_LOG_REGISTER_DEFAULT(mlx5_compress_logtype, NOTICE)
-RTE_PMD_EXPORT_NAME(MLX5_COMPRESS_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_COMPRESS_DRIVER_NAME);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_COMPRESS_DRIVER_NAME, mlx5_compress_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_COMPRESS_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/drivers/crypto/mlx5/mlx5_crypto.c b/drivers/crypto/mlx5/mlx5_crypto.c
index 2319c6920d..78a9e3d0fe 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.c
+++ b/drivers/crypto/mlx5/mlx5_crypto.c
@@ -514,6 +514,6 @@ RTE_PMD_REGISTER_CRYPTO_DRIVER(mlx5_cryptodev_driver, mlx5_drv,
mlx5_crypto_driver_id);
RTE_LOG_REGISTER_DEFAULT(mlx5_crypto_logtype, NOTICE)
-RTE_PMD_EXPORT_NAME(MLX5_CRYPTO_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_CRYPTO_DRIVER_NAME);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_CRYPTO_DRIVER_NAME, mlx5_crypto_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_CRYPTO_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 9c2872429f..997829a107 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -1385,7 +1385,7 @@ RTE_INIT(rte_mlx4_pmd_init)
rte_pci_register(&mlx4_driver);
}
-RTE_PMD_EXPORT_NAME(net_mlx4, __COUNTER__);
+RTE_PMD_EXPORT_NAME(net_mlx4);
RTE_PMD_REGISTER_PCI_TABLE(net_mlx4, mlx4_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(net_mlx4,
"* ib_uverbs & mlx4_en & mlx4_core & mlx4_ib");
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b4bd43aae2..8cf8322b34 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -3819,6 +3819,6 @@ RTE_INIT(rte_mlx5_pmd_init)
mlx5_class_driver_register(&mlx5_net_driver);
}
-RTE_PMD_EXPORT_NAME(MLX5_ETH_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_ETH_DRIVER_NAME);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_ETH_DRIVER_NAME, mlx5_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_ETH_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
index 9b4b846f8a..daf513d04d 100644
--- a/drivers/net/virtio/virtio_pci_ethdev.c
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -239,4 +239,4 @@ RTE_INIT(rte_virtio_net_pci_pmd_init)
RTE_PMD_REGISTER_PCI_TABLE(net_virtio, pci_id_virtio_map);
RTE_PMD_REGISTER_KMOD_DEP(net_virtio, "* igb_uio | uio_pci_generic | vfio-pci");
-RTE_PMD_EXPORT_NAME(net_virtio, __COUNTER__);
+RTE_PMD_EXPORT_NAME(net_virtio);
diff --git a/drivers/regex/mlx5/mlx5_regex.c b/drivers/regex/mlx5/mlx5_regex.c
index 4ed62b538b..042f585abd 100644
--- a/drivers/regex/mlx5/mlx5_regex.c
+++ b/drivers/regex/mlx5/mlx5_regex.c
@@ -183,6 +183,6 @@ RTE_INIT(rte_mlx5_regex_init)
}
RTE_LOG_REGISTER_DEFAULT(mlx5_regex_logtype, NOTICE)
-RTE_PMD_EXPORT_NAME(MLX5_REGEX_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_REGEX_DRIVER_NAME);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_REGEX_DRIVER_NAME, mlx5_regex_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_REGEX_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c
index 98c39a5e64..11708e2005 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa.c
@@ -1003,6 +1003,6 @@ RTE_INIT(rte_mlx5_vdpa_init)
mlx5_class_driver_register(&mlx5_vdpa_driver);
}
-RTE_PMD_EXPORT_NAME(MLX5_VDPA_DRIVER_NAME, __COUNTER__);
+RTE_PMD_EXPORT_NAME(MLX5_VDPA_DRIVER_NAME);
RTE_PMD_REGISTER_PCI_TABLE(MLX5_VDPA_DRIVER_NAME, mlx5_vdpa_pci_id_map);
RTE_PMD_REGISTER_KMOD_DEP(MLX5_VDPA_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
diff --git a/lib/eal/include/dev_driver.h b/lib/eal/include/dev_driver.h
index 22e48226f9..7766038b1b 100644
--- a/lib/eal/include/dev_driver.h
+++ b/lib/eal/include/dev_driver.h
@@ -30,11 +30,8 @@ struct rte_device {
struct rte_devargs *devargs; /**< Arguments for latest probing */
};
-#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
-
-#define RTE_PMD_EXPORT_NAME(name, idx) \
-static const char RTE_PMD_EXPORT_NAME_ARRAY(this_pmd_name, idx) \
-__rte_used = RTE_STR(name)
+#define RTE_PMD_EXPORT_NAME(name) \
+static const char this_pmd_name ## name __rte_used = RTE_STR(name)
#define DRV_EXP_TAG(name, tag) __##name##_##tag
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v7 3/5] dev: export driver information with MSVC
2025-06-11 9:45 ` [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC David Marchand
2025-06-11 9:45 ` [PATCH v7 1/5] dev: hide driver export macros David Marchand
2025-06-11 9:45 ` [PATCH v7 2/5] dev: rename pmdinfo internal symbols David Marchand
@ 2025-06-11 9:45 ` David Marchand
2025-06-11 13:27 ` Andre Muezerie
2025-06-11 9:45 ` [PATCH v7 4/5] buildtools: embed " David Marchand
2025-06-11 9:45 ` [PATCH v7 5/5] usertools: enable pmdinfo " David Marchand
4 siblings, 1 reply; 17+ messages in thread
From: David Marchand @ 2025-06-11 9:45 UTC (permalink / raw)
To: dev; +Cc: Andre Muezerie, Nipun Gupta, Nikhil Agarwal, Tyler Retzlaff
From: Andre Muezerie <andremue@linux.microsoft.com>
DPDK uses GCC attribute "used" through macro __rte_used to indicate
that a variable not referenced in the code should be assumed being
used and therefore not be optimized away. This technique is used to embed
information in the binaries, by having crafted information stored in
them.
MSVC offers similar functionality, but it differs significantly: MSVC
requires a pragma to be used to send a command to the linker telling it
explicitly the name of the symbol that should be included (even if not
referenced). As a side-effect, variables called out to be included cannot
be static, otherwise their symbols are not "seen" by the linker. This
restriction requires some DPDK code to be refactored.
To assimilate these requirements/restrictions, a new macro
RTE_PMD_EXPORT_SYMBOL is added in this patch to ensure these special
variables make it to the final binaries.
Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
drivers/bus/cdx/bus_cdx_driver.h | 3 +--
lib/eal/common/eal_common_options.c | 2 +-
lib/eal/include/dev_driver.h | 19 ++++++++++++-------
3 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/bus/cdx/bus_cdx_driver.h b/drivers/bus/cdx/bus_cdx_driver.h
index 4febf1fd3b..f0780a84ad 100644
--- a/drivers/bus/cdx/bus_cdx_driver.h
+++ b/drivers/bus/cdx/bus_cdx_driver.h
@@ -35,8 +35,7 @@ struct rte_cdx_bus;
#define RTE_CDX_ANY_ID (0xffff)
#define RTE_PMD_REGISTER_CDX_TABLE(name, table) \
-static const char DRV_EXP_TAG(name, cdx_tbl_export)[] __rte_used = \
-RTE_STR(table)
+RTE_PMD_EXPORT_SYMBOL(const char, DRV_EXP_TAG(name, cdx_tbl_export))[] = RTE_STR(table)
/** Device needs resource mapping */
#define RTE_CDX_DRV_NEED_MAPPING 0x0001
diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
index b4f0e23a9c..83b6fc7e89 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -137,7 +137,7 @@ static const char *default_solib_dir = RTE_EAL_PMD_PATH;
* Note: PLEASE DO NOT ALTER THIS without making a corresponding
* change to usertools/dpdk-pmdinfo.py
*/
-static const char dpdk_solib_path[] __rte_used =
+RTE_PMD_EXPORT_SYMBOL(const char, dpdk_solib_path)[] =
"DPDK_PLUGIN_PATH=" RTE_EAL_PMD_PATH;
TAILQ_HEAD(device_option_list, device_option);
diff --git a/lib/eal/include/dev_driver.h b/lib/eal/include/dev_driver.h
index 7766038b1b..a2517ac1d4 100644
--- a/lib/eal/include/dev_driver.h
+++ b/lib/eal/include/dev_driver.h
@@ -30,18 +30,24 @@ struct rte_device {
struct rte_devargs *devargs; /**< Arguments for latest probing */
};
+#ifdef RTE_TOOLCHAIN_MSVC
+#define RTE_PMD_EXPORT_SYMBOL(type, name) \
+__pragma(comment(linker, "/include:" RTE_STR(name))) type name
+#else
+#define RTE_PMD_EXPORT_SYMBOL(type, name) \
+__attribute__((used)) type name
+#endif
+
#define RTE_PMD_EXPORT_NAME(name) \
-static const char this_pmd_name ## name __rte_used = RTE_STR(name)
+RTE_PMD_EXPORT_SYMBOL(const char, this_pmd_name ## name)[] = RTE_STR(name)
#define DRV_EXP_TAG(name, tag) __##name##_##tag
#define RTE_PMD_REGISTER_PCI_TABLE(name, table) \
-static const char DRV_EXP_TAG(name, pci_tbl_export)[] __rte_used = \
-RTE_STR(table)
+RTE_PMD_EXPORT_SYMBOL(const char, DRV_EXP_TAG(name, pci_tbl_export))[] = RTE_STR(table)
#define RTE_PMD_REGISTER_PARAM_STRING(name, str) \
-static const char DRV_EXP_TAG(name, param_string_export)[] \
-__rte_used = str
+RTE_PMD_EXPORT_SYMBOL(const char, DRV_EXP_TAG(name, param_string_export))[] = str
/**
* Advertise the list of kernel modules required to run this driver
@@ -65,7 +71,6 @@ __rte_used = str
* - "* igb_uio | uio_pci_generic | vfio"
*/
#define RTE_PMD_REGISTER_KMOD_DEP(name, str) \
-static const char DRV_EXP_TAG(name, kmod_dep_export)[] \
-__rte_used = str
+RTE_PMD_EXPORT_SYMBOL(const char, DRV_EXP_TAG(name, kmod_dep_export))[] = str
#endif /* DEV_DRIVER_H */
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v7 4/5] buildtools: embed driver information with MSVC
2025-06-11 9:45 ` [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC David Marchand
` (2 preceding siblings ...)
2025-06-11 9:45 ` [PATCH v7 3/5] dev: export driver information with MSVC David Marchand
@ 2025-06-11 9:45 ` David Marchand
2025-06-11 13:28 ` Andre Muezerie
2025-06-11 9:45 ` [PATCH v7 5/5] usertools: enable pmdinfo " David Marchand
4 siblings, 1 reply; 17+ messages in thread
From: David Marchand @ 2025-06-11 9:45 UTC (permalink / raw)
To: dev; +Cc: Andre Muezerie, Dmitry Kozlyuk
From: Andre Muezerie <andremue@linux.microsoft.com>
The archiver tool from the MSVC toolset is lib.exe. It has different
parameters then it's GNU counterpart "ar".
buildtools\meson.build was updated to use lib.exe when MSVC compiler is
used. This is to allow the code to be built without requiring GNU "ar"
to be installed in that scenario.
Script gen-pmdinfo-cfile.py was updated to use the correct parameters
when using lib.exe.
Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
---
buildtools/gen-pmdinfo-cfile.py | 25 ++++++++++++++++++++-----
buildtools/meson.build | 2 ++
buildtools/pmdinfogen.py | 11 ++++++-----
3 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/buildtools/gen-pmdinfo-cfile.py b/buildtools/gen-pmdinfo-cfile.py
index 8ffc192c40..5d2e8e076e 100644
--- a/buildtools/gen-pmdinfo-cfile.py
+++ b/buildtools/gen-pmdinfo-cfile.py
@@ -6,16 +6,31 @@
import subprocess
import sys
-_, ar, tmp_dir, archive, output, *pmdinfogen = sys.argv
+_, archiver, tmp_dir, archive, output, *pmdinfogen = sys.argv
paths = []
-for name in subprocess.run([ar, "t", archive], stdout=subprocess.PIPE,
- check=True).stdout.decode().splitlines():
+if archiver == "lib":
+ archiver_options = ["/LIST", "/NOLOGO"]
+else:
+ archiver_options = ["t"]
+
+for name in (
+ subprocess.run(
+ [archiver] + archiver_options + [archive],
+ stdout=subprocess.PIPE,
+ check=True,
+ )
+ .stdout.decode()
+ .splitlines()
+):
if os.path.exists(name):
paths.append(name)
else:
if not os.path.exists(tmp_dir):
os.makedirs(tmp_dir)
- subprocess.run([ar, "x", os.path.abspath(archive), name],
- check=True, cwd=tmp_dir)
+ if archiver == "lib":
+ run_args = [archiver, f"/EXTRACT:{name}", os.path.abspath(archive)]
+ else:
+ run_args = [archiver, "x", os.path.abspath(archive), name]
+ subprocess.run(run_args, check=True, cwd=tmp_dir)
paths.append(os.path.join(tmp_dir, name))
subprocess.run(pmdinfogen + paths + [output], check=True)
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 822e79502a..7b5e449cdb 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -44,6 +44,8 @@ pmdinfogen = py3 + files('pmdinfogen.py')
if host_machine.system() == 'windows'
if cc.get_id() == 'gcc'
pmdinfo += 'ar'
+ elif cc.get_id() == 'msvc'
+ pmdinfo += 'lib'
else
pmdinfo += 'llvm-ar'
endif
diff --git a/buildtools/pmdinfogen.py b/buildtools/pmdinfogen.py
index 7be2e39dd2..63e0a8b364 100755
--- a/buildtools/pmdinfogen.py
+++ b/buildtools/pmdinfogen.py
@@ -87,7 +87,7 @@ def get_value(self, offset, size):
@property
def string_value(self):
value = self._symbol.get_value(0)
- return coff.decode_asciiz(value) if value else ''
+ return coff.decode_asciiz(value) if value else ""
class COFFImage:
@@ -192,7 +192,7 @@ def dump(self, file):
dumped = json.dumps(self.__dict__)
escaped = dumped.replace('"', '\\"')
print(
- 'const char %s_pmd_info[] __attribute__((used)) = "PMD_INFO_STRING= %s";'
+ 'RTE_PMD_EXPORT_SYMBOL(const char, %s_pmd_info)[] = "PMD_INFO_STRING= %s";'
% (self.name, escaped),
file=file,
)
@@ -215,7 +215,7 @@ def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("format", help="object file format, 'elf' or 'coff'")
parser.add_argument(
- "input", nargs='+', help="input object file path or '-' for stdin"
+ "input", nargs="+", help="input object file path or '-' for stdin"
)
parser.add_argument("output", help="output C file path or '-' for stdout")
return parser.parse_args()
@@ -252,13 +252,14 @@ def open_output(path):
def write_header(output):
output.write(
- "static __attribute__((unused)) const char *generator = \"%s\";\n" % sys.argv[0]
+ "#include <dev_driver.h>\n"
+ 'static __rte_unused const char *generator = "%s";\n' % sys.argv[0]
)
def main():
args = parse_args()
- if args.input.count('-') > 1:
+ if args.input.count("-") > 1:
raise Exception("'-' input cannot be used multiple times")
if args.format == "elf" and "ELFFile" not in globals():
raise Exception("elftools module not found")
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v7 5/5] usertools: enable pmdinfo with MSVC
2025-06-11 9:45 ` [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC David Marchand
` (3 preceding siblings ...)
2025-06-11 9:45 ` [PATCH v7 4/5] buildtools: embed " David Marchand
@ 2025-06-11 9:45 ` David Marchand
4 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2025-06-11 9:45 UTC (permalink / raw)
To: dev; +Cc: Andre Muezerie, Robin Jarry, Dmitry Kozlyuk
From: Andre Muezerie <andremue@linux.microsoft.com>
Script usertools\dpdk-pmdinfo.py was enhanced to also be able to parse
symbols from sections in PE images.
Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
Acked-by: Robin Jarry <rjarry@redhat.com>
---
usertools/dpdk-pmdinfo.py | 53 +++++++++++++++++++++++++++++++--------
1 file changed, 43 insertions(+), 10 deletions(-)
diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index 9189a2fdbc..9251c69db9 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -37,8 +37,11 @@
from pathlib import Path
from typing import Iterable, Iterator, List, Union
-import elftools
-from elftools.elf.elffile import ELFError, ELFFile
+if os.name == "nt":
+ import pefile
+else:
+ import elftools
+ from elftools.elf.elffile import ELFError, ELFFile
# ----------------------------------------------------------------------------
@@ -114,18 +117,23 @@ def parse_pmdinfo(paths: Iterable[Path], search_plugins: bool) -> List[dict]:
A list of DPDK drivers info dictionaries.
"""
binaries = set(paths)
- for p in paths:
- binaries.update(get_needed_libs(p))
- if search_plugins:
- # cast to list to avoid errors with update while iterating
- binaries.update(list(get_plugin_libs(binaries)))
+
+ if os.name == "nt":
+ section_name = ".rdata"
+ else:
+ section_name = ".rodata"
+ for p in paths:
+ binaries.update(get_needed_libs(p))
+ if search_plugins:
+ # cast to list to avoid errors with update while iterating
+ binaries.update(list(get_plugin_libs(binaries)))
drivers = []
for b in binaries:
logging.debug("analyzing %s", b)
try:
- for s in get_elf_strings(b, ".rodata", "PMD_INFO_STRING="):
+ for s in get_section_strings(b, section_name, "PMD_INFO_STRING="):
try:
info = json.loads(s)
scrub_pci_ids(info)
@@ -214,7 +222,7 @@ def find_strings(buf: bytes, prefix: str) -> Iterator[str]:
# end of string
s = view[start:i].tobytes().decode("ascii")
if s.startswith(prefix):
- yield s[len(prefix):]
+ yield s[len(prefix) :]
# There can be byte sequences where a non-printable byte
# follows a printable one. Ignore that.
start = None
@@ -233,7 +241,8 @@ def elftools_version():
return (int(match[1]), int(match[2]))
-ELFTOOLS_VERSION = elftools_version()
+if os.name != "nt":
+ ELFTOOLS_VERSION = elftools_version()
def from_elftools(s: Union[bytes, str]) -> str:
@@ -269,6 +278,30 @@ def get_elf_strings(path: Path, section: str, prefix: str) -> Iterator[str]:
yield from find_strings(sec.data(), prefix)
+# ----------------------------------------------------------------------------
+def get_pe_strings(path: Path, section: str, prefix: str) -> Iterator[str]:
+ """
+ Extract strings from a named PE section in a file.
+ """
+ pe = pefile.PE(path)
+ for sec in pe.sections:
+ section_name = sec.Name.decode().strip("\x00")
+ if section_name != section:
+ continue
+ yield from find_strings(sec.get_data(), prefix)
+
+
+# ----------------------------------------------------------------------------
+def get_section_strings(path: Path, section: str, prefix: str) -> Iterator[str]:
+ """
+ Extract strings from a named section in an ELF or PE file.
+ """
+ if os.name == "nt":
+ yield from get_pe_strings(path, section, prefix)
+ else:
+ yield from get_elf_strings(path, section, prefix)
+
+
# ----------------------------------------------------------------------------
LDD_LIB_RE = re.compile(
r"""
--
2.49.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 1/5] dev: hide driver export macros
2025-06-11 9:45 ` [PATCH v7 1/5] dev: hide driver export macros David Marchand
@ 2025-06-11 13:24 ` Andre Muezerie
0 siblings, 0 replies; 17+ messages in thread
From: Andre Muezerie @ 2025-06-11 13:24 UTC (permalink / raw)
To: David Marchand; +Cc: dev, Tyler Retzlaff
On Wed, Jun 11, 2025 at 11:45:28AM +0200, David Marchand wrote:
> The macros for tagging/exporting informations about a driver do not need
> to be exported in the public API.
> Move this to driver only header.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
Acked-by: Andre Muezerie <andremue@linux.microsoft.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 2/5] dev: rename pmdinfo internal symbols
2025-06-11 9:45 ` [PATCH v7 2/5] dev: rename pmdinfo internal symbols David Marchand
@ 2025-06-11 13:26 ` Andre Muezerie
0 siblings, 0 replies; 17+ messages in thread
From: Andre Muezerie @ 2025-06-11 13:26 UTC (permalink / raw)
To: David Marchand
Cc: dev, Dmitry Kozlyuk, Parav Pandit, Xueming Li, Nipun Gupta,
Nikhil Agarwal, Hemant Agrawal, Sachin Saxena, Rosen Xu,
Chenbo Xia, Tomasz Duszynski, Chengwen Feng, Long Li, Wei Hu,
Dariusz Sosnowski, Viacheslav Ovsiienko, Bing Zhao, Ori Kam,
Suanming Mou, Matan Azrad, Fan Zhang, Ashish Gupta,
Maxime Coquelin, Tyler Retzlaff
On Wed, Jun 11, 2025 at 11:45:29AM +0200, David Marchand wrote:
> __COUNTER__ is not supported by MSVC.
> Plus the this_pmd_name* symbols will become global (again for MSVC) in a
> next commit.
> Prefer the driver name to generate a unique symbol.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
Acked-by: Andre Muezerie <andremue@linux.microsoft.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 3/5] dev: export driver information with MSVC
2025-06-11 9:45 ` [PATCH v7 3/5] dev: export driver information with MSVC David Marchand
@ 2025-06-11 13:27 ` Andre Muezerie
0 siblings, 0 replies; 17+ messages in thread
From: Andre Muezerie @ 2025-06-11 13:27 UTC (permalink / raw)
To: David Marchand; +Cc: dev, Nipun Gupta, Nikhil Agarwal, Tyler Retzlaff
On Wed, Jun 11, 2025 at 11:45:30AM +0200, David Marchand wrote:
> From: Andre Muezerie <andremue@linux.microsoft.com>
>
> DPDK uses GCC attribute "used" through macro __rte_used to indicate
> that a variable not referenced in the code should be assumed being
> used and therefore not be optimized away. This technique is used to embed
> information in the binaries, by having crafted information stored in
> them.
>
> MSVC offers similar functionality, but it differs significantly: MSVC
> requires a pragma to be used to send a command to the linker telling it
> explicitly the name of the symbol that should be included (even if not
> referenced). As a side-effect, variables called out to be included cannot
> be static, otherwise their symbols are not "seen" by the linker. This
> restriction requires some DPDK code to be refactored.
>
> To assimilate these requirements/restrictions, a new macro
> RTE_PMD_EXPORT_SYMBOL is added in this patch to ensure these special
> variables make it to the final binaries.
>
> Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
Acked-by: Andre Muezerie <andremue@linux.microsoft.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 4/5] buildtools: embed driver information with MSVC
2025-06-11 9:45 ` [PATCH v7 4/5] buildtools: embed " David Marchand
@ 2025-06-11 13:28 ` Andre Muezerie
0 siblings, 0 replies; 17+ messages in thread
From: Andre Muezerie @ 2025-06-11 13:28 UTC (permalink / raw)
To: David Marchand; +Cc: dev, Dmitry Kozlyuk
On Wed, Jun 11, 2025 at 11:45:31AM +0200, David Marchand wrote:
> From: Andre Muezerie <andremue@linux.microsoft.com>
>
> The archiver tool from the MSVC toolset is lib.exe. It has different
> parameters then it's GNU counterpart "ar".
>
> buildtools\meson.build was updated to use lib.exe when MSVC compiler is
> used. This is to allow the code to be built without requiring GNU "ar"
> to be installed in that scenario.
>
> Script gen-pmdinfo-cfile.py was updated to use the correct parameters
> when using lib.exe.
>
> Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
> ---
Acked-by: Andre Muezerie <andremue@linux.microsoft.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2025-06-11 13:28 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-10 10:09 [PATCH v6 0/4] allow pmdinfo to be inserted and parsed using MSVC David Marchand
2025-06-10 10:09 ` [PATCH v6 1/4] dev: hide driver export macros David Marchand
2025-06-10 10:09 ` [PATCH v6 2/4] dev: export driver information with MSVC David Marchand
2025-06-10 12:13 ` David Marchand
2025-06-10 10:09 ` [PATCH v6 3/4] buildtools: embed " David Marchand
2025-06-10 10:09 ` [PATCH v6 4/4] usertools: enable pmdinfo " David Marchand
2025-06-10 10:17 ` Robin Jarry
2025-06-11 9:45 ` [PATCH v7 0/5] allow pmdinfo to be inserted and parsed using MSVC David Marchand
2025-06-11 9:45 ` [PATCH v7 1/5] dev: hide driver export macros David Marchand
2025-06-11 13:24 ` Andre Muezerie
2025-06-11 9:45 ` [PATCH v7 2/5] dev: rename pmdinfo internal symbols David Marchand
2025-06-11 13:26 ` Andre Muezerie
2025-06-11 9:45 ` [PATCH v7 3/5] dev: export driver information with MSVC David Marchand
2025-06-11 13:27 ` Andre Muezerie
2025-06-11 9:45 ` [PATCH v7 4/5] buildtools: embed " David Marchand
2025-06-11 13:28 ` Andre Muezerie
2025-06-11 9:45 ` [PATCH v7 5/5] usertools: enable pmdinfo " David Marchand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).