From: Bruce Richardson Date: Thu, 10 Sep 2020 14:36:03 +0000 (+0100) Subject: rawdev: add private data size to info query X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=10b71caecbe1cddcbb65c050ca775fba575e88db;p=dpdk.git rawdev: add private data size to info query Currently with the rawdev API there is no way to check that the structure passed in via the dev_private pointer in the dev_info structure is of the correct type - it's just checked that it is non-NULL. Adding in the length of the expected structure provides a measure of typechecking, and can also be used for ABI compatibility in future, since ABI changes involving structs almost always involve a change in size. Signed-off-by: Bruce Richardson Reviewed-by: Rosen Xu Acked-by: Rosen Xu Acked-by: Nipun Gupta --- diff --git a/app/test/test_rawdev.c b/app/test/test_rawdev.c index 524a9d5f3b..d8d9595be1 100644 --- a/app/test/test_rawdev.c +++ b/app/test/test_rawdev.c @@ -34,7 +34,7 @@ test_rawdev_selftest_ioat(void) for (i = 0; i < count; i++) { struct rte_rawdev_info info = { .dev_private = NULL }; - if (rte_rawdev_info_get(i, &info) == 0 && + if (rte_rawdev_info_get(i, &info, 0) == 0 && strstr(info.driver_name, "ioat") != NULL) return rte_rawdev_selftest(i) == 0 ? TEST_SUCCESS : TEST_FAILED; diff --git a/doc/guides/rawdevs/ioat.rst b/doc/guides/rawdevs/ioat.rst index d0eee5e237..dac52fabf1 100644 --- a/doc/guides/rawdevs/ioat.rst +++ b/doc/guides/rawdevs/ioat.rst @@ -107,7 +107,7 @@ rawdev device for use by an application: for (i = 0; i < count && !found; i++) { struct rte_rawdev_info info = { .dev_private = NULL }; - found = (rte_rawdev_info_get(i, &info) == 0 && + found = (rte_rawdev_info_get(i, &info, 0) == 0 && strcmp(info.driver_name, IOAT_PMD_RAWDEV_NAME_STR) == 0); } diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst index df227a1773..a931dc0bff 100644 --- a/doc/guides/rel_notes/release_20_11.rst +++ b/doc/guides/rel_notes/release_20_11.rst @@ -84,6 +84,10 @@ API Changes Also, make sure to start the actual text at the margin. ======================================================= +* rawdev: Added a structure size parameter to the function + ``rte_rawdev_info_get()``, + allowing limited driver type-checking and ABI compatibility. + ABI Changes ----------- diff --git a/doc/guides/sample_app_ug/ioat.rst b/doc/guides/sample_app_ug/ioat.rst index bab7654b8d..b5188220ba 100644 --- a/doc/guides/sample_app_ug/ioat.rst +++ b/doc/guides/sample_app_ug/ioat.rst @@ -265,7 +265,7 @@ functions: do { if (rdev_id == rte_rawdev_count()) goto end; - rte_rawdev_info_get(rdev_id++, &rdev_info); + rte_rawdev_info_get(rdev_id++, &rdev_info, 0); } while (strcmp(rdev_info.driver_name, IOAT_PMD_RAWDEV_NAME_STR) != 0); diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c index 6b16a20bb6..bb8b3dcfb9 100644 --- a/drivers/bus/ifpga/ifpga_bus.c +++ b/drivers/bus/ifpga/ifpga_bus.c @@ -162,7 +162,7 @@ ifpga_scan_one(struct rte_rawdev *rawdev, afu_dev->id.port = afu_pr_conf.afu_id.port; if (rawdev->dev_ops && rawdev->dev_ops->dev_info_get) - rawdev->dev_ops->dev_info_get(rawdev, afu_dev); + rawdev->dev_ops->dev_info_get(rawdev, afu_dev, sizeof(*afu_dev)); if (rawdev->dev_ops && rawdev->dev_ops->dev_start && diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index cc25c662bc..47cfa38778 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -605,7 +605,8 @@ ifpga_fill_afu_dev(struct opae_accelerator *acc, static void ifpga_rawdev_info_get(struct rte_rawdev *dev, - rte_rawdev_obj_t dev_info) + rte_rawdev_obj_t dev_info, + size_t dev_info_size) { struct opae_adapter *adapter; struct opae_accelerator *acc; @@ -617,7 +618,7 @@ ifpga_rawdev_info_get(struct rte_rawdev *dev, IFPGA_RAWDEV_PMD_FUNC_TRACE(); - if (!dev_info) { + if (!dev_info || dev_info_size != sizeof(*afu_dev)) { IFPGA_RAWDEV_PMD_ERR("Invalid request"); return; } diff --git a/drivers/raw/ioat/ioat_rawdev.c b/drivers/raw/ioat/ioat_rawdev.c index 87fd088aac..a5c0452d7e 100644 --- a/drivers/raw/ioat/ioat_rawdev.c +++ b/drivers/raw/ioat/ioat_rawdev.c @@ -111,12 +111,13 @@ ioat_dev_stop(struct rte_rawdev *dev) } static void -ioat_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info) +ioat_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info, + size_t dev_info_size) { struct rte_ioat_rawdev_config *cfg = dev_info; struct rte_ioat_rawdev *ioat = dev->dev_private; - if (cfg != NULL) + if (cfg != NULL && dev_info_size == sizeof(*cfg)) cfg->ring_size = ioat->ring_size; } diff --git a/drivers/raw/ioat/ioat_rawdev_test.c b/drivers/raw/ioat/ioat_rawdev_test.c index c37351af2d..2b40222eb4 100644 --- a/drivers/raw/ioat/ioat_rawdev_test.c +++ b/drivers/raw/ioat/ioat_rawdev_test.c @@ -148,7 +148,7 @@ ioat_rawdev_test(uint16_t dev_id) unsigned int nb_xstats; unsigned int i; - rte_rawdev_info_get(dev_id, &info); + rte_rawdev_info_get(dev_id, &info, sizeof(p)); if (p.ring_size != expected_ring_size) { printf("Error, initial ring size is not as expected (Actual: %d, Expected: %d)\n", (int)p.ring_size, expected_ring_size); @@ -160,7 +160,7 @@ ioat_rawdev_test(uint16_t dev_id) printf("Error with rte_rawdev_configure()\n"); return -1; } - rte_rawdev_info_get(dev_id, &info); + rte_rawdev_info_get(dev_id, &info, sizeof(p)); if (p.ring_size != IOAT_TEST_RINGSIZE) { printf("Error, ring size is not %d (%d)\n", IOAT_TEST_RINGSIZE, (int)p.ring_size); diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c index e40412bb7e..c890c43a32 100644 --- a/drivers/raw/ntb/ntb.c +++ b/drivers/raw/ntb/ntb.c @@ -801,11 +801,17 @@ end_of_rx: } static void -ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info) +ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info, + size_t dev_info_size) { struct ntb_hw *hw = dev->dev_private; struct ntb_dev_info *info = dev_info; + if (dev_info_size != sizeof(*info)) { + NTB_LOG(ERR, "Invalid size parameter to %s", __func__); + return; + } + info->mw_cnt = hw->mw_cnt; info->mw_size = hw->mw_size; diff --git a/drivers/raw/skeleton/skeleton_rawdev.c b/drivers/raw/skeleton/skeleton_rawdev.c index 72ece887af..dc05f3ecf8 100644 --- a/drivers/raw/skeleton/skeleton_rawdev.c +++ b/drivers/raw/skeleton/skeleton_rawdev.c @@ -42,14 +42,15 @@ static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {}; static void clear_queue_bufs(int queue_id); static void skeleton_rawdev_info_get(struct rte_rawdev *dev, - rte_rawdev_obj_t dev_info) + rte_rawdev_obj_t dev_info, + size_t dev_info_size) { struct skeleton_rawdev *skeldev; struct skeleton_rawdev_conf *skeldev_conf; SKELETON_PMD_FUNC_TRACE(); - if (!dev_info) { + if (!dev_info || dev_info_size != sizeof(*skeldev_conf)) { SKELETON_PMD_ERR("Invalid request"); return; } diff --git a/drivers/raw/skeleton/skeleton_rawdev_test.c b/drivers/raw/skeleton/skeleton_rawdev_test.c index 9ecfdee818..9b8390dfb7 100644 --- a/drivers/raw/skeleton/skeleton_rawdev_test.c +++ b/drivers/raw/skeleton/skeleton_rawdev_test.c @@ -106,12 +106,12 @@ test_rawdev_info_get(void) struct rte_rawdev_info rdev_info = {0}; struct skeleton_rawdev_conf skel_conf = {0}; - ret = rte_rawdev_info_get(test_dev_id, NULL); + ret = rte_rawdev_info_get(test_dev_id, NULL, 0); RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); rdev_info.dev_private = &skel_conf; - ret = rte_rawdev_info_get(test_dev_id, &rdev_info); + ret = rte_rawdev_info_get(test_dev_id, &rdev_info, sizeof(skel_conf)); RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get raw dev info"); return TEST_SUCCESS; @@ -142,7 +142,8 @@ test_rawdev_configure(void) rdev_info.dev_private = &rdev_conf_get; ret = rte_rawdev_info_get(test_dev_id, - (rte_rawdev_obj_t)&rdev_info); + (rte_rawdev_obj_t)&rdev_info, + sizeof(rdev_conf_get)); RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)", ret); @@ -170,7 +171,8 @@ test_rawdev_queue_default_conf_get(void) /* Get the current configuration */ rdev_info.dev_private = &rdev_conf_get; ret = rte_rawdev_info_get(test_dev_id, - (rte_rawdev_obj_t)&rdev_info); + (rte_rawdev_obj_t)&rdev_info, + sizeof(rdev_conf_get)); RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)", ret); @@ -218,7 +220,8 @@ test_rawdev_queue_setup(void) /* Get the current configuration */ rdev_info.dev_private = &rdev_conf_get; ret = rte_rawdev_info_get(test_dev_id, - (rte_rawdev_obj_t)&rdev_info); + (rte_rawdev_obj_t)&rdev_info, + sizeof(rdev_conf_get)); RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)", ret); @@ -327,7 +330,8 @@ test_rawdev_start_stop(void) dummy_firmware = NULL; rte_rawdev_start(test_dev_id); - ret = rte_rawdev_info_get(test_dev_id, (rte_rawdev_obj_t)&rdev_info); + ret = rte_rawdev_info_get(test_dev_id, (rte_rawdev_obj_t)&rdev_info, + sizeof(rdev_conf_get)); RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)", ret); @@ -336,7 +340,8 @@ test_rawdev_start_stop(void) rdev_conf_get.device_state); rte_rawdev_stop(test_dev_id); - ret = rte_rawdev_info_get(test_dev_id, (rte_rawdev_obj_t)&rdev_info); + ret = rte_rawdev_info_get(test_dev_id, (rte_rawdev_obj_t)&rdev_info, + sizeof(rdev_conf_get)); RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain rawdev configuration (%d)", ret); diff --git a/examples/ioat/ioatfwd.c b/examples/ioat/ioatfwd.c index 75d8d5b9fe..76932d3dd2 100644 --- a/examples/ioat/ioatfwd.c +++ b/examples/ioat/ioatfwd.c @@ -757,7 +757,7 @@ assign_rawdevs(void) do { if (rdev_id == rte_rawdev_count()) goto end; - rte_rawdev_info_get(rdev_id++, &rdev_info); + rte_rawdev_info_get(rdev_id++, &rdev_info, 0); } while (rdev_info.driver_name == NULL || strcmp(rdev_info.driver_name, IOAT_PMD_RAWDEV_NAME_STR) != 0); diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c index eba8ebf9fa..11e224451c 100644 --- a/examples/ntb/ntb_fwd.c +++ b/examples/ntb/ntb_fwd.c @@ -1389,7 +1389,7 @@ main(int argc, char **argv) rte_rawdev_set_attr(dev_id, NTB_QUEUE_NUM_NAME, num_queues); printf("Set queue number as %u.\n", num_queues); ntb_rawdev_info.dev_private = (rte_rawdev_obj_t)(&ntb_info); - rte_rawdev_info_get(dev_id, &ntb_rawdev_info); + rte_rawdev_info_get(dev_id, &ntb_rawdev_info, sizeof(ntb_info)); nb_mbuf = nb_desc * num_queues * 2 * 2 + rte_lcore_count() * MEMPOOL_CACHE_SIZE; diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c index 8f84d0b228..a576890356 100644 --- a/lib/librte_rawdev/rte_rawdev.c +++ b/lib/librte_rawdev/rte_rawdev.c @@ -78,7 +78,8 @@ rte_rawdev_socket_id(uint16_t dev_id) } int -rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info) +rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info, + size_t dev_private_size) { struct rte_rawdev *rawdev; @@ -89,7 +90,8 @@ rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info) if (dev_info->dev_private != NULL) { RTE_FUNC_PTR_OR_ERR_RET(*rawdev->dev_ops->dev_info_get, -ENOTSUP); - (*rawdev->dev_ops->dev_info_get)(rawdev, dev_info->dev_private); + (*rawdev->dev_ops->dev_info_get)(rawdev, dev_info->dev_private, + dev_private_size); } dev_info->driver_name = rawdev->driver_name; diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h index 32f6b8bb03..cf6acfd261 100644 --- a/lib/librte_rawdev/rte_rawdev.h +++ b/lib/librte_rawdev/rte_rawdev.h @@ -82,13 +82,20 @@ struct rte_rawdev_info; * will be returned. This can be used to safely query the type of a rawdev * instance without needing to know the size of the private data to return. * + * @param dev_private_size + * The length of the memory space pointed to by dev_private in dev_info. + * This should be set to the size of the expected private structure to be + * returned, and may be checked by drivers to ensure the expected struct + * type is provided. + * * @return * - 0: Success, driver updates the contextual information of the raw device * - <0: Error code returned by the driver info get function. * */ int -rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info); +rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info, + size_t dev_private_size); /** * Configure a raw device. diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h index 4395a2182d..0e72a92058 100644 --- a/lib/librte_rawdev/rte_rawdev_pmd.h +++ b/lib/librte_rawdev/rte_rawdev_pmd.h @@ -138,12 +138,15 @@ rte_rawdev_pmd_is_valid_dev(uint8_t dev_id) * Raw device pointer * @param dev_info * Raw device information structure + * @param dev_private_size + * The size of the structure pointed to by dev_info->dev_private * * @return * Returns 0 on success */ typedef void (*rawdev_info_get_t)(struct rte_rawdev *dev, - rte_rawdev_obj_t dev_info); + rte_rawdev_obj_t dev_info, + size_t dev_private_size); /** * Configure a device.