From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
To: "Zhang, Roy Fan" <roy.fan.zhang@intel.com>,
"dev@dpdk.org" <dev@dpdk.org>
Cc: "akhil.goyal@nxp.com" <akhil.goyal@nxp.com>
Subject: Re: [dpdk-dev] [PATCH 2/2] cryptodev: change symmetric session structure
Date: Fri, 16 Nov 2018 14:32:12 +0000 [thread overview]
Message-ID: <2601191342CEEE43887BDE71AB977258010CEB8E63@IRSMSX106.ger.corp.intel.com> (raw)
In-Reply-To: <20181115172427.67607-3-roy.fan.zhang@intel.com>
Hi Fan,
>
> This patch changes the symmetric session structure of cryptodev.
> The symmetric session now contains extra information for secure
> access purposes. The patch also includes the updates to the
> PMDs, test applications, and examples to fit the change.
Few more comments from me in-line below.
Also a generic question - docs also might also need to be updated?
Apart from that and naming collisions - looks good overall.
Konstantin
>
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> ---
> app/test-crypto-perf/cperf_ops.c | 11 +-
> app/test-crypto-perf/main.c | 91 ++++++++----
> drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 3 +-
> drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 3 +-
> drivers/crypto/armv8/rte_armv8_pmd.c | 3 +-
> drivers/crypto/kasumi/rte_kasumi_pmd.c | 3 +-
> drivers/crypto/openssl/rte_openssl_pmd.c | 3 +-
> drivers/crypto/snow3g/rte_snow3g_pmd.c | 3 +-
> drivers/crypto/zuc/rte_zuc_pmd.c | 3 +-
> examples/fips_validation/main.c | 43 ++++--
> examples/l2fwd-crypto/main.c | 66 ++++++---
> examples/vhost_crypto/main.c | 12 +-
Shouldn't ipsec-secgw also be updated?
> lib/librte_cryptodev/rte_cryptodev.c | 142 +++++++++++++++----
> lib/librte_cryptodev/rte_cryptodev.h | 65 ++++++++-
> lib/librte_cryptodev/rte_cryptodev_pmd.h | 4 +-
> lib/librte_vhost/rte_vhost_crypto.h | 9 +-
> lib/librte_vhost/vhost_crypto.c | 8 +-
> test/test/test_cryptodev.c | 220 +++++++++++++++++------------
> test/test/test_cryptodev_blockcipher.c | 7 +-
> test/test/test_cryptodev_blockcipher.h | 1 +
> test/test/test_event_crypto_adapter.c | 32 +++--
> 21 files changed, 515 insertions(+), 217 deletions(-)
>
...
> diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> index b0f5c4d67..135a2d8cb 100644
> --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
> @@ -951,7 +951,8 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
> if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
> memset(sess, 0, sizeof(struct aesni_mb_session));
> memset(op->sym->session, 0,
> - rte_cryptodev_sym_get_header_session_size());
> + rte_cryptodev_sym_get_header_session_size(
> + op->sym->session));
> rte_mempool_put(qp->sess_mp_priv, sess);
> rte_mempool_put(qp->sess_mp, op->sym->session);
> op->sym->session = NULL;
As a generic one - all the drivers for session-less sessions assume that sess_mp is initialized with
DIM(sess_data[]) greater than their driver id.
It is a valid assumption, but should we add extra check in rte_cryptodev_queue_pair_setup()?
...
> diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
> index 11776b6ac..920a32cd6 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.c
> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> @@ -1143,7 +1143,6 @@ rte_cryptodev_pmd_callback_process(struct rte_cryptodev *dev,
> rte_spinlock_unlock(&rte_cryptodev_cb_lock);
> }
>
> -
> int
> rte_cryptodev_sym_session_init(uint8_t dev_id,
> struct rte_cryptodev_sym_session *sess,
> @@ -1160,12 +1159,15 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
> return -EINVAL;
>
> index = dev->driver_id;
> + if (index > sess->nb_drivers)
> + return -EINVAL;
>
> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->sym_session_configure, -ENOTSUP);
>
> - if (sess->sess_private_data[index] == NULL) {
> + if (sess->sess_data[index].refcnt == 0) {
> ret = dev->dev_ops->sym_session_configure(dev, xforms,
> - sess, mp);
> + sess, mp);
> +
> if (ret < 0) {
> CDEV_LOG_ERR(
> "dev_id %d failed to configure session details",
> @@ -1174,6 +1176,7 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
> }
> }
>
> + sess->sess_data[index].refcnt++;
> return 0;
> }
>
> @@ -1212,10 +1215,70 @@ rte_cryptodev_asym_session_init(uint8_t dev_id,
> return 0;
> }
>
> +struct rte_cryptodev_sym_session_pool_private_data {
> + uint16_t nb_drivers;
> + /**< number of elements in sess_data array */
> + uint16_t priv_size;
> + /**< session private data will be placed after sess_data */
> +};
> +
> +struct rte_mempool *
> +rte_cryptodev_sym_session_pool_create(const char *name,
> + uint32_t nb_elts, uint32_t cache_size, uint16_t priv_size,
> + int socket_id)
> +{
> + struct rte_mempool *mp;
> + uint32_t elt_size;
> + struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
> +
> + elt_size = (uint32_t)rte_cryptodev_sym_get_header_session_size(NULL) +
> + priv_size;
> + mp = rte_mempool_create(name, nb_elts, elt_size, cache_size,
> + (uint32_t)(sizeof(*pool_priv)),
> + NULL, NULL, NULL, NULL,
> + socket_id, 0);
> + if (mp == NULL)
> + CDEV_LOG_ERR("%s(name=%s) failed, rte_errno=%d\n",
> + __func__, name, rte_errno);
> +
> + pool_priv = rte_mempool_get_priv(mp);
> + if (!pool_priv) {
> + CDEV_LOG_ERR("%s(name=%s) failed to get private data\n",
> + __func__, name);
> + rte_mempool_free(mp);
> + return NULL;
> + }
> +
> + pool_priv->nb_drivers = nb_drivers;
> + pool_priv->priv_size = priv_size;
> +
> + return mp;
> +}
> +
> +static unsigned int
> +rte_cryptodev_sym_session_data_size(struct rte_cryptodev_sym_session *sess)
> +{
> + return (sizeof(sess->sess_data[0]) * sess->nb_drivers) +
> + sess->priv_size;
> +}
> +
> struct rte_cryptodev_sym_session *
> rte_cryptodev_sym_session_create(struct rte_mempool *mp)
> {
> struct rte_cryptodev_sym_session *sess;
> + struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
> +
> + if (!mp) {
> + CDEV_LOG_ERR("Invalid mempool\n");
> + return NULL;
> + }
> +
> + pool_priv = rte_mempool_get_priv(mp);
> +
> + if (!pool_priv || mp->private_data_size < sizeof(*pool_priv)) {
> + CDEV_LOG_ERR("Invalid mempool\n");
> + return NULL;
> + }
>
> /* Allocate a session structure from the session pool */
> if (rte_mempool_get(mp, (void **)&sess)) {
> @@ -1226,7 +1289,12 @@ rte_cryptodev_sym_session_create(struct rte_mempool *mp)
> /* Clear device session pointer.
> * Include the flag indicating presence of user data
> */
> - memset(sess, 0, (sizeof(void *) * nb_drivers) + sizeof(uint8_t));
> + sess->nb_drivers = pool_priv->nb_drivers;
> + sess->priv_size = pool_priv->priv_size;
> + sess->userdata = 0;
> +
> + memset(sess->sess_data, 0,
> + rte_cryptodev_sym_session_data_size(sess));
>
> return sess;
> }
> @@ -1255,12 +1323,17 @@ rte_cryptodev_sym_session_clear(uint8_t dev_id,
> struct rte_cryptodev_sym_session *sess)
> {
> struct rte_cryptodev *dev;
> + uint8_t driver_id;
>
> dev = rte_cryptodev_pmd_get_dev(dev_id);
>
> if (dev == NULL || sess == NULL)
> return -EINVAL;
>
> + driver_id = dev->driver_id;
> + if (--sess->sess_data[driver_id].refcnt != 0)
> + return -EBUSY;
> +
> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->sym_session_clear, -ENOTSUP);
>
> dev->dev_ops->sym_session_clear(dev, sess);
> @@ -1290,16 +1363,15 @@ int
> rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
> {
> uint8_t i;
> - void *sess_priv;
> struct rte_mempool *sess_mp;
>
> if (sess == NULL)
> return -EINVAL;
>
> /* Check that all device private data has been freed */
> + /* Check that all device private data has been freed */
> for (i = 0; i < nb_drivers; i++) {
As Fiona pointed we have to use sess->nb_drivers here.
> - sess_priv = get_sym_session_private_data(sess, i);
> - if (sess_priv != NULL)
> + if (sess->sess_data[i].refcnt != 0)
> return -EBUSY;
> }
>
> @@ -1336,14 +1408,24 @@ rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess)
>
>
> unsigned int
> -rte_cryptodev_sym_get_header_session_size(void)
> +rte_cryptodev_sym_get_header_session_size(
> + struct rte_cryptodev_sym_session *sess)
That's a change in the public API, np in general,
but I suppose needs to be documented (release notes?).
> {
> /*
> * Header contains pointers to the private data
> * of all registered drivers, and a flag which
> * indicates presence of user data
> */
> - return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
> + if (!sess) {
> + struct rte_cryptodev_sym_session s = {0};
> + s.nb_drivers = nb_drivers;
> + s.priv_size = 0;
> +
> + return (unsigned int)(sizeof(s) +
> + rte_cryptodev_sym_session_data_size(&s));
> + } else
> + return (unsigned int)(sizeof(*sess) +
> + rte_cryptodev_sym_session_data_size(sess));
> }
>
> unsigned int __rte_experimental
> @@ -1361,7 +1443,6 @@ unsigned int
> rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
> {
> struct rte_cryptodev *dev;
> - unsigned int header_size = sizeof(void *) * nb_drivers;
> unsigned int priv_sess_size;
>
> if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
> @@ -1374,19 +1455,27 @@ rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
>
> priv_sess_size = (*dev->dev_ops->sym_session_get_size)(dev);
>
> - /*
> - * If size is less than session header size,
> - * return the latter, as this guarantees that
> - * sessionless operations will work
> - */
> - if (priv_sess_size < header_size)
> - return header_size;
> -
> return priv_sess_size;
>
> }
>
> unsigned int __rte_experimental
> +rte_cryptodev_sym_get_max_private_session_size(void)
> +{
> + unsigned int priv_sess_size = 0;
> + uint8_t dev_id;
> +
> + for (dev_id = 0; dev_id < rte_cryptodev_count(); dev_id++) {
> + unsigned int dev_p_size =
> + rte_cryptodev_sym_get_private_session_size(dev_id);
> +
> + priv_sess_size = RTE_MAX(priv_sess_size, dev_p_size);
> + }
> +
> + return priv_sess_size;
> +}
> +
> +unsigned int __rte_experimental
> rte_cryptodev_asym_get_private_session_size(uint8_t dev_id)
> {
> struct rte_cryptodev *dev;
> @@ -1415,15 +1504,10 @@ rte_cryptodev_sym_session_set_user_data(
> void *data,
> uint16_t size)
> {
> - uint16_t off_set = sizeof(void *) * nb_drivers;
> - uint8_t *user_data_present = (uint8_t *)sess + off_set;
> -
> - if (sess == NULL)
> + if (sess == NULL || sess->priv_size < size)
> return -EINVAL;
>
> - *user_data_present = 1;
> - off_set += sizeof(uint8_t);
> - rte_memcpy((uint8_t *)sess + off_set, data, size);
> + rte_memcpy(sess->sess_data + sess->nb_drivers, data, size);
> return 0;
> }
>
> @@ -1431,14 +1515,10 @@ void * __rte_experimental
> rte_cryptodev_sym_session_get_user_data(
> struct rte_cryptodev_sym_session *sess)
> {
> - uint16_t off_set = sizeof(void *) * nb_drivers;
> - uint8_t *user_data_present = (uint8_t *)sess + off_set;
> -
> - if (sess == NULL || !*user_data_present)
> + if (sess == NULL || sess->priv_size == 0)
> return NULL;
>
> - off_set += sizeof(uint8_t);
> - return (uint8_t *)sess + off_set;
> + return (void *)(sess->sess_data + sess->nb_drivers);
> }
>
> /** Initialise rte_crypto_op mempool element */
> diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
> index f9e7507da..999253f1f 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -951,14 +951,22 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> dev->data->queue_pairs[qp_id], ops, nb_ops);
> }
>
> -
> /** Cryptodev symmetric crypto session
> * Each session is derived from a fixed xform chain. Therefore each session
> * has a fixed algo, key, op-type, digest_len etc.
> */
> struct rte_cryptodev_sym_session {
> - __extension__ void *sess_private_data[0];
> - /**< Private symmetric session material */
> + uint64_t userdata;
> + /**< Can be used for external metadata */
> + uint16_t nb_drivers;
> + /**< number of elements in sess_data array */
> + uint16_t priv_size;
> + /**< session private data will be placed after sess_data */
> + __extension__ struct {
> + void *data;
> + uint16_t refcnt;
> + } sess_data[0];
> + /**< Driver specific session material, variable size */
> };
>
> /** Cryptodev asymmetric crypto session */
> @@ -968,6 +976,31 @@ struct rte_cryptodev_asym_session {
> };
>
> /**
> + * Create a symmetric session mempool.
> + *
> + * @param name
> + * The unique mempool name.
> + * @param nb_elts
> + * The number of elements in the mempool.
> + * @param cache_size
> + * The number of per-lcore cache elements
> + * @param priv_size
> + * The private data size of each session.
> + * @param socket_id
> + * The *socket_id* argument is the socket identifier in the case of
> + * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
> + * constraint for the reserved zone.
> + *
> + * @return
> + * - On success return size of the session
> + * - On failure returns 0
> + */
> +struct rte_mempool *
> +rte_cryptodev_sym_session_pool_create(const char *name,
> + uint32_t nb_elts, uint32_t cache_size, uint16_t priv_size,
> + int socket_id);
New function - needs experimental tag, I think.
> +
> +/**
> * Create symmetric crypto session header (generic with no private data)
> *
> * @param mempool Symmetric session mempool to allocate session
> @@ -1097,13 +1130,22 @@ rte_cryptodev_asym_session_clear(uint8_t dev_id,
> struct rte_cryptodev_asym_session *sess);
>
> /**
> - * Get the size of the header session, for all registered drivers.
> + * Get the size of the header session, for all registered drivers excluding
> + * the private data size
> + *
> + * @param sess
> + * The sym cryptodev session pointer
> *
> * @return
> - * Size of the symmetric eader session.
> + * - If sess is not NULL, return the size of the header session including
> + * the private data size defined within sess.
> + * - If sess is NULL, return the size of the header session excluded
> + * the private data size. This way can be used for creating the session
> + * mempool but the user has to add its private data to this return manually.
> */
> unsigned int
> -rte_cryptodev_sym_get_header_session_size(void);
> +rte_cryptodev_sym_get_header_session_size(
> + struct rte_cryptodev_sym_session *sess);
>
> /**
> * Get the size of the asymmetric session header, for all registered drivers.
> @@ -1129,6 +1171,17 @@ unsigned int
> rte_cryptodev_sym_get_private_session_size(uint8_t dev_id);
>
> /**
> + * Get the maximum size of the private symmetric session data
> + * for all devices.
> + *
> + * @return
> + * - Size of the maximum private data, if successful.
> + * - 0 if there is no device in the system.
> + */
> +unsigned int __rte_experimental
> +rte_cryptodev_sym_get_max_private_session_size(void);
> +
> +/**
> * Get the size of the private data for asymmetric session
> * on device
> *
next prev parent reply other threads:[~2018-11-16 14:32 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-15 17:24 [dpdk-dev] [PATCH 0/2] lib/cryptodev: change qp conf and sym session Fan Zhang
2018-11-15 17:24 ` [dpdk-dev] [PATCH 1/2] cryptodev: change queue pair configure structure Fan Zhang
2018-11-16 12:05 ` Ananyev, Konstantin
2018-11-19 10:12 ` Zhang, Roy Fan
2018-12-04 16:05 ` Trahe, Fiona
2018-11-15 17:24 ` [dpdk-dev] [PATCH 2/2] cryptodev: change symmetric session structure Fan Zhang
2018-11-16 0:47 ` Ananyev, Konstantin
2018-11-16 14:32 ` Ananyev, Konstantin [this message]
2018-11-19 10:11 ` Zhang, Roy Fan
2018-12-11 10:34 ` [dpdk-dev] [PATCH v2 0/2] lib/cryptodev: change qp conf and sym session Fan Zhang
2018-12-11 10:34 ` [dpdk-dev] [PATCH v2 1/2] cryptodev: change queue pair configure structure Fan Zhang
2018-12-17 19:31 ` Trahe, Fiona
2018-12-11 10:34 ` [dpdk-dev] [PATCH v2 2/2] cryptodev: change symmetric session structure Fan Zhang
2018-12-17 20:29 ` Trahe, Fiona
2018-12-18 16:25 ` Zhang, Roy Fan
2018-12-18 16:32 ` Trahe, Fiona
2018-12-11 12:26 ` [dpdk-dev] [PATCH v2 0/2] lib/cryptodev: change qp conf and sym session Ananyev, Konstantin
2018-12-21 13:55 ` [dpdk-dev] [PATCH v3 0/2] cryptodev: " Fan Zhang
2018-12-21 13:55 ` [dpdk-dev] [PATCH v3 1/2] cryptodev: change queue pair configure structure Fan Zhang
2019-01-08 23:20 ` De Lara Guarch, Pablo
2019-01-09 11:30 ` Zhang, Roy Fan
2019-01-09 10:41 ` De Lara Guarch, Pablo
2018-12-21 13:55 ` [dpdk-dev] [PATCH v3 2/2] cryptodev: change symmetric session structure Fan Zhang
2019-01-08 16:12 ` Trahe, Fiona
2019-01-09 11:01 ` De Lara Guarch, Pablo
2019-01-09 11:10 ` Zhang, Roy Fan
2019-01-09 22:55 ` [dpdk-dev] [PATCH v4 00/12] cryptodev: change qp conf and sym session Fan Zhang
2019-01-09 22:55 ` [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair configure structure Fan Zhang
2019-01-10 9:47 ` De Lara Guarch, Pablo
2019-01-10 11:24 ` De Lara Guarch, Pablo
2019-01-09 22:55 ` [dpdk-dev] [PATCH v4 02/12] cryptodev: add sym session mempool create Fan Zhang
2019-01-10 11:22 ` De Lara Guarch, Pablo
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 03/12] app/test-crypto-perf: use separate session mempools Fan Zhang
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 04/12] net/softnic: " Fan Zhang
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 05/12] examples: " Fan Zhang
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 06/12] vhost/crypto: " Fan Zhang
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 07/12] test/crypto: " Fan Zhang
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 08/12] cryptodev: add sym session header size API Fan Zhang
2019-01-10 13:28 ` De Lara Guarch, Pablo
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 09/12] cryptodev: update symmetric session structure Fan Zhang
2019-01-10 13:06 ` De Lara Guarch, Pablo
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 10/12] cryptodev: add user data size to symmetric session Fan Zhang
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 11/12] cryptodev: add reference count to session private data Fan Zhang
2019-01-10 12:35 ` De Lara Guarch, Pablo
2019-01-09 22:56 ` [dpdk-dev] [PATCH v4 12/12] cryptodev: add opaque data field to symmetric session Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 00/12] cryptodev: change qp conf and sym session Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 01/12] cryptodev: change queue pair configure structure Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 02/12] cryptodev: add sym session mempool create Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 03/12] app/test-crypto-perf: use separate session mempools Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 04/12] net/softnic: " Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 05/12] examples: " Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 06/12] vhost/crypto: " Fan Zhang
2019-01-11 9:13 ` Maxime Coquelin
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 07/12] test/crypto: " Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 08/12] cryptodev: add sym session header size API Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 09/12] cryptodev: update symmetric session structure Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 10/12] cryptodev: add user data size to symmetric session Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 11/12] cryptodev: add reference count to session private data Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 12/12] cryptodev: add opaque data field to symmetric session Fan Zhang
2019-01-10 15:06 ` [dpdk-dev] [PATCH v5 00/12] cryptodev: change qp conf and sym session Akhil Goyal
2019-01-10 17:18 ` De Lara Guarch, Pablo
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=2601191342CEEE43887BDE71AB977258010CEB8E63@IRSMSX106.ger.corp.intel.com \
--to=konstantin.ananyev@intel.com \
--cc=akhil.goyal@nxp.com \
--cc=dev@dpdk.org \
--cc=roy.fan.zhang@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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).