From: Bruce Richardson <bruce.richardson@intel.com> To: Nipun Gupta <nipun.gupta@nxp.com>, Hemant Agrawal <hemant.agrawal@nxp.com> Cc: dev@dpdk.org, Bruce Richardson <bruce.richardson@intel.com>, Rosen Xu <rosen.xu@intel.com>, John McNamara <john.mcnamara@intel.com>, Marko Kovacevic <marko.kovacevic@intel.com>, Satha Rao <skoteshwar@marvell.com>, Mahipal Challa <mchalla@marvell.com>, Tianfei zhang <tianfei.zhang@intel.com>, Xiaoyun Li <xiaoyun.li@intel.com>, Jingjing Wu <jingjing.wu@intel.com> Subject: [dpdk-dev] [PATCH v2 3/7] rawdev: add private data length parameter to config fn Date: Thu, 13 Aug 2020 12:28:01 +0100 Message-ID: <20200813112806.164578-4-bruce.richardson@intel.com> (raw) In-Reply-To: <20200813112806.164578-1-bruce.richardson@intel.com> Currently with the rawdev API there is no way to check that the structure passed in via the dev_private pointer in the structure passed to configure API 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 <bruce.richardson@intel.com> Reviewed-by: Rosen Xu <rosen.xu@intel.com> --- doc/guides/rawdevs/ioat.rst | 2 +- doc/guides/rawdevs/octeontx2_dma.rst | 2 +- doc/guides/rawdevs/octeontx2_ep.rst | 3 ++- doc/guides/sample_app_ug/ioat.rst | 2 +- drivers/raw/ifpga/ifpga_rawdev.c | 3 ++- drivers/raw/ioat/ioat_rawdev.c | 5 +++-- drivers/raw/ioat/ioat_rawdev_test.c | 2 +- drivers/raw/ntb/ntb.c | 6 +++++- drivers/raw/octeontx2_dma/otx2_dpi_rawdev.c | 7 ++++--- drivers/raw/octeontx2_dma/otx2_dpi_test.c | 3 ++- drivers/raw/octeontx2_ep/otx2_ep_rawdev.c | 7 ++++--- drivers/raw/octeontx2_ep/otx2_ep_test.c | 2 +- drivers/raw/skeleton/skeleton_rawdev.c | 5 +++-- drivers/raw/skeleton/skeleton_rawdev_test.c | 5 +++-- examples/ioat/ioatfwd.c | 2 +- examples/ntb/ntb_fwd.c | 2 +- lib/librte_rawdev/rte_rawdev.c | 6 ++++-- lib/librte_rawdev/rte_rawdev.h | 8 +++++++- lib/librte_rawdev/rte_rawdev_pmd.h | 3 ++- 19 files changed, 48 insertions(+), 27 deletions(-) diff --git a/doc/guides/rawdevs/ioat.rst b/doc/guides/rawdevs/ioat.rst index dac52fabf1..c46460ff45 100644 --- a/doc/guides/rawdevs/ioat.rst +++ b/doc/guides/rawdevs/ioat.rst @@ -142,7 +142,7 @@ The following code shows how the device is configured in /* ... */ p.ring_size = IOAT_TEST_RINGSIZE; - if (rte_rawdev_configure(dev_id, &info) != 0) { + if (rte_rawdev_configure(dev_id, &info, sizeof(p)) != 0) { printf("Error with rte_rawdev_configure()\n"); return -1; } diff --git a/doc/guides/rawdevs/octeontx2_dma.rst b/doc/guides/rawdevs/octeontx2_dma.rst index 1e1dfbe931..4a9794489e 100644 --- a/doc/guides/rawdevs/octeontx2_dma.rst +++ b/doc/guides/rawdevs/octeontx2_dma.rst @@ -92,7 +92,7 @@ The following code shows how the device is configured rte_mempool_set_ops_byname(conf.chunk_pool, rte_mbuf_platform_mempool_ops(), NULL); rte_mempool_populate_default(conf.chunk_pool); - rte_rawdev_configure(dev_id, (rte_rawdev_obj_t)&rdev_info); + rte_rawdev_configure(dev_id, (rte_rawdev_obj_t)&rdev_info, sizeof(conf)); Performing Data Transfer ------------------------ diff --git a/doc/guides/rawdevs/octeontx2_ep.rst b/doc/guides/rawdevs/octeontx2_ep.rst index bbcf530a45..b03fcf789a 100644 --- a/doc/guides/rawdevs/octeontx2_ep.rst +++ b/doc/guides/rawdevs/octeontx2_ep.rst @@ -66,7 +66,8 @@ The following code shows how the device is configured struct rte_rawdev_info rdev_info = {.dev_private = &config}; config.enqdeq_mpool = (void *)rte_mempool_create(...); - rte_rawdev_configure(dev_id, (rte_rawdev_obj_t)&rdev_info); + rte_rawdev_configure(dev_id, (rte_rawdev_obj_t)&rdev_info, + sizeof(config)); Performing Data Transfer ------------------------ diff --git a/doc/guides/sample_app_ug/ioat.rst b/doc/guides/sample_app_ug/ioat.rst index b5188220ba..3f7d5c34a6 100644 --- a/doc/guides/sample_app_ug/ioat.rst +++ b/doc/guides/sample_app_ug/ioat.rst @@ -296,7 +296,7 @@ is done in ``configure_rawdev_queue()``. struct rte_ioat_rawdev_config dev_config = { .ring_size = ring_size }; struct rte_rawdev_info info = { .dev_private = &dev_config }; - if (rte_rawdev_configure(dev_id, &info) != 0) { + if (rte_rawdev_configure(dev_id, &info, sizeof(dev_config)) != 0) { rte_exit(EXIT_FAILURE, "Error with rte_rawdev_configure()\n"); } diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 32a2b96c90..a50173264c 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -684,7 +684,8 @@ ifpga_rawdev_info_get(struct rte_rawdev *dev, static int ifpga_rawdev_configure(const struct rte_rawdev *dev, - rte_rawdev_obj_t config) + rte_rawdev_obj_t config, + size_t config_size __rte_unused) { IFPGA_RAWDEV_PMD_FUNC_TRACE(); diff --git a/drivers/raw/ioat/ioat_rawdev.c b/drivers/raw/ioat/ioat_rawdev.c index e2fc787263..7f1a154360 100644 --- a/drivers/raw/ioat/ioat_rawdev.c +++ b/drivers/raw/ioat/ioat_rawdev.c @@ -39,7 +39,8 @@ RTE_LOG_REGISTER(ioat_pmd_logtype, rawdev.ioat, INFO); #define COMPLETION_SZ sizeof(__m128i) static int -ioat_dev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config) +ioat_dev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config, + size_t config_size) { struct rte_ioat_rawdev_config *params = config; struct rte_ioat_rawdev *ioat = dev->dev_private; @@ -49,7 +50,7 @@ ioat_dev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config) if (dev->started) return -EBUSY; - if (params == NULL) + if (params == NULL || config_size != sizeof(*params)) return -EINVAL; if (params->ring_size > 4096 || params->ring_size < 64 || diff --git a/drivers/raw/ioat/ioat_rawdev_test.c b/drivers/raw/ioat/ioat_rawdev_test.c index 2b40222eb4..c463a82ad6 100644 --- a/drivers/raw/ioat/ioat_rawdev_test.c +++ b/drivers/raw/ioat/ioat_rawdev_test.c @@ -156,7 +156,7 @@ ioat_rawdev_test(uint16_t dev_id) } p.ring_size = IOAT_TEST_RINGSIZE; - if (rte_rawdev_configure(dev_id, &info) != 0) { + if (rte_rawdev_configure(dev_id, &info, sizeof(p)) != 0) { printf("Error with rte_rawdev_configure()\n"); return -1; } diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c index ced5b6d624..7f6b835a4b 100644 --- a/drivers/raw/ntb/ntb.c +++ b/drivers/raw/ntb/ntb.c @@ -837,13 +837,17 @@ ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info, } static int -ntb_dev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config) +ntb_dev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config, + size_t config_size) { struct ntb_dev_config *conf = config; struct ntb_hw *hw = dev->dev_private; uint32_t xstats_num; int ret; + if (conf == NULL || config_size != sizeof(*conf)) + return -EINVAL; + hw->queue_pairs = conf->num_queues; hw->queue_size = conf->queue_size; hw->used_mw_num = conf->mz_num; diff --git a/drivers/raw/octeontx2_dma/otx2_dpi_rawdev.c b/drivers/raw/octeontx2_dma/otx2_dpi_rawdev.c index e398abb75b..5b496446ca 100644 --- a/drivers/raw/octeontx2_dma/otx2_dpi_rawdev.c +++ b/drivers/raw/octeontx2_dma/otx2_dpi_rawdev.c @@ -294,7 +294,8 @@ otx2_dpi_rawdev_reset(struct rte_rawdev *dev) } static int -otx2_dpi_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config) +otx2_dpi_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config, + size_t config_size) { struct dpi_rawdev_conf_s *conf = config; struct dpi_vf_s *dpivf = NULL; @@ -302,8 +303,8 @@ otx2_dpi_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config) uintptr_t pool; uint32_t gaura; - if (conf == NULL) { - otx2_dpi_dbg("NULL configuration"); + if (conf == NULL || config_size != sizeof(*conf)) { + otx2_dpi_dbg("NULL or invalid configuration"); return -EINVAL; } dpivf = (struct dpi_vf_s *)dev->dev_private; diff --git a/drivers/raw/octeontx2_dma/otx2_dpi_test.c b/drivers/raw/octeontx2_dma/otx2_dpi_test.c index 276658af07..cec6ca91b0 100644 --- a/drivers/raw/octeontx2_dma/otx2_dpi_test.c +++ b/drivers/raw/octeontx2_dma/otx2_dpi_test.c @@ -182,7 +182,8 @@ test_otx2_dma_rawdev(uint16_t val) /* Configure rawdev ports */ conf.chunk_pool = dpi_create_mempool(); rdev_info.dev_private = &conf; - ret = rte_rawdev_configure(i, (rte_rawdev_obj_t)&rdev_info); + ret = rte_rawdev_configure(i, (rte_rawdev_obj_t)&rdev_info, + sizeof(conf)); if (ret) { otx2_dpi_dbg("Unable to configure DPIVF %d", i); return -ENODEV; diff --git a/drivers/raw/octeontx2_ep/otx2_ep_rawdev.c b/drivers/raw/octeontx2_ep/otx2_ep_rawdev.c index 0778603d5b..2b78a7941d 100644 --- a/drivers/raw/octeontx2_ep/otx2_ep_rawdev.c +++ b/drivers/raw/octeontx2_ep/otx2_ep_rawdev.c @@ -224,13 +224,14 @@ sdp_rawdev_close(struct rte_rawdev *dev) } static int -sdp_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config) +sdp_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config, + size_t config_size) { struct sdp_rawdev_info *app_info = (struct sdp_rawdev_info *)config; struct sdp_device *sdpvf; - if (app_info == NULL) { - otx2_err("Application config info [NULL]"); + if (app_info == NULL || config_size != sizeof(*app_info)) { + otx2_err("Application config info [NULL] or incorrect size"); return -EINVAL; } diff --git a/drivers/raw/octeontx2_ep/otx2_ep_test.c b/drivers/raw/octeontx2_ep/otx2_ep_test.c index 091f1827c7..b876275f7a 100644 --- a/drivers/raw/octeontx2_ep/otx2_ep_test.c +++ b/drivers/raw/octeontx2_ep/otx2_ep_test.c @@ -108,7 +108,7 @@ sdp_rawdev_selftest(uint16_t dev_id) dev_info.dev_private = &app_info; - ret = rte_rawdev_configure(dev_id, &dev_info); + ret = rte_rawdev_configure(dev_id, &dev_info, sizeof(app_info)); if (ret) { otx2_err("Unable to configure SDP_VF %d", dev_id); rte_mempool_free(ioq_mpool); diff --git a/drivers/raw/skeleton/skeleton_rawdev.c b/drivers/raw/skeleton/skeleton_rawdev.c index dce300c358..531d0450c8 100644 --- a/drivers/raw/skeleton/skeleton_rawdev.c +++ b/drivers/raw/skeleton/skeleton_rawdev.c @@ -68,7 +68,8 @@ static int skeleton_rawdev_info_get(struct rte_rawdev *dev, } static int skeleton_rawdev_configure(const struct rte_rawdev *dev, - rte_rawdev_obj_t config) + rte_rawdev_obj_t config, + size_t config_size) { struct skeleton_rawdev *skeldev; struct skeleton_rawdev_conf *skeldev_conf; @@ -77,7 +78,7 @@ static int skeleton_rawdev_configure(const struct rte_rawdev *dev, RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); - if (!config) { + if (config == NULL || config_size != sizeof(*skeldev_conf)) { SKELETON_PMD_ERR("Invalid configuration"); return -EINVAL; } diff --git a/drivers/raw/skeleton/skeleton_rawdev_test.c b/drivers/raw/skeleton/skeleton_rawdev_test.c index 9b8390dfb7..7dc7c76847 100644 --- a/drivers/raw/skeleton/skeleton_rawdev_test.c +++ b/drivers/raw/skeleton/skeleton_rawdev_test.c @@ -126,7 +126,7 @@ test_rawdev_configure(void) struct skeleton_rawdev_conf rdev_conf_get = {0}; /* Check invalid configuration */ - ret = rte_rawdev_configure(test_dev_id, NULL); + ret = rte_rawdev_configure(test_dev_id, NULL, 0); RTE_TEST_ASSERT(ret == -EINVAL, "Null configure; Expected -EINVAL, got %d", ret); @@ -137,7 +137,8 @@ test_rawdev_configure(void) rdev_info.dev_private = &rdev_conf_set; ret = rte_rawdev_configure(test_dev_id, - (rte_rawdev_obj_t)&rdev_info); + (rte_rawdev_obj_t)&rdev_info, + sizeof(rdev_conf_set)); RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure rawdev (%d)", ret); rdev_info.dev_private = &rdev_conf_get; diff --git a/examples/ioat/ioatfwd.c b/examples/ioat/ioatfwd.c index 76932d3dd2..43a19843ee 100644 --- a/examples/ioat/ioatfwd.c +++ b/examples/ioat/ioatfwd.c @@ -734,7 +734,7 @@ configure_rawdev_queue(uint32_t dev_id) struct rte_ioat_rawdev_config dev_config = { .ring_size = ring_size }; struct rte_rawdev_info info = { .dev_private = &dev_config }; - if (rte_rawdev_configure(dev_id, &info) != 0) { + if (rte_rawdev_configure(dev_id, &info, sizeof(dev_config)) != 0) { rte_exit(EXIT_FAILURE, "Error with rte_rawdev_configure()\n"); } diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c index 11e224451c..656f736594 100644 --- a/examples/ntb/ntb_fwd.c +++ b/examples/ntb/ntb_fwd.c @@ -1401,7 +1401,7 @@ main(int argc, char **argv) ntb_conf.num_queues = num_queues; ntb_conf.queue_size = nb_desc; ntb_rawdev_conf.dev_private = (rte_rawdev_obj_t)(&ntb_conf); - ret = rte_rawdev_configure(dev_id, &ntb_rawdev_conf); + ret = rte_rawdev_configure(dev_id, &ntb_rawdev_conf, sizeof(ntb_conf)); if (ret) rte_exit(EXIT_FAILURE, "Can't config ntb dev: err=%d, " "port=%u\n", ret, dev_id); diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c index bde33763ee..6c4d783cc5 100644 --- a/lib/librte_rawdev/rte_rawdev.c +++ b/lib/librte_rawdev/rte_rawdev.c @@ -104,7 +104,8 @@ rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info, } int -rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf) +rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf, + size_t dev_private_size) { struct rte_rawdev *dev; int diag; @@ -123,7 +124,8 @@ rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf) } /* Configure the device */ - diag = (*dev->dev_ops->dev_configure)(dev, dev_conf->dev_private); + diag = (*dev->dev_ops->dev_configure)(dev, dev_conf->dev_private, + dev_private_size); if (diag != 0) RTE_RDEV_ERR("dev%d dev_configure = %d", dev_id, diag); else diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h index cf6acfd261..73e3bd5aea 100644 --- a/lib/librte_rawdev/rte_rawdev.h +++ b/lib/librte_rawdev/rte_rawdev.h @@ -116,13 +116,19 @@ rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info, * driver/implementation can use to configure the device. It is also assumed * that once the configuration is done, a `queue_id` type field can be used * to refer to some arbitrary internal representation of a queue. + * @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 + * used by the driver, and may be checked by drivers to ensure the expected + * struct type is provided. * * @return * - 0: Success, device configured. * - <0: Error code returned by the driver configuration function. */ int -rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf); +rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf, + size_t dev_private_size); /** diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h index 89e46412a3..050f8b0292 100644 --- a/lib/librte_rawdev/rte_rawdev_pmd.h +++ b/lib/librte_rawdev/rte_rawdev_pmd.h @@ -160,7 +160,8 @@ typedef int (*rawdev_info_get_t)(struct rte_rawdev *dev, * Returns 0 on success */ typedef int (*rawdev_configure_t)(const struct rte_rawdev *dev, - rte_rawdev_obj_t config); + rte_rawdev_obj_t config, + size_t config_size); /** * Start a configured device. -- 2.25.1
next prev parent reply other threads:[~2020-08-13 11:28 UTC|newest] Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-07-09 15:20 [dpdk-dev] [PATCH 20.11 0/5] Enhance rawdev APIs Bruce Richardson 2020-07-09 15:20 ` [dpdk-dev] [PATCH 20.11 1/5] rawdev: add private data length parameter to info fn Bruce Richardson 2020-07-12 14:13 ` Xu, Rosen 2020-07-09 15:20 ` [dpdk-dev] [PATCH 20.11 2/5] rawdev: allow drivers to return error from info function Bruce Richardson 2020-07-12 14:13 ` Xu, Rosen 2020-07-09 15:20 ` [dpdk-dev] [PATCH 20.11 3/5] rawdev: add private data length parameter to config fn Bruce Richardson 2020-07-12 14:13 ` Xu, Rosen 2020-07-09 15:20 ` [dpdk-dev] [PATCH 20.11 4/5] rawdev: add private data length parameter to queue fns Bruce Richardson 2020-07-09 15:20 ` [dpdk-dev] [PATCH 20.11 5/5] rawdev: allow queue default config query to return error Bruce Richardson 2020-08-13 11:27 ` [dpdk-dev] [PATCH v2 0/7] Enhance rawdev APIs Bruce Richardson 2020-08-13 11:27 ` [dpdk-dev] [PATCH v2 1/7] rawdev: add private data length parameter to info fn Bruce Richardson 2020-08-17 5:26 ` Xu, Rosen 2020-08-13 11:28 ` [dpdk-dev] [PATCH v2 2/7] rawdev: allow drivers to return error from info function Bruce Richardson 2020-08-13 11:28 ` Bruce Richardson [this message] 2020-09-04 14:16 ` [dpdk-dev] [PATCH v2 3/7] rawdev: add private data length parameter to config fn Bruce Richardson 2020-08-13 11:28 ` [dpdk-dev] [PATCH v2 4/7] rawdev: add private data length parameter to queue fns Bruce Richardson 2020-08-13 11:28 ` [dpdk-dev] [PATCH v2 5/7] rawdev: allow queue default config query to return error Bruce Richardson 2020-08-13 11:28 ` [dpdk-dev] [PATCH v2 6/7] rawdev: mark start and stop functions optional Bruce Richardson 2020-08-13 11:28 ` [dpdk-dev] [PATCH v2 7/7] doc: remove rawdev deprecation notice Bruce Richardson 2020-09-02 11:21 ` [dpdk-dev] [PATCH v2 0/7] Enhance rawdev APIs Nipun Gupta 2020-09-09 9:47 ` Thomas Monjalon 2020-09-10 14:36 ` [dpdk-dev] [PATCH v3 " Bruce Richardson 2020-09-10 14:36 ` [dpdk-dev] [PATCH v3 1/7] rawdev: add private data length parameter to info fn Bruce Richardson 2020-09-10 14:36 ` [dpdk-dev] [PATCH v3 2/7] rawdev: allow drivers to return error from info function Bruce Richardson 2020-09-10 14:36 ` [dpdk-dev] [PATCH v3 3/7] rawdev: add private data length parameter to config fn Bruce Richardson 2020-09-10 14:36 ` [dpdk-dev] [PATCH v3 4/7] rawdev: add private data length parameter to queue fns Bruce Richardson 2020-09-10 14:36 ` [dpdk-dev] [PATCH v3 5/7] rawdev: allow queue config query to return error Bruce Richardson 2020-09-10 14:36 ` [dpdk-dev] [PATCH v3 6/7] rawdev: mark start and stop functions optional Bruce Richardson 2020-09-10 14:36 ` [dpdk-dev] [PATCH v3 7/7] doc: remove rawdev deprecation notice Bruce Richardson 2020-09-11 9:56 ` [dpdk-dev] [PATCH v3 0/7] Enhance rawdev APIs Thomas Monjalon
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200813112806.164578-4-bruce.richardson@intel.com \ --to=bruce.richardson@intel.com \ --cc=dev@dpdk.org \ --cc=hemant.agrawal@nxp.com \ --cc=jingjing.wu@intel.com \ --cc=john.mcnamara@intel.com \ --cc=marko.kovacevic@intel.com \ --cc=mchalla@marvell.com \ --cc=nipun.gupta@nxp.com \ --cc=rosen.xu@intel.com \ --cc=skoteshwar@marvell.com \ --cc=tianfei.zhang@intel.com \ --cc=xiaoyun.li@intel.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
DPDK patches and discussions This inbox may be cloned and mirrored by anyone: git clone --mirror http://inbox.dpdk.org/dev/0 dev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 dev dev/ http://inbox.dpdk.org/dev \ dev@dpdk.org public-inbox-index dev Example config snippet for mirrors. Newsgroup available over NNTP: nntp://inbox.dpdk.org/inbox.dpdk.dev AGPL code for this site: git clone https://public-inbox.org/public-inbox.git