On 19.04.2017 13:00, Shally Verma wrote: > An API set to add compression/decompression support in ODP > interface. > > Signed-off-by: Shally Verma <sve...@cavium.com> > Signed-off-by: Mahipal Challa <mcha...@cavium.com> > --- > include/odp/api/spec/comp.h | 748 > ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 748 insertions(+) > > diff --git a/include/odp/api/spec/comp.h b/include/odp/api/spec/comp.h > new file mode 100644 > index 0000000..65feacf > --- /dev/null > +++ b/include/odp/api/spec/comp.h > @@ -0,0 +1,748 @@ > +/* > + */ > + > +/** > + * @file > + * > + * ODP Compression > + */ > + > +#ifndef ODP_API_COMP_H_ > +#define ODP_API_COMP_H_ > +#include <odp/visibility_begin.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** @defgroup odp_compression ODP COMP > + * ODP Compression defines interface to compress/decompress and authenticate > + * data. > + * > + * Compression here implicilty refer to both compression and decompression. > + * Example, compression algo 'deflate' mean both 'deflate' and 'inflate'. > + * > + * if opcode = ODP_COMP_COMPRESS, then it will Compress, > + * if opcode = ODP_COMP_DECOMPRESS, then it will Decompress. > + * > + * Current version of Interface allow Compression ONLY,Authentication ONLY > or > + * both Compression + Auth ONLY sessions. > + * > + * Macros, enums, types and operations to utilise compression. > + * @{ > + */ > + > +/** > + * @def ODP_COMP_SESSION_INVALID > + * Invalid session handle > + */ > + > +/** > + * @typedef odp_comp_session_t (platform dependent) > + * Comp API opaque session handle > + */ > + > +/** > + * @typedef odp_comp_compl_t > +* Compression API completion event (platform dependent) > +*/ > + > +/** > + * Compression API operation mode > + */ > +typedef enum { > + /** Synchronous, return results immediately */ > + ODP_COMP_SYNC, > + /** Asynchronous, return results via queue event */ > + ODP_COMP_ASYNC, > +} odp_comp_op_mode_t; > + > +/** > + * Comp API operation type. > + * Ignored for Authentication ONLY. > + * > + */ > +typedef enum { > + /** Compress and/or Compute digest */ > + ODP_COMP_OP_COMPRESS, > + /** Decompress and/or Compute digest */ > + ODP_COMP_OP_DECOMPRESS, > +} odp_comp_op_t; > + > +/** > + * Comp API authentication algorithm > + * > + */ > +typedef enum { > + /** No authentication algorithm specified */ > + ODP_COMP_AUTH_ALG_NULL, > + /** ODP_COMP_AUTH_ALG_SHA1*/ > + ODP_COMP_AUTH_ALG_SHA1, > + /** ODP_COMP_AUTH_ALG_SHA256*/ > + ODP_COMP_AUTH_ALG_SHA256 > +} odp_comp_auth_alg_t;
Why do you need special comp_auth_alg instead of just odp_auth_alg_t? > + > +/** > + * Comp API compression algorithm > + * > + */ > +typedef enum { > + /** No algorithm specified. > + * Means no compression, no output provided. > + */ > + ODP_COMP_ALG_NULL, > + /** DEFLATE - > + * implicit Inflate in case of decode operation. > + */ > + ODP_COMP_ALG_DEFLATE, > + /** ZLIB-RFC1950 */ > + ODP_COMP_ALG_ZLIB, > + /** LZS*/ > + ODP_COMP_ALG_LZS, > +} odp_comp_alg_t; > + > +/** > + * Comp API session creation return code > + * > + */ > +typedef enum { > + /** Session created */ > + ODP_COMP_SES_CREATE_ERR_NONE, > + /** Creation failed, no resources */ > + ODP_COMP_SES_CREATE_ERR_ENOMEM, > + /** Creation failed, bad compression params */ > + ODP_COMP_SES_CREATE_ERR_INV_COMP, > + /** Creation failed, bad auth params */ > + ODP_COMP_SES_CREATE_ERR_INV_AUTH, > + /** Creation failed,requested configuration not supported*/ > + ODP_COMP_SES_CREATE_ERR_NOT_SUPPORTED > +} odp_comp_ses_create_err_t; > + > +/** > + * Comp API operation return codes > + * > + */ > +typedef enum { > + /** Operation completed successfully*/ > + ODP_COMP_ERR_NONE, > + /** Invalid user data pointers*/ > + ODP_COMP_ERR_DATA_PTR, > + /** Invalid input data size*/ > + ODP_COMP_ERR_DATA_SIZE, > + /** Compression and/or Auth Algo failure*/ > + ODP_COMP_ERR_ALGO_FAIL, > + /** Error detected during DMA of data*/ > + ODP_COMP_ERR_DMA, > + /** Operation paused due to insufficient output buffer > + * > + * This is not an error condition. On seeing this error, caller > + * should call odp_comp_operation() again with valid output buffer > + * with no-more input or altercation to other input > + * operation parameters. > + * > + * for applications, considering this an error condition should destroy > + * and re-create session to start afresh. > + * > + * Implementation should maintain context in this condition. > + */ > + ODP_COMP_ERR_OUT_OF_SPACE, > + /** Error if operation has been requested in an invalid state */ > + ODP_COMP_ERR_INV_STATE > +} odp_comp_err_t; > + > +/** > +* Comp API enumeration for preferred compression level/speed. > +* > +* trade-off between speed and compression ratio. > +* > +* Please note this enumeration is only a peferential selection > +* but may not guarantee operation to committed level depending > +* on implementation support. Ex. SPEED_FASTEST and SPEED_FAST may > +* give same result on some platforms. > +* > +*/ > +typedef enum { > + /* Use implementaion default between ratio and speed */ > + ODP_COMP_SPEED_DEFAULT = 0, > + /** fastest speed, lowest compression */ > + ODP_COMP_SPEED_FASTEST, > + /** fast speed, lower compression */ > + ODP_COMP_SPEED_FAST, > + /** medium speed, medium compression */ > + ODP_COMP_SPEED_MED, > + /** slowest speed, maximum compression */ > + ODP_COMP_SPEED_SLOWEST, > + > +} odp_comp_speed_t; It might be easier to specify this as unsigned integer and "max" speed level specific to exact algorithm implementation acquired through capabilities. > + > +/** > + * Comp API enumeration for encoding type > + * > + */ > +typedef enum { > + /** use implementation default to choose between compression codes */ > + ODP_COMP_CODE_DEFAULT = 0, > + /** use fixed huffman codes */ > + ODP_COMP_CODE_FIX_HUFFMAN, > + /** use dynamic huffman coding */ > + ODP_COMP_CODE_DYN_HUFFMAN, > +} odp_comp_code_t; Isn't this too specific? > + > +/** > + * Authentication algorithms in a bit field structure > + * > + */ > +typedef union odp_comp_auth_algos_t { > + /** Authentication algorithms*/ > + struct { > + /** ODP_AUTH_ALG_NULL*/ > + uint32_t null : 1; > + > + /** SHA-1*/ > + uint32_t sha1 : 1; > + > + /** SHA-2 with 256 bits of Message Digest*/ > + uint32_t sha256 : 1; > + > + } bit; > + > + /** All bits of the bit field structure > + * > + * This field can be used to set/clear all flags, or bitwise > + * operations over the entire structure. > + */ > + uint32_t all_bits; > +} odp_comp_auth_algos_t; Any real benefit over odp_crypto_auth_algos_t? > +/** > + * Comp algorithms in a bit field structure > + * > + */ > +typedef union odp_comp_algos_t { > + /** Compression algorithms */ > + struct { > + /** ODP_COMP_ALG_NULL */ > + uint32_t null : 1; > + > + /** ODP_COMP_ALG_DEFLATE */ > + uint32_t deflate : 1; > + > + /** ODP_COMP_ALG_ZLIB */ > + uint32_t zlib : 1; > + > + /** ODP_COMP_ALG_LZS */ > + uint32_t lzs :1; > + } bit; > + > + /** All bits of the bit field structure > + * > + * This field can be used to set/clear all flags, or bitwise > + * operations over the entire structure. */ > + uint32_t all_bits; > +} odp_comp_algos_t; > + > +/** > + * Compression Interface Capabilities > + * > + */ > +typedef struct odp_comp_capability_t { > + /** Maximum number of sessions*/ > + uint32_t max_sessions; > + > + /** Supported compression algorithms*/ > + odp_comp_algos_t comps; > + > + /** Supported authentication algorithms*/ > + odp_comp_auth_algos_t auths; > + > + /** Support level for synchrnous operation mode (ODP_COMP_SYNC) > + * User should set odp_comp_session_param_t:mode based on > + * support level as indicated by this param. > + * true - mode supported, > + * false - mode not supported Usually this is unsupported/supported/preferred. We are waiting for Petri's proposal to unify the interface. > + */ > + odp_bool_t sync; > + > + /** Support level for asynchrnous operation mode (ODP_COMP_ASYNC) > + * User should set odp_comp_session_param_t:mode param based on > + * support level as indicated by this param. > + * true - mode supported, > + * false - mode not supported > + * > + */ > + odp_bool_t async; > +} odp_comp_capability_t; > + > +/** > + * Authentication algorithm capabilities > + * > + */ > +typedef struct odp_comp_auth_alg_capability_t { > + /** key size in bytes */ > + uint32_t key_size; > + > + /** Digest length in bytes */ > + uint32_t digest_len; Ideally this cap should go to crypto interface. > + > + /** Optional NULL-terminated string description > + * message (platform-dependent). > + */ > + void *description; > + > + /** Optional Null-terminated string > + * identifier of the algo (platform-dependent) > + */ > + void *name; Why do you need those two fields? > +} odp_comp_auth_alg_capability_t; > + > +/** > + * Compression algorithm capabilities > + * structure for each algorithm. > + * > + */ > +typedef struct odp_comp_alg_capability_t { > + /** Boolean indicating alg support dictionary load > + * > + * true: yes > + * false : no > + * > + */ > + odp_bool_t support_dict; > + > + /** Optional Maximum length of dictionary supported > + * by implementation of the algorithm. > + * > + * Invalid if support_dict == false. > + * > + * Implementation not supporting this may still allow a dictionary > + * load during odp_comp_operation() where Implementation may > + * use either of user input or maximum allowed, whichever is less. > + * In such case, implementation keep responsibility to update user > + * used dictionary length. > + * > + */ > + uint32_t dict_len; > + > + /** NULL-terminated Optional identifier of the algo (platform-dependent) > + */ > + void *name; > + > + /** NULL-terminated optional description message (platform-dependent) */ > + void *description; Again. Why do you need those names? If they are meant for UI, who will care about l10n? > +} odp_comp_alg_capability_t; > + > +/** > + * Comp API data range specifier > + * > + */ > +typedef struct odp_comp_data_range_t { > + /** Offset from beginning of input */ > + uint32_t offset; > + > + /** Length of data to operate on */ > + uint32_t length; > +} odp_comp_data_range_t; Please use odp_crypto_data_range_t instead. Maybe it would be a good idea to have generic 'odp_data_range_t' instead, which would be used by compression and crypto interfaces. > + > +/** > + * Comp API key structure > + * > + */ > +typedef struct odp_comp_auth_key_t { > + /** Key */ > + uint8_t *key; > + > + /** Key length in bytes */ > + uint32_t length; > +} odp_comp_auth_key_t; Just odp_crypto_key_t please. > + > + /** > + * Comp API session creation parameters > + * > + */ > +typedef struct odp_comp_session_param_t { > + /** Compress vs. Decompress operation */ > + odp_comp_op_t op; > + > + /** Sync vs Async > + * > + * When mode = ODP_COMP_SYNC, odp_comp_operation() behaves > + * synchronously. Operation results will be available as the call > + * returns. > + * > + * When mode = ODP_COMP_ASYNC, odp_comp_operation() behaves > + * asynchronously. Operation results will be notified via > + * ODP_COMP_COMPL_EVENT enqueued into completion queue. > + * > + * Before passing, User should ensure given > + * mode is supported by implementation via call to > + * odp_comp_capability_query(). > + * > + * Set mode to ODP_COMP_ASYNC, if > + * odp_comp_capability_t:async is set to true > + * > + * > + * Set mode to ODP_COMP_SYNC, if > + * odp_comp_capability_t:sync is set to true > + * > + */ > + odp_comp_op_mode_t mode; As said before, please switch to IPsec-like interface, where there are separate functions for SYNC and ASYNC modes. > + > + /** Compression algorithm > + * > + * Use odp_comp_capability() for supported algorithms. > + */ > + odp_comp_alg_t comp_alg; > + > + /** Compression preferred encoding mode > + * > + */ > + odp_comp_code_t comp_code; > + > + /** Compression preferred speed > + * > + */ > + odp_comp_speed_t comp_speed; > + > + /** Authentication algorithm. > + * > + * if enabled along with non-null compression algo, follows a fixed > + * ordering. it will be applied on plaintext i.e. > + * before data is compressed for compression session, and > + * after it is decompressed for decompression session. > + * > + * This may later be enhanced to allow re-ordering subject to > + * explicitly defined use-case. > + */ > + odp_comp_auth_alg_t auth_alg; > + > + /** auth parameters during session creation*/ > + odp_comp_auth_key_t auth_key; > + > + /** Async mode completion event queue > + * > + * When mode = ODP_COMP_ASYNC, User should wait on ODP_COMP_COMPL_EVENT > + * on this queue. > + * > + * By default, implementation enques completion events in-order-of > + * request submission and thus queue is considered ordered. > + * > + * Please note, behavior could be changed or enhanced > + * to queue event in-order-of their completion to enable > + * performance-oriented application to leverage hw offered parallelism. > + * However, This will be subject to application requirement and more > + * explicit defined use-case. > + * > + */ > + odp_queue_t compl_queue; > + > + /** Pool used by user for input/output data > + * > + * used by implementation to have user pool information. > + * Helps to map input/output data pointer to appropriate type > + * and other pool related operations. > + * > + */ > + odp_pool_t pool; What is the usage of this pool? Your commentary isn't easy to parse. > +} odp_comp_session_param_t; > + > +/** > + * Comp API operation parameters. > + * Called to process each data unit. > + * > + */ > +typedef struct odp_comp_op_param_t { > + /** Session handle from creation */ > + odp_comp_session_t session; > + > + /** User context */ > + void *ctx; > + > + /** Boolean indicating End of data > + * for stateless compressions (ex ipcomp), it should always be 'true' > + * > + * true : last chunk > + * false: more to follow > + * > + * for compression+authentication, digest will be available after > + * last chunk is processed completely. > + */ > + odp_bool_t last; Maybe it'd be better named 'flush' instead of 'last'? > + > + /** Input packet*/ > + odp_packet_t in_data; > + > + /** input data range w.r.t in_data*/ > + odp_comp_data_range_t in_data_range; > + > + /** Output packet. > + * Stores processed output. > + * > + * For Compression+Authentication session, > + * output buffer will store both data and digest(with digest appended at > + * end-of-data). User should pass packet of sufficiently large size > + * to store digest. > + * > + * Auto-allocation of output buffer( i.e. when out_data set to > + * ODP_PACKET_INVALID) and/or in-place operation support > + * to be considered later based on explicit defined use-case. > + * > + */ > + odp_packet_t out_data; If you do not allow auto allocation of output packet, I don't see why would you need a pool in odp_comp_session_param_t. > + > + /** output data range w.r.t out_data, where > + * > + * At input, length specifies length of available output buffer, and > + * offset marks beginning of output buffer. > + * > + * At output, length is updated to length of data written in output, and > + * offset marks start of the data. > + * > + * For Compression+Authentication session, Both data and digest are > + * written to same output buffer (with digest written at the end of > + * data), so data length = out_data_range.len-digest_size. I'd suggest to have separate data range for digest algo. It is more future proof. > + * > + */ > + odp_comp_data_range_t out_data_range; > + > + /** dictionary - Optional Pointer to dictionary as passed by user. > + * User should pass dictionary when interface is in idle state i.e. > + * no operation is in progress. > + */ > + uint8_t *dict; What is the format of the dictionary? Also the requirement of 'idle' state seems quite troublesome. Maybe it should go to odp_comp_session_param_t ? > + > + /** Length of dictionary */ > + uint32_t dict_len; > + > +} odp_comp_op_param_t; > + > +/** > + * Comp API per operation result > + * > + */ > +typedef struct odp_comp_op_result_t { > + /** User context from request */ > + void *ctx; > + > + /** Operation Return Code */ > + odp_comp_err_t err; > + > + /** pointer to output buffer. Valid when odp_comp_err_t is > + * ODP_COMP_ERR_NONE > + * > + * Contains digest for authentication ONLY operations, > + * processed output for compression/decompression operations, and > + * both data and digest for Compression+Authentication Operations. > + * > + */ > + odp_packet_t out_data; > + > + /** length of data written to output packet. > + * include both data+digest_len, for compression+authentication > + * session > + */ > + odp_comp_data_range_t data_range; > +} odp_comp_op_result_t; So, here we have 1 packet per request. Would we like to support multiple packets per request instead? -- With best wishes Dmitry