In the patchset, that removes the GNU style zero length arrays, there is a problem caused by the use of these in the cryptodev header files.
For both rte_session and rte_cryptodev, the current convention is to do: struct rte_security_session { RTE_MARKER cacheline0; uint64_t opaque_data; /**< Opaque user defined data */ uint64_t fast_mdata; /**< Fast metadata to be used for inline path */ rte_iova_t driver_priv_data_iova; /**< session private data IOVA address */ RTE_MARKER cacheline1 __rte_cache_min_aligned; uint8_t driver_priv_data[0]; /**< Private session material, variable size (depends on driver) */ }; This can not just be replaced with a C90 flex array because then clang correctly complains of using flex array not at the end of the structure. struct cn9k_sec_session { struct rte_security_session rte_sess; /** PMD private space */ /** ESN */ union { uint64_t esn; struct { uint32_t seq_lo; uint32_t seq_hi; }; }; /** IPsec SA direction */ uint8_t is_outbound; /* ESN enable flag */ uint8_t esn_en; /** Pre-populated CPT inst words */ struct cnxk_cpt_inst_tmpl inst; /** Response length calculation data */ struct cnxk_ipsec_outb_rlens rlens; /** Anti replay window size */ uint32_t replay_win_sz; /** Cipher IV offset in bytes */ uint16_t cipher_iv_off; /** Cipher IV length in bytes */ uint8_t cipher_iv_len; /** Outbound custom header length */ uint8_t custom_hdr_len; /** Anti replay */ struct cnxk_on_ipsec_ar ar; /** Queue pair */ struct cnxk_cpt_qp *qp; struct cn9k_ipsec_sa sa; } __rte_cache_aligned; There are a couple of ways to fix this, and both are non-trivial. The first is to get rid of the priv_data element and modify the management to do the cache alignment. Something like: diff --git a/lib/security/rte_security_driver.h b/lib/security/rte_security_driver.h index faa4074f1965..ffc5b5d7257b 100644 --- a/lib/security/rte_security_driver.h +++ b/lib/security/rte_security_driver.h @@ -30,11 +30,6 @@ struct rte_security_session { uint64_t fast_mdata; /**< Fast metadata to be used for inline path */ rte_iova_t driver_priv_data_iova; - /**< session private data IOVA address */ - - RTE_MARKER cacheline1 __rte_cache_min_aligned; - uint8_t driver_priv_data[]; - /**< Private session material, variable size (depends on driver) */ }; /** @@ -61,13 +56,33 @@ struct rte_security_ctx { /**< Number of MACsec SA attached to this context */ }; +/** + * Helper to acces rte_session private data + * @param sess + * Pointer to Security private session structure + * + * @return + * Pointer to area reserved for private data + */ +static inline void * +rte_security_priv(const struct rte_security_session *sess) +{ + return (void *)((uintptr_t)sess + RTE_CACHE_LINE_ROUNDUP(sizeof(*sess))); +} + diff --git a/lib/security/rte_security.c b/lib/security/rte_security.c index b082a290296b..f3202e3df6cd 100644 --- a/lib/security/rte_security.c +++ b/lib/security/rte_security.c @@ -66,6 +66,7 @@ rte_security_session_create(void *ctx, { struct rte_security_session *sess = NULL; struct rte_security_ctx *instance = ctx; + const size_t sess_size = RTE_CACHE_LINE_ROUNDUP(sizeof(*sess)); uint32_t sess_priv_size; RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_create, NULL, NULL); @@ -73,17 +74,16 @@ rte_security_session_create(void *ctx, RTE_PTR_OR_ERR_RET(mp, NULL); sess_priv_size = instance->ops->session_get_size(instance->device); - if (mp->elt_size < (sizeof(struct rte_security_session) + sess_priv_size)) + if (mp->elt_size < sess_size + sess_priv_size) return NULL; if (rte_mempool_get(mp, (void **)&sess)) return NULL; /* Clear session priv data */ - memset(sess->driver_priv_data, 0, sess_priv_size); + memset(rte_security_priv(sess), 0, sess_priv_size); - sess->driver_priv_data_iova = rte_mempool_virt2iova(sess) + - offsetof(struct rte_security_session, driver_priv_data); + sess->driver_priv_data_iova = rte_mempool_virt2iova(sess) + sess_size; if (instance->ops->session_create(instance->device, conf, sess)) { rte_mempool_put(mp, (v This is what Linux kernel does with netdev_priv() helper. There is also a lot of open coded versions of same thing in Intel crypto drivers. Anything with that many casts looks like a design mistake to me. struct ixgbe_crypto_session *ic_session = (void *)(uintptr_t) ((const struct rte_security_session *)sess)->driver_priv_data;