Re: [lng-odp] [PATCHv3 5/5] api: config: simplify packet configuration
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Wednesday, February 18, 2015 10:03 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv3 5/5] api: config: simplify packet configuration Remove headroom/tailroom from ODP_CONFIG_PACKET_SEG_LEN_MIN and clarify meaning of ODP_CONFIG_PACKET_SEG_LEN_MAX. Signed-off-by: Bill Fischofer bill.fischo...@linaro.org --- include/odp/api/config.h | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/include/odp/api/config.h b/include/odp/api/config.h index 3ac9e2c..5f211f3 100644 --- a/include/odp/api/config.h +++ b/include/odp/api/config.h @@ -95,25 +95,17 @@ extern C { * This defines the minimum packet segment buffer length in bytes. The user * defined segment length (seg_len in odp_pool_param_t) will be rounded up into * this value. - * - * @internal In linux-generic implementation: - * - The value MUST be a multiple of 8. - * - The value MUST be a multiple of ODP_CACHE_LINE_SIZE - * - The default value (1664) is large enough to support 1536-byte packets - * with the default headroom shown above and is a multiple of both 64 and 128, - * which are the most common cache line sizes. */ -#define ODP_CONFIG_PACKET_SEG_LEN_MIN (1664) +#define ODP_CONFIG_PACKET_SEG_LEN_MIN (1598) /** * Maximum packet segment length * * This defines the maximum packet segment buffer length in bytes. The user * defined segment length (seg_len in odp_pool_param_t) must not be larger than - * this. - * + * this. A value of 0 indicates no upper limit. */ -#define ODP_CONFIG_PACKET_SEG_LEN_MAX ODP_CONFIG_PACKET_SEG_LEN_MIN +#define ODP_CONFIG_PACKET_SEG_LEN_MAX 0 0 doesn't work here since user may want to compare, if (my_seg_len _SEG_LEN_MAX) ... else ... OR substitute it (use always max seg len) params.pkt.seg_len = _SEG_LEN_MAX; So, it's better to pick a reasonable max number, e.g. 64 kB which would already fit the largest possible UDP datagram (16 bit length) into a single segment. Patches 1-4 are OK. -Petri /** * Maximum packet buffer length -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2 00/10] add global and local termination
It's OK to do that. Also since it's implementation, you can exploit the fact that shm_free catches SHM_INVALID and returns -1 (== defined behavior). It would be cleaner/faster to save handles and use those, but not that important since termination is not performance critical. -Petri -Original Message- From: ext Robbie King (robking) [mailto:robk...@cisco.com] Sent: Wednesday, February 18, 2015 6:50 PM To: Taras Kondratiuk Cc: Mike Holmes; lng-odp@lists.linaro.org; Petri Savolainen (petri.savolai...@linaro.org) Subject: RE: [lng-odp] [PATCH v2 00/10] add global and local termination While I'm not a big fan of the lookup APIs myself, if they exist implementations should be able to use them I think. Does the nesting violate any coding style restrictions? ret = odp_shm_free(odp_shm_lookup(shm_odp_cos_tbl)); -Original Message- From: Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Wednesday, February 18, 2015 11:01 AM To: Robbie King (robking) Cc: Mike Holmes; lng-odp@lists.linaro.org; Petri Savolainen (petri.savolai...@linaro.org) Subject: Re: [lng-odp] [PATCH v2 00/10] add global and local termination On 02/18/2015 05:53 PM, Robbie King (robking) wrote: Hey Mike (and everyone else), I noticed this code is replicated throughout the patch: cos_shm = odp_shm_lookup(shm_odp_cos_tbl); if (cos_shm == ODP_SHM_INVALID) return -1; ret = odp_shm_free(cos_shm); As I was looking to make the changes we discussed (continue on versus returning -1) it seemed instead of replicating even more code it would be better to have some cleaner way of doing this. One possibility is to simply nest the calls (shm_free just returns -1 if passed SHM_INVALID). ret = odp_shm_free(odp_shm_lookup(shm_odp_cos_tbl)); Another option is to create a helper function, something like: ret = odp_shm_free_by_name(shm_odp_cos_tbl); If the helper is the way to go, then it could either be internal or published API. Any thoughts on the correct solution? 1) nested calls 2) internal API 3) published API I prefer a forth option :) Save allocated odp_shm_t handle and don't lookup it. ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv4 5/5] api: config: simplify packet configuration
Entire patch set Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Thursday, February 19, 2015 3:38 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv4 5/5] api: config: simplify packet configuration Remove headroom/tailroom from ODP_CONFIG_PACKET_SEG_LEN_MIN and clarify meaning of ODP_CONFIG_PACKET_SEG_LEN_MAX. Signed-off-by: Bill Fischofer bill.fischo...@linaro.org --- include/odp/api/config.h | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/include/odp/api/config.h b/include/odp/api/config.h index 3ac9e2c..c15d340 100644 --- a/include/odp/api/config.h +++ b/include/odp/api/config.h @@ -95,15 +95,8 @@ extern C { * This defines the minimum packet segment buffer length in bytes. The user * defined segment length (seg_len in odp_pool_param_t) will be rounded up into * this value. - * - * @internal In linux-generic implementation: - * - The value MUST be a multiple of 8. - * - The value MUST be a multiple of ODP_CACHE_LINE_SIZE - * - The default value (1664) is large enough to support 1536-byte packets - * with the default headroom shown above and is a multiple of both 64 and 128, - * which are the most common cache line sizes. */ -#define ODP_CONFIG_PACKET_SEG_LEN_MIN (1664) +#define ODP_CONFIG_PACKET_SEG_LEN_MIN (1598) /** * Maximum packet segment length @@ -111,9 +104,8 @@ extern C { * This defines the maximum packet segment buffer length in bytes. The user * defined segment length (seg_len in odp_pool_param_t) must not be larger than * this. - * */ -#define ODP_CONFIG_PACKET_SEG_LEN_MAX ODP_CONFIG_PACKET_SEG_LEN_MIN +#define ODP_CONFIG_PACKET_SEG_LEN_MAX (64*1024) /** * Maximum packet buffer length -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 1/2] api: scheduler: atomic and ordered definitions
It's going to be only this patch 1/2. There's no 2/2 (for API 1.0). -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv2 1/4] linux-generic: pools: rename odp_buffer_pool files to odp_pool
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Saturday, February 14, 2015 1:14 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv2 1/4] linux-generic: pools: rename odp_buffer_pool files to odp_pool Signed-off-by: Bill Fischofer bill.fischo...@linaro.org --- +++ b/platform/linux-generic/include/odp_pool_internal.h @@ -0,0 +1,380 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +/** + * @file + * + * ODP buffer pool - internal header + */ + +#ifndef ODP_BUFFER_POOL_INTERNAL_H_ +#define ODP_BUFFER_POOL_INTERNAL_H_ It should be now ODP_POOL_INTERNAL_H_ -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv2 3/4] api: pools: normalize odp_pool_param_t layout
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Saturday, February 14, 2015 1:14 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv2 3/4] api: pools: normalize odp_pool_param_t layout Signed-off-by: Bill Fischofer bill.fischo...@linaro.org --- include/odp/api/pool.h | 24 +--- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/include/odp/api/pool.h b/include/odp/api/pool.h index 66dc70e..b15ddd5 100644 --- a/include/odp/api/pool.h +++ b/include/odp/api/pool.h @@ -47,8 +47,10 @@ extern C { * Used to communicate pool creation options. */ typedef struct odp_pool_param_t { + int type; /** Pool type */ A minor thing. I'd keep type after the union in this struct. The union may have larger alignment requirement than int (depending on compiler) and in that case would force padding here (between int and union). Otherwise OK. -Petri union { struct { + uint32_t num; /** Number of buffers in the pool */ uint32_t size; /** Buffer size in bytes. The maximum number of bytes application will store in each @@ -58,20 +60,11 @@ typedef struct odp_pool_param_t { Use 0 for default alignment. Default will always be a multiple of 8. */ - uint32_t num; /** Number of buffers in the pool */ } buf; struct { - uint32_t seg_len; /** Minimum number of packet data - bytes that are stored in the - first segment of a packet. - The maximum value is defined by - ODP_CONFIG_PACKET_SEG_LEN_MAX. - Use 0 for default. */ - uint32_t __res1;/* Keep struct identical to buf, -until implementation is fixed */ uint32_t num; /** The number of packets that the pool must provide that are - packet lenght 'len' bytes or + packet length 'len' bytes or smaller. */ uint32_t len; /** Minimum packet length that the pool must provide 'num' @@ -80,16 +73,17 @@ typedef struct odp_pool_param_t { packets are larger than 'len'. Use 0 for default. */ + uint32_t seg_len; /** Minimum number of packet data + bytes that are stored in the + first segment of a packet. + The maximum value is defined by + ODP_CONFIG_PACKET_SEG_LEN_MAX. + Use 0 for default. */ } pkt; struct { - uint32_t __res1; /* Keep struct identical to buf, */ - uint32_t __res2; /* until pool implementation is fixed*/ uint32_t num;/** Number of timeouts in the pool */ } tmo; }; - - int type; /** Pool type */ - } odp_pool_param_t; /** Packet pool*/ -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv2] api: reflect file path in header guards
This is OK to merge. Reviewed-by: Petri Savolainen petri.savolai...@linaro.org --- a/include/odp/api/classification.h +++ b/include/odp/api/classification.h @@ -11,8 +11,8 @@ * ODP classification descriptor */ -#ifndef ODP_CLASSIFY_H_ -#define ODP_CLASSIFY_H_ +#ifndef ODP_API_CLASSIFY_H_ +#define ODP_API_CLASSIFY_H_ #define ODP_API_CLASSIFICATION_H_ That and potentially other .h file guard names (check all .h files in the repo) should be corrected also in another patch. -Petri -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Taras Kondratiuk Sent: Thursday, February 05, 2015 7:58 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv2] api: reflect file path in header guards Start header guards with ODP_API_ prefix to avoid confusion with other files with the same name. Signed-off-by: Taras Kondratiuk taras.kondrat...@linaro.org --- v2: updated missed ticketlock.h include/odp/api/align.h | 4 ++-- include/odp/api/atomic.h | 4 ++-- include/odp/api/barrier.h| 4 ++-- include/odp/api/buffer.h | 4 ++-- include/odp/api/byteorder.h | 4 ++-- include/odp/api/classification.h | 4 ++-- include/odp/api/compiler.h | 4 ++-- include/odp/api/config.h | 4 ++-- include/odp/api/cpumask.h| 4 ++-- include/odp/api/crypto.h | 4 ++-- include/odp/api/debug.h | 4 ++-- include/odp/api/event.h | 4 ++-- include/odp/api/hints.h | 4 ++-- include/odp/api/init.h | 4 ++-- include/odp/api/packet.h | 4 ++-- include/odp/api/packet_flags.h | 4 ++-- include/odp/api/packet_io.h | 4 ++-- include/odp/api/pool.h | 4 ++-- include/odp/api/queue.h | 4 ++-- include/odp/api/random.h | 4 ++-- include/odp/api/rwlock.h | 4 ++-- include/odp/api/schedule.h | 4 ++-- include/odp/api/shared_memory.h | 4 ++-- include/odp/api/spinlock.h | 4 ++-- include/odp/api/std_types.h | 4 ++-- include/odp/api/sync.h | 4 ++-- include/odp/api/system_info.h| 4 ++-- include/odp/api/thread.h | 4 ++-- include/odp/api/ticketlock.h | 4 ++-- include/odp/api/time.h | 4 ++-- include/odp/api/timer.h | 4 ++-- include/odp/api/version.h| 4 ++-- 32 files changed, 64 insertions(+), 64 deletions(-) diff --git a/include/odp/api/align.h b/include/odp/api/align.h index b97ee57..97cedc3 100644 --- a/include/odp/api/align.h +++ b/include/odp/api/align.h @@ -11,8 +11,8 @@ * ODP alignments */ -#ifndef ODP_ALIGN_H_ -#define ODP_ALIGN_H_ +#ifndef ODP_API_ALIGN_H_ +#define ODP_API_ALIGN_H_ #ifdef __cplusplus extern C { diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h index 9e759fb..ba5c354 100644 --- a/include/odp/api/atomic.h +++ b/include/odp/api/atomic.h @@ -11,8 +11,8 @@ * ODP atomic operations */ -#ifndef ODP_ATOMIC_H_ -#define ODP_ATOMIC_H_ +#ifndef ODP_API_ATOMIC_H_ +#define ODP_API_ATOMIC_H_ #ifdef __cplusplus extern C { diff --git a/include/odp/api/barrier.h b/include/odp/api/barrier.h index 2066210..35f0981 100644 --- a/include/odp/api/barrier.h +++ b/include/odp/api/barrier.h @@ -11,8 +11,8 @@ * ODP execution barriers */ -#ifndef ODP_BARRIER_H_ -#define ODP_BARRIER_H_ +#ifndef ODP_API_BARRIER_H_ +#define ODP_API_BARRIER_H_ #ifdef __cplusplus extern C { diff --git a/include/odp/api/buffer.h b/include/odp/api/buffer.h index 4bbac1e..9ad08ea 100644 --- a/include/odp/api/buffer.h +++ b/include/odp/api/buffer.h @@ -11,8 +11,8 @@ * ODP buffer descriptor */ -#ifndef ODP_BUFFER_H_ -#define ODP_BUFFER_H_ +#ifndef ODP_API_BUFFER_H_ +#define ODP_API_BUFFER_H_ #ifdef __cplusplus extern C { diff --git a/include/odp/api/byteorder.h b/include/odp/api/byteorder.h index 3a36afc..a7b3647 100644 --- a/include/odp/api/byteorder.h +++ b/include/odp/api/byteorder.h @@ -11,8 +11,8 @@ * ODP byteorder */ -#ifndef ODP_BYTEORDER_H_ -#define ODP_BYTEORDER_H_ +#ifndef ODP_API_BYTEORDER_H_ +#define ODP_API_BYTEORDER_H_ #ifdef __cplusplus extern C { diff --git a/include/odp/api/classification.h b/include/odp/api/classification.h index 5a61bd8..8758fb5 100644 --- a/include/odp/api/classification.h +++ b/include/odp/api/classification.h @@ -11,8 +11,8 @@ * ODP classification descriptor */ -#ifndef ODP_CLASSIFY_H_ -#define ODP_CLASSIFY_H_ +#ifndef ODP_API_CLASSIFY_H_ +#define ODP_API_CLASSIFY_H_ #ifdef __cplusplus extern C { diff --git a/include/odp/api/compiler.h b/include/odp/api/compiler.h index 71a4431..5a24bfb 100644 --- a/include/odp/api/compiler.h +++ b/include/odp/api/compiler.h @@ -11,8 +11,8 @@ * Compiler related */ -#ifndef ODP_COMPILER_H_ -#define ODP_COMPILER_H_ +#ifndef ODP_API_COMPILER_H_ +#define ODP_API_COMPILER_H_ #ifdef
Re: [lng-odp] [PATCH v2 1/3] api: pool: Added packet pool parameters
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Tuesday, February 03, 2015 11:05 PM To: Petri Savolainen Cc: LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH v2 1/3] api: pool: Added packet pool parameters My alternative approach that should achieve that same goals as Petri but give more freedom to implementations. You don't have to approve of it, I just want to show that given a defined and understood problem, many potential solutions exist and the first alternative might not be the best. Let's work together. I think your proposal is not substantially different what I have suggested already (including conf calls). Main difference is that 1st segment vs other segments configuration would be introduced already in v1.0. I was thinking to nail v1.0 with minimum support (keep it close to what we have already done) and extend from there (with concept of 1st/other segments). * init_seg_len: On input: user's required (desired) minimal length of initial segment (including headroom) On output: implementation's best effort to match user's request Purpose: ensure that those packet headers the application normally will process are stored in a consecutive memory area. Applications do not have to check any configuration in order to initialize a configuration which the implementation anyway has to check if it can support. Applications should check output values to see if its desired values were matched. The application decides whether a failure to match is a fatal error or the application can handle the situation anyway (e.g. with degraded performance because it has to do some workarounds in SW). This would be .first_seg_len. Application is not interested on the actual len, either implementation can support the minimum requirement or not. That's why output param is not necessary, but min/max limits are needed. Limits can be provided as macros or function calls. I'd postpone splitting .seg_len from current proposal to .first_seg_len and .other_seg_len some time after v1.0 when we continue packet API segmentation API development anyway. * seg_len: On input: user's desired length of other segments On output: implementation's best effort to match user's request Purpose: a hint from the user how to partition to pool into segments for best trade-off between memory utilization and SW processing performance. Note: I know some HW can support multiple segment sizes so I think it is useful for the API to allow for this. Targets which only support one segment size (per packet pool) could use e.g. max(int_seg_len, seg_len). Some targets may not allow user-defined segment sizes at all, the ODP implementation will just return the actual values and the application can check whether those are acceptable. This would be .other_seg_len. This can be hint vs 1st seg len is strict requirement. * init_seg_num: On input: Number of initial segments. On output: Updated with actual number of segments if a shared memory region was specified? This is also max number of packets (== seg_num in my proposal). Again I considered to postpone the split of first_seg_num/packet_num and other_seg_num after v1.0. Application may want (usually does) to specify max number of packet as hard limit, since that's the limit for maximum number of in-flight packet inside your app / SoC. The limit is needed for QoS, per packet context memory allocation, etc. It depends on application if actual number is interesting or only success/failure. * seg_num: On input: Number of other segments. On output: Updated with actual number of segments if a shared memory region was specified? I dislike the defines because they will make a future portable ABI (binary interface) definition impossible. We will need a portable ABI to support e.g. shared library implementations. So all ODP_CONFIG's should only be used internally (by the implementation in question) and not be accessible as compile time constants to applications, i.e. they should not be part of the ODP API. Are there any other instances where the application is supposed to use these constants? This a new requirement, and is probably a valid one also. Obviously, any config interface development need to be postponed after v1.0. Since v1.0 has ODP_CONFIG_XXX (config.h) in the API, it's possible to use that mechanism also for these limits. Functions could be used also, but it would not solve the config issue as have used ODP_CONFIG_XXX already for other things like buffers. Minimizing changes to current practices to reach v1.0 sooner than later... -Petri -- Ola On 3 February 2015 at 14:31, Ola Liljedahl ola.liljed...@linaro.org wrote: On 3 February 2015 at 13:59, Petri Savolainen petri.savolai...@linaro.org wrote: Completed odp_pool_param_t definition with packet pool
Re: [lng-odp] [PATCH] api: odp_schedule.h: use int to match return type
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Thursday, February 05, 2015 6:20 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH] api: odp_schedule.h: use int to match return type Use (signed) int for parameter that should match return type of function. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/schedule.h| 2 +- platform/linux-generic/odp_schedule.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/odp/api/schedule.h b/include/odp/api/schedule.h index 3019b84..226dc9b 100644 --- a/include/odp/api/schedule.h +++ b/include/odp/api/schedule.h @@ -87,7 +87,7 @@ odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait); * @return Number of events outputed (0 ... num) */ int odp_schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], -unsigned int num); +int num); /** * Pause scheduling diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux- generic/odp_schedule.c index 999c800..3427082 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -386,7 +386,7 @@ odp_event_t odp_schedule(odp_queue_t *out_queue, uint64_t wait) int odp_schedule_multi(odp_queue_t *out_queue, uint64_t wait, -odp_event_t events[], unsigned int num) +odp_event_t events[], int num) { return schedule_loop(out_queue, wait, events, num, MAX_DEQ); } -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv2] api: pool: move buffer allocation to buffer.h
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Thursday, February 05, 2015 7:37 PM To: lng-odp@lists.linaro.org Cc: Savolainen, Petri (NSN - FI/Espoo); Taras Kondratiuk Subject: [PATCHv2] api: pool: move buffer allocation to buffer.h Signed-off-by: Taras Kondratiuk taras.kondrat...@linaro.org --- include/odp/api/buffer.h | 19 +++ include/odp/api/pool.h| 20 platform/linux-generic/include/odp/pool.h | 1 + 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/odp/api/buffer.h b/include/odp/api/buffer.h index 09bddf2..4bbac1e 100644 --- a/include/odp/api/buffer.h +++ b/include/odp/api/buffer.h @@ -105,6 +105,25 @@ int odp_buffer_is_valid(odp_buffer_t buf); odp_pool_t odp_buffer_pool(odp_buffer_t buf); /** + * Buffer alloc + * + * The validity of a buffer can be cheked at any time with odp_buffer_is_valid() + * @param pool Pool handle + * + * @return Handle of allocated buffer + * @retval ODP_BUFFER_INVALID Buffer could not be allocated + */ +odp_buffer_t odp_buffer_alloc(odp_pool_t pool); + +/** + * Buffer free + * + * @param buf Buffer handle + * + */ +void odp_buffer_free(odp_buffer_t buf); + +/** * Print buffer metadata to STDOUT * * @param buf Buffer handle diff --git a/include/odp/api/pool.h b/include/odp/api/pool.h index 14d18fb..f5dda10 100644 --- a/include/odp/api/pool.h +++ b/include/odp/api/pool.h @@ -22,7 +22,6 @@ extern C { #include odp/std_types.h #include odp/plat/shared_memory_types.h -#include odp/buffer.h #include odp/event.h /** @addtogroup odp_buffer @@ -195,25 +194,6 @@ void odp_pool_print(odp_pool_t pool); uint64_t odp_pool_to_u64(odp_pool_t hdl); /** - * Buffer alloc - * - * The validity of a buffer can be cheked at any time with odp_buffer_is_valid() - * @param pool Pool handle - * - * @return Handle of allocated buffer - * @retval ODP_BUFFER_INVALID Buffer could not be allocated - */ -odp_buffer_t odp_buffer_alloc(odp_pool_t pool); - -/** - * Buffer free - * - * @param buf Buffer handle - * - */ -void odp_buffer_free(odp_buffer_t buf); - -/** * @} */ diff --git a/platform/linux-generic/include/odp/pool.h b/platform/linux- generic/include/odp/pool.h index 0591fcf..e68b11e 100644 --- a/platform/linux-generic/include/odp/pool.h +++ b/platform/linux-generic/include/odp/pool.h @@ -25,6 +25,7 @@ extern C { * @} */ +#include odp/plat/pool_types.h #include odp/api/pool.h #ifdef __cplusplus -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv6 5/9] api: odp_packet_io.h: updated return descriptions
*/ int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len); Same here: int/int vs. int/unsigned Those changes are in another patch (the last one I think). Found it. That's OK for me. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv7] api: odp_shared_memory.h: updated return descriptions
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Petri -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Thursday, February 05, 2015 3:41 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv7] api: odp_shared_memory.h: updated return descriptions Also corrected return description of odp_shm_reserve(), it returns ODP_SHM_INVALID (not NULL) on failure. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/shared_memory.h | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/include/odp/api/shared_memory.h b/include/odp/api/shared_memory.h index d4445f7..8d8df3f 100644 --- a/include/odp/api/shared_memory.h +++ b/include/odp/api/shared_memory.h @@ -71,7 +71,8 @@ typedef struct odp_shm_info_t { * @param[in] flags Shared memory parameter flags (ODP_SHM_*). * Default value is 0. * - * @return Pointer to the reserved block, or NULL + * @return Handle of the reserved block + * @retval ODP_SHM_INVALID on failure */ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags); @@ -84,9 +85,8 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, * * @param[in] shm Block handle * - * @retval 0 if the handle is already free - * @retval 0 if the handle free succeeds - * @retval -1 on failure to free the handle + * @retval 0 on success + * @retval 0 on failure */ int odp_shm_free(odp_shm_t shm); @@ -96,7 +96,7 @@ int odp_shm_free(odp_shm_t shm); * @param[in] name Name of the block * * @return A handle to the block if it is found by name - * @retval #ODP_SHM_INVALID if the block is not found + * @retval ODP_SHM_INVALID on failure */ odp_shm_t odp_shm_lookup(const char *name); @@ -106,18 +106,22 @@ odp_shm_t odp_shm_lookup(const char *name); * * @param[in] shm Block handle * - * @return Memory block address, or NULL on error + * @return Memory block address + * @retval NULL on failure */ void *odp_shm_addr(odp_shm_t shm); /** * Shared memory block info + * @note This is the only shared memory API function which accepts invalid + * shm handles (any bit value) without causing undefined behavior. * * @param[in] shm Block handle * @param[out] info Block info pointer for output * - * @return 0 on success, otherwise non-zero + * @retval 0 on success + * @retval 0 on failure */ int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] return type mismatch
Hi, This call has still int vs. unsigned int mismatch. * * @return Number of events outputed (0 ... num) */ int odp_schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], unsigned int num); int num would be according to our new policy. Negative return values are not needed (yet), but better to leave that door open. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] api: pool: move buffer allocation to buffer.h
This move is OK. Just remove also this: #include odp/buffer.h since there's not dependency anymore. -petri -Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Thursday, February 05, 2015 4:19 PM To: lng-odp@lists.linaro.org Cc: Savolainen, Petri (NSN - FI/Espoo); Taras Kondratiuk Subject: [PATCH] api: pool: move buffer allocation to buffer.h Signed-off-by: Taras Kondratiuk taras.kondrat...@linaro.org --- include/odp/api/buffer.h | 19 +++ include/odp/api/pool.h | 19 --- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/odp/api/buffer.h b/include/odp/api/buffer.h index 09bddf2..4bbac1e 100644 --- a/include/odp/api/buffer.h +++ b/include/odp/api/buffer.h @@ -105,6 +105,25 @@ int odp_buffer_is_valid(odp_buffer_t buf); odp_pool_t odp_buffer_pool(odp_buffer_t buf); /** + * Buffer alloc + * + * The validity of a buffer can be cheked at any time with odp_buffer_is_valid() + * @param pool Pool handle + * + * @return Handle of allocated buffer + * @retval ODP_BUFFER_INVALID Buffer could not be allocated + */ +odp_buffer_t odp_buffer_alloc(odp_pool_t pool); + +/** + * Buffer free + * + * @param buf Buffer handle + * + */ +void odp_buffer_free(odp_buffer_t buf); + +/** * Print buffer metadata to STDOUT * * @param buf Buffer handle diff --git a/include/odp/api/pool.h b/include/odp/api/pool.h index 14d18fb..b0b26e4 100644 --- a/include/odp/api/pool.h +++ b/include/odp/api/pool.h @@ -195,25 +195,6 @@ void odp_pool_print(odp_pool_t pool); uint64_t odp_pool_to_u64(odp_pool_t hdl); /** - * Buffer alloc - * - * The validity of a buffer can be cheked at any time with odp_buffer_is_valid() - * @param pool Pool handle - * - * @return Handle of allocated buffer - * @retval ODP_BUFFER_INVALID Buffer could not be allocated - */ -odp_buffer_t odp_buffer_alloc(odp_pool_t pool); - -/** - * Buffer free - * - * @param buf Buffer handle - * - */ -void odp_buffer_free(odp_buffer_t buf); - -/** * @} */ -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv6 3/9] api: odp_buffer.h: undefined behavior description
As discussed before, I think this function can crash on bad handles as any other buffer API call. So, let's leave out this patch. More documentation on sanity checking can be added with another patch. -Petri -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Wednesday, February 04, 2015 11:07 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv6 3/9] api: odp_buffer.h: undefined behavior description Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/buffer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/odp/api/buffer.h b/include/odp/api/buffer.h index 09bddf2..e0e25b0 100644 --- a/include/odp/api/buffer.h +++ b/include/odp/api/buffer.h @@ -88,7 +88,9 @@ uint32_t odp_buffer_size(odp_buffer_t buf); /** * Tests if buffer is valid * - * @param buf Buffer handle + * @param buf Buffer handle (possibly invalid) + * @note This is the only buffer API function which accepts invalid buffer + * handles (any bit value) without causing undefined behavior. * * @retval 1 Buffer handle represents a valid buffer. * @retval 0 Buffer handle does not represent a valid buffer. -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv6 5/9] api: odp_packet_io.h: updated return descriptions
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Wednesday, February 04, 2015 11:07 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv6 5/9] api: odp_packet_io.h: updated return descriptions Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/packet_io.h | 55 - 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h index 9d18489..36be5b1 100644 --- a/include/odp/api/packet_io.h +++ b/include/odp/api/packet_io.h @@ -57,7 +57,8 @@ extern C { * @param pool Pool from which to allocate buffers for storing packets * received over this packet IO * - * @return ODP packet IO handle or ODP_PKTIO_INVALID on error + * @return ODP packet IO handle + * @retval ODP_PKTIO_INVALID on failure * * @note dev name loop is specially pktio reserved name for *device used for testing. Usually it's loop back @@ -70,7 +71,8 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t pool); * * @param id ODP packet IO handle * - * @return 0 on success or -1 on error + * @retval 0 on success + * @retval 0 on failure */ int odp_pktio_close(odp_pktio_t id); @@ -79,7 +81,8 @@ int odp_pktio_close(odp_pktio_t id); * * @param dev Packet IO device name * - * @return ODP packet IO handle or ODP_PKTIO_INVALID + * @return ODP packet IO handle + * @retval ODP_PKTIO_INVALID on failure */ odp_pktio_t odp_pktio_lookup(const char *dev); @@ -90,7 +93,8 @@ odp_pktio_t odp_pktio_lookup(const char *dev); * @param pkt_table[] Storage for received packets (filled by function) * @param len Length of pkt_table[], i.e. max number of pkts to receive * - * @return Number of packets received or -1 on error + * @return Number of packets received + * @retval 0 on failure */ int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len); I think you missed this comment from yesterday: About unsigned len: if I remember correctly we agreed that functions that handle number of objects (not bytes or offset or chars) would have int both on input and output. int odp_pktio_recv(odp_pktio_t hdl, odp_packet_t pkt_table[], int len); int num = 10; int ret; ret = odp_pktio_recv(pktio, pkts[], num); if (ret num) ... I short: use int for both return and len. @@ -101,16 +105,18 @@ int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len); * @param pkt_table[] Array of packets to send * @param len length of pkt_table[] * - * @return Number of packets sent or -1 on error + * @return Number of packets sent + * @retval 0 on failure */ int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len); Same here: int/int vs. int/unsigned -Petri /** * Set the default input queue to be associated with a pktio handle * - * @param id ODP packet IO handle + * @param id ODP packet IO handle * @param queue default input queue set - * @return 0 on success or -1 on error + * @retval 0 on success + * @retval 0 on failure */ int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue); @@ -119,7 +125,8 @@ int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue); * * @param id ODP packet IO handle * - * @return Default input queue set or ODP_QUEUE_INVALID on error + * @return Default input queue set + * @retval ODP_QUEUE_INVALID on failure */ odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id); @@ -128,7 +135,8 @@ odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id); * * @param id ODP packet IO handle * - * @return 0 on success or -1 on error + * @retval 0 on success + * @retval 0 on failure */ int odp_pktio_inq_remdef(odp_pktio_t id); @@ -137,7 +145,8 @@ int odp_pktio_inq_remdef(odp_pktio_t id); * * @param id ODP packet IO handle * - * @return Default out queue or ODP_QUEUE_INVALID on error + * @return Default out queue + * @retval ODP_QUEUE_INVALID on failure */ odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id); @@ -146,8 +155,8 @@ odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id); * * @param[in] id ODP packet IO handle. * - * @retval MTU value 0 on success. - * @retval -1 on any error or not existance pktio id. + * @return MTU value on success + * @retval 0 on failure */ int odp_pktio_mtu(odp_pktio_t id); @@ -157,8 +166,8 @@ int odp_pktio_mtu(odp_pktio_t id); * @param[in] id ODP packet IO handle. * @param[in] enable 1 to enable, 0 to disable. * - * @retval 0 on success. - * @retval non-zero on any error. + * @retval 0 on success + * @retval 0 on failure */ int
Re: [lng-odp] [PATCHv6 6/9] api: odp_shared_memory.h: updated return descriptions
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Wednesday, February 04, 2015 11:07 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv6 6/9] api: odp_shared_memory.h: updated return descriptions Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/shared_memory.h | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/include/odp/api/shared_memory.h b/include/odp/api/shared_memory.h index d4445f7..78e11a5 100644 --- a/include/odp/api/shared_memory.h +++ b/include/odp/api/shared_memory.h @@ -71,7 +71,8 @@ typedef struct odp_shm_info_t { * @param[in] flags Shared memory parameter flags (ODP_SHM_*). * Default value is 0. * - * @return Pointer to the reserved block, or NULL + * @return Handle of the reserved block + * @retval NULL on failure */ There's actually bug in the original text. It should be: @retval ODP_SHM_INVALID on failure Maybe it's worth correcting it in this series, instead of correcting it on top of it. -Petri odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags); @@ -84,9 +85,8 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, * * @param[in] shm Block handle * - * @retval 0 if the handle is already free - * @retval 0 if the handle free succeeds - * @retval -1 on failure to free the handle + * @retval 0 on success + * @retval 0 on failure to free the handle */ int odp_shm_free(odp_shm_t shm); @@ -96,7 +96,7 @@ int odp_shm_free(odp_shm_t shm); * @param[in] name Name of the block * * @return A handle to the block if it is found by name - * @retval #ODP_SHM_INVALID if the block is not found + * @retval ODP_SHM_INVALID on failure */ odp_shm_t odp_shm_lookup(const char *name); @@ -106,18 +106,22 @@ odp_shm_t odp_shm_lookup(const char *name); * * @param[in] shm Block handle * - * @return Memory block address, or NULL on error + * @return Memory block address + * @retval NULL on failure */ void *odp_shm_addr(odp_shm_t shm); /** * Shared memory block info + * @note This is the only shared memory API function which accepts invalid + * shm handles (any bit value) without causing undefined behavior. * * @param[in] shm Block handle * @param[out] info Block info pointer for output * - * @return 0 on success, otherwise non-zero + * @retval 0 on success + * @retval 0 on failure */ int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv5 05/18] api: odp_buffer.h: undefined behavior description
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, February 03, 2015 6:48 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5 05/18] api: odp_buffer.h: undefined behavior description Documented API calls which are guaranteed to handle invalid/stale handles. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/buffer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/odp/api/buffer.h b/include/odp/api/buffer.h index 12b2f5a..1eb2e5a 100644 --- a/include/odp/api/buffer.h +++ b/include/odp/api/buffer.h @@ -88,7 +88,9 @@ uint32_t odp_buffer_size(odp_buffer_t buf); /** * Tests if buffer is valid * - * @param buf Buffer handle + * @param buf Buffer handle (possibly invalid) + * @note This is the only buffer API function which accepts invalid buffer + * handles (any bit value) without causing undefined behavior. * * @retval 1 Buffer handle represents a valid buffer. * @retval 0 Buffer handle does not represent a valid buffer. -- Originally, this and odp_packet_is_valid() were defined to enable full sanity check over the object. During debugging user could insert these on the way and (hopefully) catch the point where e.g. packet metadata (e.g. segment linking) was corrupted. So, I think this function could still crash on bad handles. Is there a use case that application would just want to check the handle validity (without crashing), but not the object sanity? -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Savolainen, Petri (NSN - FI/Espoo) Sent: Wednesday, February 04, 2015 10:31 AM To: ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error diff --git a/include/odp/api/cpumask.h b/include/odp/api/cpumask.h index 7482899..65969c3 100644 --- a/include/odp/api/cpumask.h +++ b/include/odp/api/cpumask.h @@ -18,12 +18,20 @@ extern C { #endif +#include sys/types.h +#include odp/config.h + /** @addtogroup odp_scheduler * CPU mask operations. * @{ */ - /** +/** + * @def ODP_CPUMASK_BUFSIZE + * Minimum size of output buffer for odp_cpumask_to_str() + */ ODP_CPUMASK_STRLEN is better. Better to use term string when it's a character string. This one is missing from v5. Better name it STRLEN when it used for _to_str() and _from_str() function calls. char mask_str[ODP_CPUMASK_STRLEN]; memset(mask_str, 0, sizeof(mask_str)); odp_cpumask_to_str(mask, mask_str, sizeof(mask_str)); odp_cpumask_from_str(mask, mask_str); -Petri Or ODP_CPUMASK_STRLEN_MAX or ODP_CPUMASK_STR_MAX_CHARS ... The point is that, it's defining the max number of chars (not bytes) needed for the string output - and it cannot be mixed with the odp_cpumask_t (buffer) size. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error
diff --git a/include/odp/api/cpumask.h b/include/odp/api/cpumask.h index 7482899..65969c3 100644 --- a/include/odp/api/cpumask.h +++ b/include/odp/api/cpumask.h @@ -18,12 +18,20 @@ extern C { #endif +#include sys/types.h +#include odp/config.h + /** @addtogroup odp_scheduler * CPU mask operations. * @{ */ - /** +/** + * @def ODP_CPUMASK_BUFSIZE + * Minimum size of output buffer for odp_cpumask_to_str() + */ ODP_CPUMASK_STRLEN is better. Better to use term string when it's a character string. This one is missing from v5. Better name it STRLEN when it used for _to_str() and _from_str() function calls. char mask_str[ODP_CPUMASK_STRLEN]; memset(mask_str, 0, sizeof(mask_str)); odp_cpumask_to_str(mask, mask_str, sizeof(mask_str)); odp_cpumask_from_str(mask, mask_str); -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv5 02/18] api: odp_pktio.h: odp_pktio_mac_addr() return chars written or error
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, February 03, 2015 6:48 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5 02/18] api: odp_pktio.h: odp_pktio_mac_addr() return chars written or error Added define ODP_PKTIO_MACADDRSIZE which specifies the recommended output buffer size for odp_pktio_mac_addr(). odp_pktio_mac_addr() takes output buffer size as input and returns number of chars written (on success), 0 on failure. Updated the implementation. Updated all usages in example and test programs. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/packet_io.h | 20 +-- - .../linux-generic/include/odp/plat/packet_io_types.h | 2 ++ platform/linux-generic/odp_packet_io.c | 11 ++- test/validation/odp_pktio.c | 8 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h index da7bc3f..0c8af0c 100644 --- a/include/odp/api/packet_io.h +++ b/include/odp/api/packet_io.h @@ -18,6 +18,7 @@ extern C { #endif +#include sys/types.h /** @defgroup odp_packet_io ODP PACKET IO * Operations on a packet. @@ -39,6 +40,11 @@ extern C { * odp_pktio_t value to indicate any port */ +/* + * @def ODP_PKTIO_MACADDRSIZE + * Minimum size of output buffer for odp_pktio_mac_addr() Should this be defined as ODP_PKTIO_MACADDRSIZE_MAX or similar. If the interface support two sizes this is the larger, although the configured and currently used size would be the smaller. I want to avoid applications mixing this into protocol definitions like this struct ether_hdr { uint8_t dst_mac[ODP_PKTIO_MACADDRSIZE]; uint8_t src_mac[ODP_PKTIO_MACADDRSIZE]; ... }; + */ + /** * Open an ODP packet IO instance * @@ -167,16 +173,16 @@ int odp_pktio_promisc_mode_set(odp_pktio_t id, odp_bool_t enable); int odp_pktio_promisc_mode(odp_pktio_t id); /** - * Get the default MAC address of a packet IO interface. + * Get the native MAC address of a packet IO interface. Why this is now defined as native. Does it mean the address burned into the device. What if SW has overwritten that? Is it still native? Default is referring to the default address, whatever that maybe. * - * @paramidODP packet IO handle. - * @param[out] mac_addr Storage for MAC address of the packet IO interface. - * @paramaddr_size Storage size for the address + * @paramhdl ODP packet IO handle This parameter renaming is not needed. All other packet_io.h API calls are using id here. Parameter naming should be constant throughout the API. Do not rename it in this patch. I agree that id is not the best name for that parameter, but that's how it is in this API right now. We need another patch for renaming that over all the API calls. Also hdl is not a good parameter name for an object. The name should link to the object type, like pktio (for odp_pktio_t type) in this case. Parameter list shows up in Doxygen function documentation without types. -Petri + * @param[out] mac_addr Output buffer (use ODP_PKTIO_MACADDRSIZE) + * @param size Size of output buffer * - * @retval Number of bytes written on success, 0 on failure. + * @return Number of bytes written to buffer + * @retval 0 on failure */ -size_t odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, - size_t addr_size); +ssize_t odp_pktio_mac_addr(odp_pktio_t hdl, void *mac_addr, ssize_t size); /** * Setup per-port default class-of-service. diff --git a/platform/linux-generic/include/odp/plat/packet_io_types.h b/platform/linux-generic/include/odp/plat/packet_io_types.h index a6bbacf..61dca13 100644 --- a/platform/linux-generic/include/odp/plat/packet_io_types.h +++ b/platform/linux-generic/include/odp/plat/packet_io_types.h @@ -23,6 +23,8 @@ extern C { * @{ */ +#define ODP_PKTIO_MACADDRSIZE 16 + typedef uint32_t odp_pktio_t; #define ODP_PKTIO_INVALID 0 diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux- generic/odp_packet_io.c index bdb690e..f156dd3 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -798,18 +798,19 @@ int odp_pktio_promisc_mode(odp_pktio_t id) } -size_t odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, -size_t addr_size) +ssize_t odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, ssize_t addr_size) { pktio_entry_t *entry; - if (addr_size ETH_ALEN) - return 0; + if (addr_size ETH_ALEN) { + /* Output buffer too small */ + return -1; + }
Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, February 04, 2015 11:20 AM To: Savolainen, Petri (NSN - FI/Espoo) Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error On 4 February 2015 at 09:38, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Savolainen, Petri (NSN - FI/Espoo) Sent: Wednesday, February 04, 2015 10:31 AM To: ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error diff --git a/include/odp/api/cpumask.h b/include/odp/api/cpumask.h index 7482899..65969c3 100644 --- a/include/odp/api/cpumask.h +++ b/include/odp/api/cpumask.h @@ -18,12 +18,20 @@ extern C { #endif +#include sys/types.h +#include odp/config.h + /** @addtogroup odp_scheduler * CPU mask operations. * @{ */ - /** +/** + * @def ODP_CPUMASK_BUFSIZE + * Minimum size of output buffer for odp_cpumask_to_str() + */ ODP_CPUMASK_STRLEN is better. Better to use term string when it's a character string. But is it not a character string. The user specifies a buffer and a buffer size. The function writes a string into that buffer (if it fits into the buffer). The buffer then *contains* a string (which will be shorter that the buffer size value specified, e.g. because trailing CPU bits may not be set and also the string length does not include the terminating null char). But a string and a buffer are not the same thing. This one is missing from v5. Better name it STRLEN when it used for _to_str() and _from_str() function calls. I think this is a poor choice of name. The length of a string is the number of characters in the string (excluding the terminating null char). But we need to pass the buffer size. char mask_str[ODP_CPUMASK_STRLEN]; memset(mask_str, 0, sizeof(mask_str)); Why is the memset() here? It is not needed. odp_cpumask_to_str(mask, mask_str, sizeof(mask_str)); odp_cpumask_from_str(mask, mask_str); Yes this is how it is done, before my patch and after my patch. -Petri Or ODP_CPUMASK_STRLEN_MAX or ODP_CPUMASK_STR_MAX_CHARS ... The point is that, it's defining the max number of chars (not bytes) needed for the string output - and it cannot be mixed with the odp_cpumask_t (buffer) size. odp_cpumask_t has a separate well-defined type (no char bufs or void pointers used when you are passing an odp_cpumask_t value), I see no risk for mixing it with ODP_CPUMASK_BUFSIZE. If you reserve ODP_CPUMASK_BUFSIZE for the string API. What if we add odp_cpumask_to_u64(), odp_cpumask_to_u8(),odp_cpumask_to_buf(), etc API calls later on? It's better to reserve BUF for those buffers and use STR for strings (no matter if sting initialized or not before the call, output is still a string). -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv2] api: fix odp_version_api_str()
It's API function. It's important that user can log the used API version. -Petri -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Maxim Uvarov Sent: Wednesday, February 04, 2015 10:46 AM To: Anders Roxell; Mike Holmes Cc: lng-odp Subject: Re: [lng-odp] [PATCHv2] api: fix odp_version_api_str() odp_version_api_str() is API function or not? If it's api it has to be in api header. If it's implementation only helper it hat to be under linux- generic. Maxim. On 02/04/2015 01:48 AM, Anders Roxell wrote: On 2015-02-03 11:28, Mike Holmes wrote: On 3 February 2015 at 11:12, Maxim Uvarov maxim.uva...@linaro.org wrote: odp_version_api_str() has to be in API header while odp_version_impl_str() should be in linux-generic. That change fixes: https://bugs.linaro.org/show_bug.cgi?id=1194 Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org Reviewed-by: Mike Holmes mike.hol...@linaro.org Clears the new test case patch validation: add version string check which should be added as insurance against this bug in the future before closing the bug I think we can drop static inline to the version string function, because checking for a version string is not time critical right? If we assume that its not time critical the diff below + Mikes validation version string patch got it to pass and we hide more stuff from the public doxygen clean API include/odp/api/*.h files. Cheers, Anders $ git df diff --git a/platform/linux-generic/include/odp/version.h b/platform/linux-generic/include/odp/version.h index f29320a..2c557cc 100644 --- a/platform/linux-generic/include/odp/version.h +++ b/platform/linux-generic/include/odp/version.h @@ -23,11 +23,6 @@ extern C { * @{ */ -static inline const char *odp_version_api_str(void) -{ - return ODP_VERSION_API_STR; -} - /** * @} */ diff --git a/platform/linux-generic/odp_impl.c b/platform/linux- generic/odp_impl.c index ca3224d..23ab12d 100644 --- a/platform/linux-generic/odp_impl.c +++ b/platform/linux-generic/odp_impl.c @@ -28,6 +28,11 @@ const char *odp_version_impl_str(void) return ODP_VERSION_IMPL_STR; } +const char *odp_version_api_str(void) +{ + return ODP_VERSION_API_STR; +} + #ifdef __cplusplus } #endif ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, February 04, 2015 12:32 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error On 4 February 2015 at 11:13, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, February 04, 2015 11:50 AM To: Savolainen, Petri (NSN - FI/Espoo) Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error On 4 February 2015 at 10:27, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, February 04, 2015 11:20 AM To: Savolainen, Petri (NSN - FI/Espoo) Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error On 4 February 2015 at 09:38, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Savolainen, Petri (NSN - FI/Espoo) Sent: Wednesday, February 04, 2015 10:31 AM To: ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error diff --git a/include/odp/api/cpumask.h b/include/odp/api/cpumask.h index 7482899..65969c3 100644 --- a/include/odp/api/cpumask.h +++ b/include/odp/api/cpumask.h @@ -18,12 +18,20 @@ extern C { #endif +#include sys/types.h +#include odp/config.h + /** @addtogroup odp_scheduler * CPU mask operations. * @{ */ - /** +/** + * @def ODP_CPUMASK_BUFSIZE + * Minimum size of output buffer for odp_cpumask_to_str() + */ ODP_CPUMASK_STRLEN is better. Better to use term string when it's a character string. But is it not a character string. The user specifies a buffer and a buffer size. The function writes a string into that buffer (if it fits into the buffer). The buffer then *contains* a string (which will be shorter that the buffer size value specified, e.g. because trailing CPU bits may not be set and also the string length does not include the terminating null char). But a string and a buffer are not the same thing. This one is missing from v5. Better name it STRLEN when it used for _to_str() and _from_str() function calls. I think this is a poor choice of name. The length of a string is the number of characters in the string (excluding the terminating null char). But we need to pass the buffer size. char mask_str[ODP_CPUMASK_STRLEN]; memset(mask_str, 0, sizeof(mask_str)); Why is the memset() here? It is not needed. odp_cpumask_to_str(mask, mask_str, sizeof(mask_str)); odp_cpumask_from_str(mask, mask_str); Yes this is how it is done, before my patch and after my patch. -Petri Or ODP_CPUMASK_STRLEN_MAX or ODP_CPUMASK_STR_MAX_CHARS ... The point is that, it's defining the max number of chars (not bytes) needed for the string output - and it cannot be mixed with the odp_cpumask_t (buffer) size. odp_cpumask_t has a separate well-defined type (no char bufs or void pointers used when you are passing an odp_cpumask_t value), I see no risk for mixing it with ODP_CPUMASK_BUFSIZE. If you reserve ODP_CPUMASK_BUFSIZE for the string API. What if we add odp_cpumask_to_u64(), odp_cpumask_to_u8(),odp_cpumask_to_buf(), etc API calls later on? It's better to reserve BUF for those buffers and use STR for strings (no matter if sting initialized or not before the call, output is still a string). Purely hypothetical. One can invent any number of counter arguments, that does not make them realistic or meaningful. What if we add other odp_cpumask string calls that need some (other) type of buffer to hold their strings? But I do want to make the name as easy as possible to understand and try to see your criticism in a constructive light. Perhaps ODP_CPUMASK_STR_BUFSIZE? Buffer size for cpumask strings. The buffer size is still different from the string length just as a buffer is not a string. And hypothetical seems to be favorite counter-counter argument... Because you are the expert at finding hypothetical counter arguments as soon as anyone else has a different opinion. This happens like ten times every time we have a call. We
Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, February 04, 2015 2:03 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error On 4 February 2015 at 09:38, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Savolainen, Petri (NSN - FI/Espoo) Sent: Wednesday, February 04, 2015 10:31 AM To: ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 01/18] api: odp_cpumask.h: odp_cpumask_to_str() return chars written or error diff --git a/include/odp/api/cpumask.h b/include/odp/api/cpumask.h index 7482899..65969c3 100644 --- a/include/odp/api/cpumask.h +++ b/include/odp/api/cpumask.h @@ -18,12 +18,20 @@ extern C { #endif +#include sys/types.h +#include odp/config.h + /** @addtogroup odp_scheduler * CPU mask operations. * @{ */ - /** +/** + * @def ODP_CPUMASK_BUFSIZE + * Minimum size of output buffer for odp_cpumask_to_str() + */ ODP_CPUMASK_STRLEN is better. Better to use term string when it's a character string. This one is missing from v5. Better name it STRLEN when it used for _to_str() and _from_str() function calls. char mask_str[ODP_CPUMASK_STRLEN]; memset(mask_str, 0, sizeof(mask_str)); odp_cpumask_to_str(mask, mask_str, sizeof(mask_str)); odp_cpumask_from_str(mask, mask_str); -Petri Or ODP_CPUMASK_STRLEN_MAX or ODP_CPUMASK_STR_MAX_CHARS ... The point is that, it's defining the max number of chars (not bytes) needed for the string output In C, byte means storage unit. A char is defined to take one storage unit (sizeof(char)==1). Yeah, I know. But in common language byte refers to 8 bits. Normally it is like that and lot's of SW would break if it's not. We have both used chips with 16 bit chars in the past. My point is that str highlights to the user that it's a character string, and not a byte (== 8-bit) buffer. int8_t buf[BUF_SIZE]; // wrong, although it compiles due to typedef char int8_t vs char str[STR_SIZE]; -Petri See e.g. C - A Reference Manual; Harbison, Steele Jr. (chapter 6.1.1 in the 4th edition) or http://c0x.coding-guidelines.com/6.5.3.4.html So for an array of char (the odp_cpumask_to_str() uses char * to reference this array), there is no practical nor semantic difference between number of chars or number of bytes. We could have added some more words to the description (e.g. size of output buffer in chars) but I think this would be redundant and potentially confusing (as the size in chars is the default and the output buffer is specified as an array of char). In a case where the output buffer is of some non-char type, it makes sense to specify what type is used for the size if this is not otherwise obvious from the description. - and it cannot be mixed with the odp_cpumask_t (buffer) size. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv5 16/18] api: odp_timer.h: updated return descriptions
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, February 03, 2015 6:48 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5 16/18] api: odp_timer.h: updated return descriptions Updated doxygen descriptions, particularly the @return/@retval descriptions. Documented API calls which are guaranteed to handle invalid/stale handles. Removed unnecessary warnings of undefined behavior. No change of implementation necessary. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/timer.h | 52 - 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/include/odp/api/timer.h b/include/odp/api/timer.h index 64ccc4b..1b813da 100644 --- a/include/odp/api/timer.h +++ b/include/odp/api/timer.h @@ -112,8 +112,8 @@ typedef struct { * @param name Name of the timer pool. The string will be copied. * @param params Timer pool parameters. The content will be copied. * - * @return Timer pool handle if successful, otherwise ODP_TIMER_POOL_INVALID - * and errno set + * @return Timer pool handle on success + * @retval ODP_TIMER_POOL_INVALID on failure and errno set */ odp_timer_pool_t odp_timer_pool_create(const char *name, @@ -135,14 +135,14 @@ void odp_timer_pool_start(void); * Destroy a timer pool, freeing all resources. * All timers must have been freed. * - * @param tpid Timer pool identifier + * @param tpid Timer pool handle */ void odp_timer_pool_destroy(odp_timer_pool_t tpid); /** * Convert timer ticks to nanoseconds * - * @param tpid Timer pool identifier + * @param tpid Timer pool handle * @param ticks Timer ticks * * @return Nanoseconds @@ -152,7 +152,7 @@ uint64_t odp_timer_tick_to_ns(odp_timer_pool_t tpid, uint64_t ticks); /** * Convert nanoseconds to timer ticks * - * @param tpid Timer pool identifier + * @param tpid Timer pool handle * @param nsNanoseconds * * @return Timer ticks @@ -162,7 +162,7 @@ uint64_t odp_timer_ns_to_tick(odp_timer_pool_t tpid, uint64_t ns); /** * Current tick value * - * @param tpid Timer pool identifier + * @param tpid Timer pool handle * * @return Current time in timer ticks */ @@ -181,12 +181,14 @@ typedef struct { /** * Query timer pool configuration and current state + * @note This is the only timer API function which accepts invalid handles + * (any bit value) without causing undefined behavior. Why? How this is different? I think all calls accessing the timer pool (a shared resource) have the same behavior. Those can crash on bad tpid handles, and may catch stale handles with return code or crash. - Petri * - * @param tpid Timer pool identifier + * @param tpid Timer pool handle * @param[out] info Pointer to information buffer * - * @retval 0 Success - * @retval -1 Failure. Info could not be retrieved. + * @retval 0 on success + * @retval 0 on failure. Info could not be retrieved. */ int odp_timer_pool_info(odp_timer_pool_t tpid, odp_timer_pool_info_t *info); @@ -198,12 +200,12 @@ int odp_timer_pool_info(odp_timer_pool_t tpid, * the timer pool. The user_ptr is copied to timeouts and can be retrieved * using the odp_timeout_user_ptr() call. * - * @param tpid Timer pool identifier + * @param tpid Timer pool handle * @param queueDestination queue for timeout notifications * @param user_ptr User defined pointer or NULL to be copied to timeouts * - * @return Timer handle if successful, otherwise ODP_TIMER_INVALID and - * errno set. + * @return Timer handle on success + * @retval ODP_TIMER_INVALID on failure and errno set. */ odp_timer_t odp_timer_alloc(odp_timer_pool_t tpid, odp_queue_t queue, @@ -218,7 +220,8 @@ odp_timer_t odp_timer_alloc(odp_timer_pool_t tpid, * responsibility of the application to handle this timeout when it is received. * * @param tim Timer handle - * @return Event handle of timeout event or ODP_EVENT_INVALID + * @return Event handle of timeout event + * @retval ODP_EVENT_INVALID on failure */ odp_event_t odp_timer_free(odp_timer_t tim); @@ -228,9 +231,6 @@ odp_event_t odp_timer_free(odp_timer_t tim); * Set (arm) the timer to expire at specific time. The timeout * event will be enqueued when the timer expires. * - * Note: any invalid parameters will be treated as programming errors and will - * cause the application to abort. - * * @param tim Timer * @param abs_tck Expiration time in absolute timer ticks * @param[in,out] tmo_ev Reference to an event variable that points to @@ -255,9 +255,6 @@ int odp_timer_set_abs(odp_timer_t tim, * *
Re: [lng-odp] [PATCHv5 11/18] api: odp_packet_io.h: updated return descriptions
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, February 03, 2015 6:48 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5 11/18] api: odp_packet_io.h: updated return descriptions Updated doxygen descriptions, particularly the @return/@retval descriptions. No change of implementation necessary. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/packet_io.h | 89 ++-- - Updated doxygen descriptions, particularly the @return/@retval descriptions. No change of implementation necessary. 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h index 0c8af0c..3fa4063 100644 --- a/include/odp/api/packet_io.h +++ b/include/odp/api/packet_io.h @@ -56,7 +56,8 @@ extern C { * @param pool Pool from which to allocate buffers for storing packets * received over this packet IO * - * @return ODP packet IO handle or ODP_PKTIO_INVALID on error + * @return ODP packet IO handle + * @retval ODP_PKTIO_INVALID on failure * * @note dev name loop is specially pktio reserved name for *device used for testing. Usually it's loop back @@ -67,110 +68,118 @@ odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t pool); /** * Close an ODP packet IO instance * - * @param id ODP packet IO handle + * @param hdl ODP packet IO handle * - * @return 0 on success or -1 on error + * @retval 0 on success + * @retval 0 on failure */ -int odp_pktio_close(odp_pktio_t id); +int odp_pktio_close(odp_pktio_t hdl); /** * Return a packet IO handle for an already open device * * @param dev Packet IO device name * - * @return ODP packet IO handle or ODP_PKTIO_INVALID + * @return ODP packet IO handle + * @retval ODP_PKTIO_INVALID on failure */ odp_pktio_t odp_pktio_lookup(const char *dev); /** * Receive packets * - * @param id ODP packet IO handle + * @param hdl ODP packet IO handle * @param pkt_table[] Storage for received packets (filled by function) * @param len Length of pkt_table[], i.e. max number of pkts to receive * - * @return Number of packets received or -1 on error + * @return Number of packets received + * @retval 0 on failure */ -int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len); +int odp_pktio_recv(odp_pktio_t hdl, odp_packet_t pkt_table[], unsigned len); As agreed, it's better to rename id to pktio. And do that (preferably) on a separate patch. That can rename those couple of pktio_in in the bottom of the file. About unsigned len: if I remember correctly we agreed that functions that handle number of objects (not bytes or offset or chars) would have int both on input and output. int odp_pktio_recv(odp_pktio_t hdl, odp_packet_t pkt_table[], int len); int num = 10; int ret; ret = odp_pktio_recv(pktio, pkts[], num); if (ret num) ... /** * Send packets * - * @param id ODP packet IO handle + * @param hdl ODP packet IO handle * @param pkt_table[] Array of packets to send * @param len length of pkt_table[] * - * @return Number of packets sent or -1 on error + * @return Number of packets sent + * @retval 0 on failure */ -int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len); +int odp_pktio_send(odp_pktio_t hdl, odp_packet_t pkt_table[], unsigned len); Same here: int vs. unsigned ? -Petri /** * Set the default input queue to be associated with a pktio handle * - * @param id ODP packet IO handle + * @param hdlODP packet IO handle * @param queue default input queue set - * @return 0 on success or -1 on error + * @retval 0 on success + * @retval 0 on failure */ -int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue); +int odp_pktio_inq_setdef(odp_pktio_t hdl, odp_queue_t queue); /** * Get default input queue associated with a pktio handle * - * @param id ODP packet IO handle + * @param hdl ODP packet IO handle * - * @return Default input queue set or ODP_QUEUE_INVALID on error + * @return Default input queue set + * @retval ODP_QUEUE_INVALID on failure */ -odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id); +odp_queue_t odp_pktio_inq_getdef(odp_pktio_t hdl); /** * Remove default input queue (if set) * - * @param id ODP packet IO handle + * @param hdl ODP packet IO handle * - * @return 0 on success or -1 on error + * @retval 0 on success + * @retval 0 on failure */ -int odp_pktio_inq_remdef(odp_pktio_t id); +int odp_pktio_inq_remdef(odp_pktio_t hdl); /** * Query default output queue * - * @param id ODP packet IO
Re: [lng-odp] [PATCHv5 14/18] api: odp_shared_memory.h: updated return descriptions
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, February 03, 2015 6:48 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5 14/18] api: odp_shared_memory.h: updated return descriptions Updated doxygen descriptions, particularly the @return/@retval descriptions. No change of implementation necessary. Documented API calls which are guaranteed to handle invalid/stale handles. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/shared_memory.h | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/odp/api/shared_memory.h b/include/odp/api/shared_memory.h index 5b27b6b..18764ce 100644 --- a/include/odp/api/shared_memory.h +++ b/include/odp/api/shared_memory.h @@ -71,7 +71,8 @@ typedef struct odp_shm_info_t { * @param[in] flags Shared memory parameter flags (ODP_SHM_*). * Default value is 0. * - * @return Pointer to the reserved block, or NULL + * @return Handle of the reserved block + * @retval NULL on failure */ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags); @@ -84,9 +85,8 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, * * @param[in] shm Block handle * - * @retval 0 if the handle is already free - * @retval 0 if the handle free succeeds - * @retval -1 on failure to free the handle + * @retval 0 on success + * @retval 0 on failure to free the handle */ int odp_shm_free(odp_shm_t shm); @@ -96,7 +96,7 @@ int odp_shm_free(odp_shm_t shm); * @param[in] name Name of the block * * @return A handle to the block if it is found by name - * @retval #ODP_SHM_INVALID if the block is not found + * @retval ODP_SHM_INVALID on failure */ odp_shm_t odp_shm_lookup(const char *name); @@ -106,18 +106,21 @@ odp_shm_t odp_shm_lookup(const char *name); * * @param[in] shm Block handle * - * @return Memory block address, or NULL on error + * @return Memory block address Missing the failure case. @retval NULL on failure -Petri */ void *odp_shm_addr(odp_shm_t shm); /** * Shared memory block info + * @note This is the only shared memory API function which accepts invalid + * shm handles (any bit value) without causing undefined behavior. * * @param[in] shm Block handle * @param[out] info Block info pointer for output * - * @return 0 on success, otherwise non-zero + * @retval 0 on success + * @retval 0 on failure */ int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv5 08/18] api: odp_init.h: updated return descriptions
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, February 03, 2015 6:48 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5 08/18] api: odp_init.h: updated return descriptions Updated doxygen descriptions, particularly the @return/@retval descriptions. No change of implementation necessary. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/init.h | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/odp/api/init.h b/include/odp/api/init.h index c73b321..c14769f 100644 --- a/include/odp/api/init.h +++ b/include/odp/api/init.h @@ -66,8 +66,8 @@ typedef enum odp_log_level { * @param[in] level Log level * @param[in] fmt printf-style message format * - * @return The number of characters logged if succeeded. Otherwise returns - * a negative number. + * @return The number of characters logged on success + * @retval 0 on failure */ int odp_override_log(odp_log_level_e level, const char *fmt, ...); @@ -108,8 +108,8 @@ typedef struct odp_platform_init_t { * @param[in] platform_params Those parameters that are passed without * interpretation by the ODP API to the implementation. * - * @retval 0 if successful - * @retval -1 on failure + * @retval 0 on success + * @retval 0 on failure */ int odp_init_global(odp_init_t *params, odp_platform_init_t *platform_params); @@ -133,8 +133,8 @@ int odp_init_global(odp_init_t *params, odp_platform_init_t *platform_params); * @sa odp_init_global() * @sa odp_term_local() which must have been called prior to this. * - * @retval 0 if successful - * @retval -1 on failure + * @retval 0 on success + * @retval 0 on failure */ int odp_term_global(void); @@ -147,8 +147,8 @@ int odp_term_global(void); * @sa odp_term_local() * @sa odp_init_global() which must have been called prior to this. * - * @retval 0 if successful - * @retval -1 on failure + * @retval 0 on success + * @retval 0 on failure */ int odp_init_local(void); @@ -170,8 +170,8 @@ int odp_init_local(void); * @warning The unwinding of HW resources to allow them to be re used without reseting * the device is a complex task that the application is expected to coordinate. * - * @retval 1 if successful and more ODP thread exists - * @retval 0 if successful and it was the last ODP thread + * @retval 1 on success and more ODP threads exist + * @retval 0 on success and no more ODP threads exist The existing documentation is better. The _last_ thread calls odp_term_global(). -Petri * @retval -1 on failure */ int odp_term_local(void); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv5 05/18] api: odp_buffer.h: undefined behavior description
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, February 04, 2015 12:01 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv5 05/18] api: odp_buffer.h: undefined behavior description On 4 February 2015 at 10:51, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, February 03, 2015 6:48 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5 05/18] api: odp_buffer.h: undefined behavior description Documented API calls which are guaranteed to handle invalid/stale handles. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/buffer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/odp/api/buffer.h b/include/odp/api/buffer.h index 12b2f5a..1eb2e5a 100644 --- a/include/odp/api/buffer.h +++ b/include/odp/api/buffer.h @@ -88,7 +88,9 @@ uint32_t odp_buffer_size(odp_buffer_t buf); /** * Tests if buffer is valid * - * @param buf Buffer handle + * @param buf Buffer handle (possibly invalid) + * @note This is the only buffer API function which accepts invalid buffer + * handles (any bit value) without causing undefined behavior. * * @retval 1 Buffer handle represents a valid buffer. * @retval 0 Buffer handle does not represent a valid buffer. -- Originally, this and odp_packet_is_valid() were defined to enable full sanity check over the object. During debugging user could insert these on the way and (hopefully) catch the point where e.g. packet metadata (e.g. segment linking) was corrupted. Should we specify this full sanity check of object as well? That part is not obvious now and an ODP implementer could easily interpret represents a valid buffer in a less complete way. Perhaps this function needs more return values. E.g. @retval 0 Buffer handle is invalid (no further checks done) @retval 1 Buffer handle is valid but buffer is corrupted @retval 2 Buffer handle is valid and buffer seems correct Another option is to set errno to indicate the reason of failure. Valid vs. broken buffer/packet is the most valuable information from the call. It's secondary to know why it's broken. No need to change return values or add errno for v1.0. Also if this function needs to accept bad handles, I think it means that in general the handle structure/mapping to memory/etc have to be error tolerant, which we try to not force on other calls (by specifying undefined behavior on bad handles). To me it sounds all or nothing - either all buffer calls (that access only odp_buffer_t, no shared resources) have undefined behavior or non. So, I'd leave the patch out from the set, and improve documentation (add sanity check) with another patch. So, I think this function could still crash on bad handles. Is there a use case that application would just want to check the handle validity (without crashing), but not the object sanity? I was thinking that some post-mortem dump code could iterate over all known (to the application) buffer and packet handles and save information about those. But in a crash situation, you can't really be sure that the handles you find are correct, e.g. could be stale handles so treated as invalid by an implementation. But you don't want to crash in your PMD code, in this case just save that this specific handle is invalid. Good point, but maybe post mortem tools are a separate topic (vendor specific). Can we standardize what happens / can be done after crash? I guess not. -Petri -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2 1/4] api: cpu: Added cpu.h
Sorry about top posting … just cannot reply cleanly on HTML mails. Mike, I have seen same thing happening on your patches. On a patch series, one patch modifies a file in one direction and another patch modifies the same in other direction, but as long as the end result is OK - I have not minded. Maybe we have a new rule then on top of check patch and make check passing on each step: “each patch set must be optimized for minimum number of changes per file”. Sure, I can fix it if it’s worth of the delay. -Petri From: ext Mike Holmes [mailto:mike.hol...@linaro.org] Sent: Wednesday, February 04, 2015 12:59 AM To: Bill Fischofer Cc: Anders Roxell; Savolainen, Petri (NSN - FI/Espoo); LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH v2 1/4] api: cpu: Added cpu.h On 3 February 2015 at 17:10, Bill Fischofer bill.fischo...@linaro.orgmailto:bill.fischo...@linaro.org wrote: My review simply says I'm happy with it. Others can NAK it if they choose. On Tue, Feb 3, 2015 at 3:54 PM, Anders Roxell anders.rox...@linaro.orgmailto:anders.rox...@linaro.org wrote: On 2015-02-03 11:16, Bill Fischofer wrote: For this series: Reviewed-by: Bill Fischofer bill.fischo...@linaro.orgmailto:bill.fischo...@linaro.org On Tue, Feb 3, 2015 at 5:25 AM, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.commailto:petri.savolai...@nsn.com wrote: [...] + * + * CPU number where the thread is currently running. CPU numbering is system + * specific. + * + * @return CPU number + */ +int odp_cpu(void); Why not call thus function odp_cpu_num()? (or odp_cpu_number)? odp_cpu is missing something and does not lead to direct understanding of what the function does or returns. I become odp_cpu_id() in the second patch. Why not to name it like this in the first patch? I rebased the second commit (should have rebased the first). The commit history is not perfect, but I think we can live with that. Why do we think this is good enough when others have to redo their patches? nack: I don't think it is ok to accept something when we know it is incorrect. Cheers, Anders ___ lng-odp mailing list lng-odp@lists.linaro.orgmailto:lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp -- Mike Holmes Linaro Sr Technical Manager LNG - ODP ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv5 00/19] Add Strong Typing for ODP Abstract Types
APIs OK. Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Tuesday, February 03, 2015 6:45 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5 00/19] Add Strong Typing for ODP Abstract Types This patch series adds strong typing support for ODP abstract types. This prevents incorrect types from being used with ODP APIs. Misuse of types will now result in a compile-time error. To allow handles to be printed for diagnostic purposes the following new APIs are added that have the signatures: uint64_t odp_buffer_to_u64(odp_buffer_t hdl); uint64_t odp_cos_to_u64(odp_cos_t hdl); uint64_t odp_crypto_compl_to_u64(odp_crypto_compl_t hdl); uint64_t odp_crypto_session_to_u64(odp_crypto_session_t hdl); uint64_t odp_pmr_to_u64(odp_pmr_t_hdl); uint64_t odp_pmr_set_to_u64(odp_pmr_set_t hdl); uint64_t odp_event_to_u64(odp_event_t hdl); uint64_t odp_packet_to_u64(odp_packet_t hdl); uint64_t odp_packet_seg_to_u64(odp_packet_seg_t_print); uint64_t odp_pool_to_u64(odp_pool_t hdl); uint64_t odp_pktio_to_u64(odp_pktio_t hdl); uint64_t odp_queue_to_u64(odp_queue_t hdl); uint64_t odp_shm_to_u64(odp_shm_t hdl); The output of these routines should be printed using the C99 PRIu64 format code, and examples are updated to this convention. Patch change history: v2 - Adds print functions for the remaining public ODP types. It is also rebased to apply on the 0.10.0 release of ODP. v3 - Corrects the definition of odp_buffer_bits to ensure that correct fields are referenced on both big and little endian systems. v4 - Add missing strong typing support for odp_crypto_session_t and odp_crypto_compl_t types. v5 - Change display function names from odp_type_t_print() to odp_type_to_u64(). Split out API changes from linux-generic implementation changes. Petri: Please review these new APIs. All other changes as a result of this patch are internal and transparent to ODP applications. Bill Fischofer (19): api: buffers: add strong typing handle diplay function api: classification: add strong typing handle display functions api: crypto: add strong typing handle display functions api: events: add strong typing handle display function api: packets: add strong typing handle display function api: pktio: add strong typing handle display function api: pool: add strong typing handle display function api: queues: add strong typing handle display function api: shm: add strong typing handle display function linux-generic: add base macros for strong typing support linux-generic: buffers: add strong typing support linux-generic: classification: add strong typing support linux-generic: crypto: add strong typing support linux-generic: events: add strong typing support linux-generic: pktio: add strong typing support linux-generic: packets: add strong typing support linux-generic: pool: add strong typing support linux-generic: queues: add strong typing support linux-generic: shm: add strong typing support example/generator/odp_generator.c | 12 +++-- example/ipsec/odp_ipsec.c | 18 +--- example/l2fwd/odp_l2fwd.c | 11 +++-- example/packet/odp_pktio.c | 22 ++ include/odp/api/buffer.h | 13 ++ include/odp/api/classification.h | 44 - -- include/odp/api/crypto.h | 26 +++ include/odp/api/event.h| 12 + include/odp/api/packet.h | 25 +++ include/odp/api/packet_io.h| 12 + include/odp/api/pool.h | 13 ++ include/odp/api/queue.h| 13 ++ include/odp/api/shared_memory.h| 13 ++ platform/linux-generic/Makefile.am | 1 + .../linux-generic/include/odp/plat/buffer_types.h | 15 +-- .../include/odp/plat/classification_types.h| 34 --- .../linux-generic/include/odp/plat/crypto_types.h | 13 +- .../linux-generic/include/odp/plat/event_types.h | 14 -- .../include/odp/plat/packet_io_types.h | 15 +-- .../linux-generic/include/odp/plat/packet_types.h | 24 +++--- .../linux-generic/include/odp/plat/pool_types.h| 13 +- .../linux-generic/include/odp/plat/queue_types.h | 14 -- .../include/odp/plat/shared_memory_types.h | 13 +- .../linux-generic/include/odp/plat/strong_types.h | 38 .../linux-generic/include/odp_buffer_inlines.h | 16 --- .../linux-generic/include/odp_buffer_internal.h| 31 ++--- .../include/odp_buffer_pool_internal.h | 4 +-
Re: [lng-odp] [PATCH] api: odp_event.h: remove ODP_EVENT_TYPE_INVALID
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Monday, February 02, 2015 6:01 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH] api: odp_event.h: remove ODP_EVENT_TYPE_INVALID Remove ODP_EVENT_TYPE_INVALID from odp_event.h. Update description of odp_event_type(), is does not return ODP_EVENT_TYPE_INVALID. Remove ODP_POOL_TYPE_INVALID from odp_pool.h. It was defined to ODP_EVENT_TYPE_INVALID. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/event.h | 9 ++--- include/odp/api/pool.h| 2 -- platform/linux-generic/include/odp/plat/event_types.h | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/include/odp/api/event.h b/include/odp/api/event.h index 50c031a..ce97bdc 100644 --- a/include/odp/api/event.h +++ b/include/odp/api/event.h @@ -36,11 +36,6 @@ extern C { */ /** - * @def ODP_EVENT_TYPE_INVALID - * Invalid event type - */ - -/** * @def ODP_EVENT_BUFFER * Buffer event */ @@ -61,11 +56,11 @@ extern C { */ /** - * Event type + * Return type of event Don't change the Doxygen brief description. Almost every function return something, no need to mention that in the brief description. The detail description is there for full description/sentences. Otherwise OK. -Petri * * @param eventEvent handle * - * @return Event type or ODP_EVENT_TYPE_INVALID + * @return Event type */ int odp_event_type(odp_event_t event); diff --git a/include/odp/api/pool.h b/include/odp/api/pool.h index 1582102..d09d92e 100644 --- a/include/odp/api/pool.h +++ b/include/odp/api/pool.h @@ -79,8 +79,6 @@ typedef struct odp_pool_param_t { } odp_pool_param_t; -/** Invalid pool type */ -#define ODP_POOL_TYPE_INVALID ODP_EVENT_TYPE_INVALID /** Packet pool*/ #define ODP_POOL_PACKET ODP_EVENT_PACKET /** Buffer pool */ diff --git a/platform/linux-generic/include/odp/plat/event_types.h b/platform/linux-generic/include/odp/plat/event_types.h index 4a0756b..c98d416 100644 --- a/platform/linux-generic/include/odp/plat/event_types.h +++ b/platform/linux-generic/include/odp/plat/event_types.h @@ -30,7 +30,6 @@ typedef odp_buffer_t odp_event_t; #define ODP_EVENT_INVALID ODP_BUFFER_INVALID -#define ODP_EVENT_TYPE_INVALID (-1) #define ODP_EVENT_BUFFER 1 #define ODP_EVENT_PACKET 2 #define ODP_EVENT_TIMEOUT3 -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2 1/4] api: cpu: Added cpu.h
-Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Tuesday, February 03, 2015 1:19 PM To: Ola Liljedahl; Petri Savolainen Cc: LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH v2 1/4] api: cpu: Added cpu.h On 02/03/2015 01:07 PM, Ola Liljedahl wrote: On 3 February 2015 at 11:59, Petri Savolainen petri.savolai...@linaro.org wrote: This file contains cpu related API calls. The calls are renames from odp_thread_cpu() and odp_sys_cpu_count(). Signed-off-by: Petri Savolainen petri.savolai...@linaro.org --- include/odp.h| 1 + include/odp/api/cpu.h| 54 platform/linux-generic/Makefile.am | 2 ++ platform/linux-generic/include/odp/cpu.h | 26 +++ 4 files changed, 83 insertions(+) create mode 100644 include/odp/api/cpu.h create mode 100644 platform/linux-generic/include/odp/cpu.h diff --git a/include/odp.h b/include/odp.h index 30bed8e..99e01eb 100644 --- a/include/odp.h +++ b/include/odp.h @@ -27,6 +27,7 @@ extern C { #include odp/hints.h #include odp/debug.h #include odp/byteorder.h +#include odp/cpu.h #include odp/cpumask.h #include odp/barrier.h #include odp/spinlock.h diff --git a/include/odp/api/cpu.h b/include/odp/api/cpu.h new file mode 100644 index 000..16461a3 --- /dev/null +++ b/include/odp/api/cpu.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +/** + * @file + * + * ODP CPU API + */ + +#ifndef ODP_CPU_H_ +#define ODP_CPU_H_ + +#ifdef __cplusplus +extern C { +#endif + +/** @defgroup odp_cpu ODP CPU + * @{ + */ + + +/** + * CPU number + * + * CPU number where the thread is currently running. CPU numbering is system + * specific. + * + * @return CPU number + */ +int odp_cpu(void); Why not call thus function odp_cpu_num()? (or odp_cpu_number)? odp_cpu is missing something and does not lead to direct understanding of what the function does or returns. I become odp_cpu_id() in the second patch. Why not to name it like this in the first patch? I rebased the second commit (should have rebased the first). The commit history is not perfect, but I think we can live with that. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] api: odp_event.h: remove ODP_EVENT_TYPE_INVALID
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Tuesday, February 03, 2015 10:49 AM To: Savolainen, Petri (NSN - FI/Espoo) Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCH] api: odp_event.h: remove ODP_EVENT_TYPE_INVALID On 3 February 2015 at 09:15, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Monday, February 02, 2015 6:01 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH] api: odp_event.h: remove ODP_EVENT_TYPE_INVALID Remove ODP_EVENT_TYPE_INVALID from odp_event.h. Update description of odp_event_type(), is does not return ODP_EVENT_TYPE_INVALID. Remove ODP_POOL_TYPE_INVALID from odp_pool.h. It was defined to ODP_EVENT_TYPE_INVALID. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) include/odp/api/event.h | 9 ++--- include/odp/api/pool.h| 2 -- platform/linux-generic/include/odp/plat/event_types.h | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/include/odp/api/event.h b/include/odp/api/event.h index 50c031a..ce97bdc 100644 --- a/include/odp/api/event.h +++ b/include/odp/api/event.h @@ -36,11 +36,6 @@ extern C { */ /** - * @def ODP_EVENT_TYPE_INVALID - * Invalid event type - */ - -/** * @def ODP_EVENT_BUFFER * Buffer event */ @@ -61,11 +56,11 @@ extern C { */ /** - * Event type + * Return type of event Don't change the Doxygen brief description. Almost every function return something, no need to mention that in the brief description. The detail description is there for full description/sentences. Most functions have side effects and it is the side effect you are after. What they return is normally just a status code or other information on how successful they were (e.g. number of items processed or written etc) in that side effect. This function *only* returns something with no side effects. Thus the difference in description. When you browse or search through the doxygen API documentation. It would be nice to find the keyword pair event type easily (and consistently). Currently most get type functions are labeled either Type_x param_y or Get type_x param_y (in brief description). You can change it to Get event type, or leave as is. But do not change to Return param_y of type_x. -Petri Otherwise OK. -Petri * * @param eventEvent handle * - * @return Event type or ODP_EVENT_TYPE_INVALID + * @return Event type */ int odp_event_type(odp_event_t event); diff --git a/include/odp/api/pool.h b/include/odp/api/pool.h index 1582102..d09d92e 100644 --- a/include/odp/api/pool.h +++ b/include/odp/api/pool.h @@ -79,8 +79,6 @@ typedef struct odp_pool_param_t { } odp_pool_param_t; -/** Invalid pool type */ -#define ODP_POOL_TYPE_INVALID ODP_EVENT_TYPE_INVALID /** Packet pool*/ #define ODP_POOL_PACKET ODP_EVENT_PACKET /** Buffer pool */ diff --git a/platform/linux-generic/include/odp/plat/event_types.h b/platform/linux-generic/include/odp/plat/event_types.h index 4a0756b..c98d416 100644 --- a/platform/linux-generic/include/odp/plat/event_types.h +++ b/platform/linux-generic/include/odp/plat/event_types.h @@ -30,7 +30,6 @@ typedef odp_buffer_t odp_event_t; #define ODP_EVENT_INVALID ODP_BUFFER_INVALID -#define ODP_EVENT_TYPE_INVALID (-1) #define ODP_EVENT_BUFFER 1 #define ODP_EVENT_PACKET 2 #define ODP_EVENT_TIMEOUT3 -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v1] api: classification: pmr statistics counter API moved out of ODP 1.0
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext bala.manoha...@linaro.org Sent: Friday, January 30, 2015 8:20 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v1] api: classification: pmr statistics counter API moved out of ODP 1.0 From: Balasubramanian Manoharan bala.manoha...@linaro.org odp_pmr_match_count() API related to statistics count of PMR has been moved out of ODP 1.0 version and the same will be incorporated once an ODP level common statistics counter design has been achieved. Signed-off-by: Balasubramanian Manoharan bala.manoha...@linaro.org --- include/odp/api/classification.h| 9 - platform/linux-generic/odp_classification.c | 8 .../classification/odp_classification_tests.c | 21 - 3 files changed, 38 deletions(-) diff --git a/include/odp/api/classification.h b/include/odp/api/classification.h index 5c6636f..609d529 100644 --- a/include/odp/api/classification.h +++ b/include/odp/api/classification.h @@ -279,15 +279,6 @@ int odp_pktio_pmr_cos(odp_pmr_t pmr_id, int odp_cos_pmr_cos(odp_pmr_t pmr_id, odp_cos_t src_cos, odp_cos_t dst_cos); /** - * Retrieve packet matcher statistics - * - * @param[in]pmr_id PMR from which to retrieve the count - * - * @return Current number of matches for a given matcher instance. - */ -signed long odp_pmr_match_count(odp_pmr_t pmr_id); - -/** * Inquire about matching terms supported by the classifier * * @return A mask one bit per enumerated term, one for each of op_pmr_term_e diff --git a/platform/linux-generic/odp_classification.c b/platform/linux- generic/odp_classification.c index 78597ef..31d1328 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -505,14 +505,6 @@ int odp_cos_pmr_cos(odp_pmr_t pmr_id, odp_cos_t src_cos, odp_cos_t dst_cos) return 0; } -signed long odp_pmr_match_count(odp_pmr_t pmr_id) -{ - pmr_t *pmr = get_pmr_entry(pmr_id); - if (pmr == NULL) - return -1; - return (signed long)odp_atomic_load_u32(pmr-s.count); -} - unsigned long long odp_pmr_terms_cap(void) { unsigned long long term_cap = 0; diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c index e4b3260..45822d3 100644 --- a/test/validation/classification/odp_classification_tests.c +++ b/test/validation/classification/odp_classification_tests.c @@ -423,8 +423,6 @@ void test_cls_pmr_chain(void) pkt = receive_packet(queue, ODP_TIME_SEC); CU_ASSERT(queue == queue_list[CLS_PMR_CHAIN_SRC]); CU_ASSERT(seq == cls_pkt_get_seq(pkt)); - - CU_ASSERT(1 == odp_pmr_match_count(pmr_list[CLS_PMR_CHAIN_DST])); odp_packet_free(pkt); } @@ -657,7 +655,6 @@ void test_pmr_cos(void) pkt = receive_packet(queue, ODP_TIME_SEC); CU_ASSERT(queue == queue_list[CLS_PMR]); CU_ASSERT(seq == cls_pkt_get_seq(pkt)); - CU_ASSERT(1 == odp_pmr_match_count(pmr_list[CLS_PMR])); odp_packet_free(pkt); } @@ -740,23 +737,6 @@ void test_pktio_pmr_match_set_cos(void) odp_packet_free(pkt); } -static void classification_pmr_match_count(void) -{ - odp_pmr_t pmr; - uint16_t val; - uint16_t mask; - val = 1024; - mask = 0x; - int retval; - pmr = odp_pmr_create_match(ODP_PMR_TCP_SPORT, val, mask, sizeof(val)); - CU_ASSERT(pmr != ODP_PMR_INVAL); - - retval = odp_pmr_match_count(pmr); - CU_ASSERT(retval == 0); - - odp_pmr_destroy(pmr); -} - static void classification_pmr_terms_avail(void) { int retval; @@ -814,6 +794,5 @@ CU_TestInfo classification_tests[] = { _CU_TEST_INFO(classification_pmr_terms_cap), _CU_TEST_INFO(classification_pktio_configure), _CU_TEST_INFO(classification_pktio_test), - _CU_TEST_INFO(classification_pmr_match_count), CU_TEST_INFO_NULL, }; -- 2.0.1.472.g6f92e5f ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 1/5] api: odp_hints: Add ODP_NORETURN
Entire patch set: Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mike Holmes Sent: Friday, January 30, 2015 12:52 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH 1/5] api: odp_hints: Add ODP_NORETURN Add the ability to mark a function as never returning to the caller. Signed-off-by: Mike Holmes mike.hol...@linaro.org --- include/odp/api/hints.h | 4 1 file changed, 4 insertions(+) diff --git a/include/odp/api/hints.h b/include/odp/api/hints.h index 7f04886..a7aa90e 100644 --- a/include/odp/api/hints.h +++ b/include/odp/api/hints.h @@ -25,6 +25,10 @@ extern C { #ifdef __GNUC__ +/** Define a fn that does not return + */ +#define ODP_NORETURN __attribute__((__noreturn__)) + /** Define a weak symbol * This is primarily useful in defining library functions that can be * overridden in user code. -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 1/2] api: pool: Added packet pool parameters
Hi, An ODP application is SW running on cores (not HW or firmware). If there's no SW, there's no need for ODP API. Application receives odp_packets, which consist of odp_packet_segs. From application point of view, each segment is a block of contiguous memory (implementation can be anything as long as application can access it contiguously). Application has the knowledge on incoming packets and SW processing of those. Segmentation is a trade-off between linear memory processing (good performance) and memory usage. These parameters give application the change to tune the trade-off in each use case. For example, application may - receive 49% 64 byte packets, 49% 1500 byte packets and 2% 9kB packets - read up to 300 bytes into a packet - add upto 54 bytes of tunnel headers in front of the packet = ask first min seg len 354 bytes, that would fit all accesses. Implementation rounds that up to 384 bytes (full cache line) = run tests and notice that performance is good, but we need to lower the memory usage of this pool = drop min seg len to 200 bytes, implementation rounds that to 256 = run tests, performance is still good enough and pool uses less memory (which can be then used for something else) How implementation could do this trade-off analysis behalf of the user? + uint32_t seg_len; /** Minimum packet segment buffer +length in bytes. It includes +possible head-/tailroom bytes. +Use 0 for default length. */ In addition to this, we have lower and upper config limits (ODP_CONFIG_PACKET_BUF_LEN_XXX need to be updated also). If implementation can support only one segment len, it will be documented by those min/max limits being the same. -Petri -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Sunday, February 01, 2015 12:06 AM To: Bill Fischofer Cc: Petri Savolainen; LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH 1/2] api: pool: Added packet pool parameters One important aspect of ODP is a hardware abstraction, the ODP API is supposed to hide implementations details such as how buffers are managed (segmentation is one implementation detail that we allow to leak through as this is common and very expensive to hide from the application). I recently heard of a 40G NIC which doesn't use (user visible) buffer pools at all. You just pass a large (shared) memory region to the NIC and it carves up suitable buffers as needed. Needless to say, DPDK has problem with that. But ODP shouldn't. On 31 January 2015 at 01:22, Bill Fischofer bill.fischo...@linaro.org wrote: I really can't concur with this proposed design. The fundamental issue here is the proper relationship between applications and implementations with respect to packet storage. Packets have an overall length, and this is within the purview of the application, since it understands the type of traffic it is looking to process. Length is a property that packets have on the wire and is independent of how packets may be stored within a processing node. Segments are always an implementation construct and exist for the convenience of an implementation. Segments do not exist on the wire and are not part of any inherent (i.e., platform-independent) packet structure. To assert application control over packet segmentation is to say that the application is controlling the implementation of packet storage. This is a fundamental departure from the API/Implementation separation paradigm that ODP is promoting. If an application wishes to do this it is leaving no room for HW offload or innovation in this area--it's just using the HW as a raw block manager and doing everything itself in SW. It is understood that the existence of segmentation imposes some processing overhead on SW to the extent that SW must deal with the seams in a packet addressability that results from segmentation. There are two ways to address this. The first is to recognize that in the data plane the vast bulk of processing is on packet headers rather than payload and that HW is aware of this fact, which is why HW designed for packet processing invariably uses segment sizes large enough to contain all of the packet headers within the first packet segment for the vast majority of packets of interest. In the spec we worked on last year we stated that ODP would require a minimum segment size of 256 bytes so that applications would have assurance regarding this, and no surveyed platforms had issues with that. The second means of addressing this problem is to allow applications to explicitly request unsegmented pools. While recognizing that not all platforms can provide unsegmented pools efficiently, the idea behind unsegmented pools was that this would aid
Re: [lng-odp] [PATCH 1/2] api: config: move ODP_SHM_NUM_BLOCKS to config.h
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mike Holmes Sent: Saturday, January 31, 2015 3:21 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH 1/2] api: config: move ODP_SHM_NUM_BLOCKS to config.h ODP_SHM_NUM_BLOCKS was defined down in the implementation, move it out to the config.h Signed-off-by: Mike Holmes mike.hol...@linaro.org --- include/odp/api/config.h | 6 ++ platform/linux-generic/odp_shared_memory.c | 5 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/odp/api/config.h b/include/odp/api/config.h index 3529fca..16157b0 100644 --- a/include/odp/api/config.h +++ b/include/odp/api/config.h @@ -119,6 +119,12 @@ extern C { */ #define ODP_CONFIG_PACKET_BUF_LEN_MAX (ODP_CONFIG_PACKET_BUF_LEN_MIN*6) +/** Maximum number of shared memory blocks. + * + * Limits how many blocks are available for calls to odp_shm_reserve() + */ +#define ODP_SHM_NUM_BLOCKS 32 All config macros must have ODP_CONFIG_ prefix. So rename it to this: #define ODP_CONFIG_SHM_BLOCKS 64 -Petri + /** * @} */ diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux- generic/odp_shared_memory.c index 96d10e8..e157871 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -15,6 +15,7 @@ #include odp/debug.h #include odp_debug_internal.h #include odp_align_internal.h +#include odp/config.h #include unistd.h #include sys/mman.h @@ -26,10 +27,6 @@ #include string.h #include errno.h - -#define ODP_SHM_NUM_BLOCKS 32 - - typedef struct { char name[ODP_SHM_NAME_LEN]; uint64_t size; -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] Handling xxx_INVALID handles
-Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Friday, January 30, 2015 3:17 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Ola Liljedahl; lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 01/30/2015 02:41 PM, Savolainen, Petri (NSN - FI/Espoo) wrote: -Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Friday, January 30, 2015 2:28 PM To: Savolainen, Petri (NSN - FI/Espoo); ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 01/30/2015 02:06 PM, Savolainen, Petri (NSN - FI/Espoo) wrote: -Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Friday, January 30, 2015 1:50 PM To: Savolainen, Petri (NSN - FI/Espoo); ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 01/30/2015 01:15 PM, Savolainen, Petri (NSN - FI/Espoo) wrote: As explained below, XXX_NULL != XXX_INVALID enables to distinguish this error ... x = odp_xxx_create(...); // error! = Returns XXX_INVALID y = odp_yyy_create(x, ); // x == XXX_INVALID = error! Deferring error detection to a second function doesn't look like a good practice. It will be harder to determine a cause of the error then. The error! mains any, undefined error (e.g. crash). It's an example of an error, another would be this. x = XXX_INVALID; //init // forgot to set x with valid value y = odp_yyy_create(x, ); // x == XXX_INVALID = error! Also 'x == XXX_INVALID = error!' is not a correct statement. We agreed that 'x == XXX_INVALID = *undefined behavior*', so this is a definitely a bad example. Error! == undefined error, crash! 'Undefined behavior' means not only error return or crash, but it can silently succeed and mess some unrelated stuff. So application will crash later in some random place. Do you want to promote such API usage? Sorry, but I'm really missing your point. The point is that, if we use XXX_INVALID to indicate that user choose to let the implementation decide on parameter X (e.g. let pool_create() to reserve the shared memory), how implementation would separate that intention from a bad handle (like XXX_INVALID)? We reserve special handle id XXX_NULL for that purpose only. When user gives that implementation, do not crash etc, but knows that it has to reserve the resource X. Behaviour is undefined: odp_xxx_create(XXX_INVALID, ..) Behaviour is defined: odp_xxx_create(XXX_NULL, ..) I understand that part, but if I try to list possible use cases which don't cause undefined behavior, then XXX_INVALID seems to be redundant anyway. Let's take your example x = odp_xxx_create(...); // error! = Returns XXX_INVALID y = odp_yyy_create(x, ); // x == XXX_INVALID = error! - If x can be XXX_INVALID, then application have to *always* check it before passing to odp_yyy_create(). Otherwise - undefined behavior. - If application have to check it anyway, then it can test it against ODP_XXX_NULL - odp_xxx_create() can return _NULL instead of _INVALID. - If x is ODP_XXX_NULL, then odp_yyy_create() should not be called. - No need for ODP_XXX_INVALID. Can you give an example which doesn't cause undefined behavior where both XXX_IVALID and XXX_NULL are needed? The example above is an example of bad application. Of course application should check x before passing it forward, but when it _fails_ to do so (or inits it but fails to set it with a valid handle), we are still possible to catch that. If we use the same value as invalid return value and null option, we cannot even check for the error above. 1) x = odp_xxx_create(...); // Should check x here, but missed it. // Robust implementation should catch bad x, instead of // letting odp_yyy_create() to succeed always with implementation // reserved resource x. // Implementation is in control of picking value for XXX_INVALID. y = odp_yyy_create(x, ..); 2) x = XXX_INVALID; // Intention is to stop if we don't create x if (0) x = odp_xxx_create(...); if (x == XXX_INVALID) ABORT; else ... // oops, forgot to call odp_xxx_create(...) // Failed to call odp_xxx_create(). Again implementation // is possible to catch this, if XXX_NULL != XXX_INVALID. y = odp_yyy_create(x, ..); 3) x = XXX_NULL; // Intention is to use default if we don't create x if (0) x = odp_xxx_create(...); if (x == XXX_INVALID) ABORT; else ... // Use default y = odp_yyy_create(x, ..); 1) and 2) have bugs and user wants to find those as early as possible. Why API should force odp_yyy_create() to always succeed in 1) and 2)? It was not user's intention to continue there (with default). He wants to catch the bug early - either through crash
Re: [lng-odp] Handling xxx_INVALID handles
x = odp_xxx_create(...); // error! = Returns XXX_INVALID y = odp_yyy_create(x, ); // x == XXX_INVALID = error! When in ODP will this be the recommended or desired practice? Either the user will have to check the return values for success or the different calls will have to check their inputs for validity. If we are trying to support a number of (non-obvious) design patterns for the applications to use, these need to be documented (e.g. in architecture document or user's guide). There only one design pattern for application: check return values. We provide error check possibility for implementation. x = XXX_INVALID; //init Why initialize x at all? The compiler will warn you if you are reading x before it has been assigned a value. IMO default initializations are dangerous. It documents your intention: by default I'm doing X. Yes, compiler can check that it's always set, but it does not which values produce correct behavior by default (e.g. fail/crash by default). -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] Handling xxx_INVALID handles
I don't think these use cases can be supported unless we define that ODP calls must detect INVALID handles and handle them in a well-defined manner. The question is which calls, perhaps all of them. To me undefined behavior is crash or return error. That should be the goal for implementers anyway. Implementation has basically two options - use pointer as handle and access that without checking it = crash - use index as handle: fast to check it and return error, or map the table memory so that invalid handle cause page miss and crash. Third, option would be to successfully use invalid handles/pointers into memory and return success for any random handles, but I would not use that implementation for production... -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] Handling xxx_INVALID handles
-Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Friday, January 30, 2015 2:28 PM To: Savolainen, Petri (NSN - FI/Espoo); ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 01/30/2015 02:06 PM, Savolainen, Petri (NSN - FI/Espoo) wrote: -Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Friday, January 30, 2015 1:50 PM To: Savolainen, Petri (NSN - FI/Espoo); ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 01/30/2015 01:15 PM, Savolainen, Petri (NSN - FI/Espoo) wrote: As explained below, XXX_NULL != XXX_INVALID enables to distinguish this error ... x = odp_xxx_create(...); // error! = Returns XXX_INVALID y = odp_yyy_create(x, ); // x == XXX_INVALID = error! Deferring error detection to a second function doesn't look like a good practice. It will be harder to determine a cause of the error then. The error! mains any, undefined error (e.g. crash). It's an example of an error, another would be this. x = XXX_INVALID; //init // forgot to set x with valid value y = odp_yyy_create(x, ); // x == XXX_INVALID = error! Also 'x == XXX_INVALID = error!' is not a correct statement. We agreed that 'x == XXX_INVALID = *undefined behavior*', so this is a definitely a bad example. Error! == undefined error, crash! 'Undefined behavior' means not only error return or crash, but it can silently succeed and mess some unrelated stuff. So application will crash later in some random place. Do you want to promote such API usage? Sorry, but I'm really missing your point. The point is that, if we use XXX_INVALID to indicate that user choose to let the implementation decide on parameter X (e.g. let pool_create() to reserve the shared memory), how implementation would separate that intention from a bad handle (like XXX_INVALID)? We reserve special handle id XXX_NULL for that purpose only. When user gives that implementation, do not crash etc, but knows that it has to reserve the resource X. Behaviour is undefined: odp_xxx_create(XXX_INVALID, ..) Behaviour is defined: odp_xxx_create(XXX_NULL, ..) -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] Handling xxx_INVALID handles
As explained below, XXX_NULL != XXX_INVALID enables to distinguish this error ... x = odp_xxx_create(...); // error! = Returns XXX_INVALID y = odp_yyy_create(x, ); // x == XXX_INVALID = error! ... from this valid use case (user choose to leave x NULL) y = odp_yyy_create(XXX_NULL, ); -Petri -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Friday, January 30, 2015 10:58 AM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Bill Fischofer; lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 30 January 2015 at 09:08, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: In API definition, XXX_NULL is not alias for XXX_INVALID. When user passes XXX_NULL, it tells that application did not pass a handle. If user passes XXX_INVALID, it’s an error (e.g. another ODP call returned XXX_INVALID before this one, and user tries to pass that INVALID forward). How is this not like passing a NULL handle? Current linux-generic odp_pool_create() implementation uses SHM_NULL and SHM_INVALID as synonyms, but that’s not robust and actually against API definition, since SHM_INVALID should cause an error. I understand the definition and usage of ODP_SHM_NULL, it's like any other NULL definitions, including the NULL pointer in C/C++. But if the INVALID and NULL handles are not supposed to be equivalent, then I don't understand why ODP needs the INVALID handles. You never need to specify an INVALID handle (if you have the NULL handle) and calls that cannot return a handle that refers to a valid object can return the NULL handle. So what's the INVALID handle for? Currently it seems like the INVALID handle is a synonym for the NULL handle but only for outputs (return values) according to your statement above. The semantics of the different ODP operations here do not seem different from e.g. malloc, strdup and free. How come C can support these operations with only a NULL handle? -Petri From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Thursday, January 29, 2015 11:14 PM To: Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles Given that pool creation/deletion is a relatively involved procedure and not expected to be called frequently, it makes sense to include full parameter validation as part of the operation. The same should be true for other APIs with similar expected call frequencies. We do allow explicit INVALID input parameters, however for semantic reasons they sometimes have aliases. For example, odp_pool_create() can take ODP_SHM_NULL as input to specify that the caller is not supplying a shm handle. However this is just an alias for ODP_SHM_INVALID since that is the distinguished not a handle value for that data type. ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] Handling xxx_INVALID handles
-Original Message- From: ext Taras Kondratiuk [mailto:taras.kondrat...@linaro.org] Sent: Friday, January 30, 2015 1:50 PM To: Savolainen, Petri (NSN - FI/Espoo); ext Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 01/30/2015 01:15 PM, Savolainen, Petri (NSN - FI/Espoo) wrote: As explained below, XXX_NULL != XXX_INVALID enables to distinguish this error ... x = odp_xxx_create(...); // error! = Returns XXX_INVALID y = odp_yyy_create(x, ); // x == XXX_INVALID = error! Deferring error detection to a second function doesn't look like a good practice. It will be harder to determine a cause of the error then. The error! mains any, undefined error (e.g. crash). It's an example of an error, another would be this. x = XXX_INVALID; //init // forgot to set x with valid value y = odp_yyy_create(x, ); // x == XXX_INVALID = error! Also 'x == XXX_INVALID = error!' is not a correct statement. We agreed that 'x == XXX_INVALID = *undefined behavior*', so this is a definitely a bad example. Error! == undefined error, crash! -Petri ... from this valid use case (user choose to leave x NULL) y = odp_yyy_create(XXX_NULL, ); -Petri -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Friday, January 30, 2015 10:58 AM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Bill Fischofer; lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 30 January 2015 at 09:08, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: In API definition, XXX_NULL is not alias for XXX_INVALID. When user passes XXX_NULL, it tells that application did not pass a handle. If user passes XXX_INVALID, it’s an error (e.g. another ODP call returned XXX_INVALID before this one, and user tries to pass that INVALID forward). How is this not like passing a NULL handle? Current linux-generic odp_pool_create() implementation uses SHM_NULL and SHM_INVALID as synonyms, but that’s not robust and actually against API definition, since SHM_INVALID should cause an error. I understand the definition and usage of ODP_SHM_NULL, it's like any other NULL definitions, including the NULL pointer in C/C++. But if the INVALID and NULL handles are not supposed to be equivalent, then I don't understand why ODP needs the INVALID handles. You never need to specify an INVALID handle (if you have the NULL handle) and calls that cannot return a handle that refers to a valid object can return the NULL handle. So what's the INVALID handle for? Currently it seems like the INVALID handle is a synonym for the NULL handle but only for outputs (return values) according to your statement above. The semantics of the different ODP operations here do not seem different from e.g. malloc, strdup and free. How come C can support these operations with only a NULL handle? -Petri From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Thursday, January 29, 2015 11:14 PM To: Ola Liljedahl Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles Given that pool creation/deletion is a relatively involved procedure and not expected to be called frequently, it makes sense to include full parameter validation as part of the operation. The same should be true for other APIs with similar expected call frequencies. We do allow explicit INVALID input parameters, however for semantic reasons they sometimes have aliases. For example, odp_pool_create() can take ODP_SHM_NULL as input to specify that the caller is not supplying a shm handle. However this is just an alias for ODP_SHM_INVALID since that is the distinguished not a handle value for that data type. ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv4 1/5] api: crypto: new completion event scheme
Hi, Reviewed-by: Petri Savolainen petri.savolai...@linaro.org API changes are OK and can be merged today. Two things should be fixed then on top of that. 1) odp_hw_random_get() This could be renamed to e.g. odp_rand() and moved out from crypto header (odp_misc.h ?) size_t odp_rand(uint8_t *buf, size_t len, odp_bool_t use_entropy); Should it return number of bytes written, instead of output param *len? 2) Correct sequences to free a compl event needs to be specified more clearly. There seems to be only one right now? compl = odp_crypto_compl_from_event(ev); odp_crypto_compl_result(compl, result); odp_crypto_compl_free(compl); if(result.pkt != ODP_PACKET_INVALID) odp_packet_free(result.pkt) Simple free call would result memory leak because the result packet would not be freed: compl = odp_crypto_compl_from_event(ev); odp_crypto_compl_free(compl); + +/** + * Release crypto completion event + * + * @param completion_event Completion event we are done accessing e.g. @note User needs to free the potential result packet. This call frees the completion event only. + */ +void +odp_crypto_compl_free(odp_crypto_compl_t completion_event); -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] API questions - sizes and numelems as inputs and outputs
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Wednesday, January 28, 2015 7:06 PM To: LNG ODP Mailman List Subject: [lng-odp] API questions - sizes and numelems as inputs and outputs Talking about API's that take some type of element count or buffer size as input and return a value related to that. There seems to be a number of different models. /** * Generate random byte string * * @param buf Pointer to store result * @param len Pointer to input length value as well as return value I assume the return value is the number of result bytes stored. But this is not very clear. * @param use_entropy Use entropy * * @todo Define the implication of the use_entropy parameter * * @retval 0 on success Not the same return value as described above. * @retval 0 on failure */ int odp_hw_random_get(uint8_t *buf, size_t *len, bool use_entropy); Here we return the actual size written (I assume) through the len parameter which is consequently passed by reference. How use full the function is if it does not fill the whole buffer with rand data? I think in this case should be success vs. failure. In success the whole buffer is written. /** * Write CPU mask as a string of hexadecimal digits * * @param mask CPU mask to write * @param bufOutput buffer * @param bufsz Size of output buffer * * @return 0 on success. Number of characters written (including the * terminating null char). * @return 0 on failure (output buffer too small). */ size_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *buf, size_t bufsz); The new definition of odp_cpumask_to_str() as recently agreed. Number of characters written is returned. It can't be 0 so 0 can be used as an error indicator. In other formatting-type of functions, 0 might be a valid return value (it primarily depends on whether the terminating null char should be included in the count). * @param[out] mac_addr Storage for MAC address of the packet IO interface. * @param addr_size Storage size for the address * * @retval Number of bytes written on success, 0 on failure. */ size_t odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, size_t addr_size); This function returns 0 for failure (but this is incidental and prevents us to support pktio types that have zero-length MAC address (i.e. does not have any MAC address)). What is a successful copy of a zero length MAC address? I think it's OK to return failure (==0), if user asks for a copy of MAC address from a interface that do not have one. /** * Copy data from packet * * Copy 'len' bytes of data from the packet level offset to the destination * address. * * @param pktPacket handle * @param offset Byte offset into the packet * @param lenNumber of bytes to copy * @param dstDestination address * * @retval 0 on success * @retval 0 on failure Not documented what constitutes a failure. */ int odp_packet_copydata_out(odp_packet_t pkt, uint32_t offset, uint32_t len, void *dst); What if less than len bytes could be copied (because reaching end of packet)? How is this reported? Should we use uint32_t *len and update it on return with the actual number of bytes copied? Or is this situation considered an error and reported with a negative return value? Seems excessive. Better to just specify len as the size of the output buffer and in some way be notified about the actual number of bytes copied. It's better to keep this simple: success or failure. In success len bytes was copied. It's not important how many bytes were copied in failure. Failures: offset odp_packet_len() offset + len odp_packet_len() /** * Copy data into packet * * Copy'len' bytes of data from the source address into the packet level * offset. Maximum number of bytes to copy is packet data length minus the * offset. Packet is not modified on an error. * * @param pktPacket handle * @param offset Byte offset into the packet * @param lenNumber of bytes to copy * @param srcSource address * * @retval 0 on success * @retval 0 on failure Not documented what constitutes a failure. */ int odp_packet_copydata_in(odp_packet_t pkt, uint32_t offset, uint32_t len, const void *src); Similar for this function. Is it an error if 'len' bytes does not fit into the current packet size? Is this good semantics? Failures: offset odp_packet_len() offset + len odp_packet_len() /** * Receive packets * * @param id ODP packet IO handle * @param pkt_table[] Storage for received packets (filled by function) * @param len Length of pkt_table[], i.e. max number of pkts to receive * * @return Number of packets received * @retval 0 on failure */ int odp_pktio_recv(odp_pktio_t
Re: [lng-odp] Handling xxx_INVALID handles
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Taras Kondratiuk Sent: Thursday, January 29, 2015 6:47 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] Handling xxx_INVALID handles Hi We had a discussion recently about wrong ODP handles passed to API functions. As far as I remember we agreed that in this case behavior is undefined. What about passing xxx_INVALID values to API? Currently packet IO verification tests pass ODP_PKTIO_INVALID explicitly to some API functions and expect them to return error. Generally, XXX_INVALID is as bad handle as any other random value, and API calls are not expected handle it differently (if not documented otherwise). It's implementation choice if it checks for that specific value (and on which debug levels). XXX_NULL handle is specific (input) value telling that user does not give a valid handle and e.g. lets the implementation to allocate the resource. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] Handling xxx_INVALID handles
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Thursday, January 29, 2015 7:02 PM To: Taras Kondratiuk Cc: lng-odp@lists.linaro.org Subject: Re: [lng-odp] Handling xxx_INVALID handles On 29 January 2015 at 17:46, Taras Kondratiuk taras.kondrat...@linaro.org wrote: Petri requires calls on shared resources (e.g. shared memory, pools) to be robust even when called with *stale* handles (because some other thread might just have freed the shared resource). No, implementation is _not required_ to do that check, but API definition must not ban that check. If implementation can check it, it can return an error. If it cannot check, it will crash. Application will always check the return value. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] odp_cpumask.h
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, January 28, 2015 1:29 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: LNG ODP Mailman List Subject: Re: [lng-odp] odp_cpumask.h On 28 January 2015 at 12:21, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Wednesday, January 28, 2015 12:48 PM To: LNG ODP Mailman List Subject: [lng-odp] odp_cpumask.h * @param strOutput buffer * @param lenSize of string length (incl. ending zero) */ void odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int len); Why don't we use size_t for thelen parameter? -- Ola It's an object size, so it can be changed to size_t (similar to e.g. snprintf()). Packet data len/offsets, buffer sizes, packet/bytes counts etc, should be uintxx_t - but object sizes should be size_t. Answer to: What happens if len output length? Maybe we copy the snprintf definition (except output also ending zero). Return number chars written (incl. str ending zero), otherwise return number of chars that would have been outputted (return len and clip output). This is more complicated to check for and goes against the convention of returning 0 for errors. I would prefer my suggestion with returning -(minimum required buffer size), there's a clear separation between success and error. And that we add a define with a suggested buffer size which will be usable when the CPU mask is full (all bits set), this seems to be 128 when using Linux cpu_set_t for the implementation. Of course ODP could use a smaller max size as well. About error from functions that return len. I'd have input param and return type the same, so that compiler don't complain when comparing those (maybe your audio was breaking on call yesterday on that part). e.g. size_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, size_t len); size_t len, out; char str[SIZE]; len = sizeof(str); out = odp_cpumask_to_str(mask, str, len); if (out len) { printf(output needs %z chars, out); ABORT(); } -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] api: packet: odp_packet_flags spec changes
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Wednesday, January 28, 2015 12:37 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH] api: packet: odp_packet_flags spec changes Change odp_packet_error() to odp_packet_has_error() and delete odp_packet_errflag_frame_len() per v1.0 delta doc. Signed-off-by: Bill Fischofer bill.fischo...@linaro.org --- example/generator/odp_generator.c | 2 +- example/ipsec/odp_ipsec.c | 2 +- example/l2fwd/odp_l2fwd.c | 2 +- example/packet/odp_pktio.c| 2 +- platform/linux-generic/include/api/odp_packet_flags.h | 13 +++-- platform/linux-generic/odp_packet_flags.c | 9 + test/validation/buffer/odp_packet_test.c | 5 + test/validation/odp_pktio.c | 2 +- 8 files changed, 10 insertions(+), 27 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 492664e..ad62e08 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -522,7 +522,7 @@ static void *gen_recv_thread(void *arg) pkt = odp_packet_from_event(ev); /* Drop packets with errors */ - if (odp_unlikely(odp_packet_error(pkt))) { + if (odp_unlikely(odp_packet_has_error(pkt))) { odp_packet_free(pkt); continue; } diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index f2d2fc7..22fddb2 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -616,7 +616,7 @@ static pkt_disposition_e do_input_verify(odp_packet_t pkt, pkt_ctx_t *ctx EXAMPLE_UNUSED) { - if (odp_unlikely(odp_packet_error(pkt))) + if (odp_unlikely(odp_packet_has_error(pkt))) return PKT_DROP; if (!odp_packet_has_eth(pkt)) diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c index 18403da..305d9ae 100644 --- a/example/l2fwd/odp_l2fwd.c +++ b/example/l2fwd/odp_l2fwd.c @@ -424,7 +424,7 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len) for (i = 0, j = 0; i len; ++i) { pkt = pkt_tbl[i]; - if (odp_unlikely(odp_packet_error(pkt))) { + if (odp_unlikely(odp_packet_has_error(pkt))) { odp_packet_free(pkt); /* Drop */ pkt_cnt--; } else if (odp_unlikely(i != j++)) { diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c index c4c720b..1972dfa 100644 --- a/example/packet/odp_pktio.c +++ b/example/packet/odp_pktio.c @@ -408,7 +408,7 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len) for (i = 0, j = 0; i len; ++i) { pkt = pkt_tbl[i]; - if (odp_unlikely(odp_packet_error(pkt))) { + if (odp_unlikely(odp_packet_has_error(pkt))) { odp_packet_free(pkt); /* Drop */ pkt_cnt--; } else if (odp_unlikely(i != j++)) { diff --git a/platform/linux-generic/include/api/odp_packet_flags.h b/platform/linux-generic/include/api/odp_packet_flags.h index 24c4065..c239a28 100644 --- a/platform/linux-generic/include/api/odp_packet_flags.h +++ b/platform/linux-generic/include/api/odp_packet_flags.h @@ -32,17 +32,10 @@ extern C { * Checks all error flags at once. * * @param pkt Packet handle - * @return 1 if packet has errors, 0 otherwise + * @retval 1 packet has errors + * @retval 0 packet has no errors */ -int odp_packet_error(odp_packet_t pkt); - -/** - * Check if error was 'frame length' error - * - * @param pkt Packet handle - * @return 1 if frame length error detected, 0 otherwise - */ -int odp_packet_errflag_frame_len(odp_packet_t pkt); +int odp_packet_has_error(odp_packet_t pkt); /** * Check for L2 header, e.g. ethernet diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux- generic/odp_packet_flags.c index 3f0ea9f..e678f66 100644 --- a/platform/linux-generic/odp_packet_flags.c +++ b/platform/linux-generic/odp_packet_flags.c @@ -8,18 +8,11 @@ #include odp_packet_internal.h -int odp_packet_error(odp_packet_t pkt) +int odp_packet_has_error(odp_packet_t pkt) { return (odp_packet_hdr(pkt)-error_flags.all != 0); } -/* Get Error Flags */ - -int odp_packet_errflag_frame_len(odp_packet_t pkt) -{ - return odp_packet_hdr(pkt)-error_flags.frame_len; -} - /* Get Input Flags */ int odp_packet_has_l2(odp_packet_t pkt) diff --git a/test/validation/buffer/odp_packet_test.c b/test/validation/buffer/odp_packet_test.c index c1b28ab..022f9a3 100644 ---
Re: [lng-odp] odp_cpumask.h
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Wednesday, January 28, 2015 12:48 PM To: LNG ODP Mailman List Subject: [lng-odp] odp_cpumask.h * @param strOutput buffer * @param lenSize of string length (incl. ending zero) */ void odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int len); Why don't we use size_t for thelen parameter? -- Ola It's an object size, so it can be changed to size_t (similar to e.g. snprintf()). Packet data len/offsets, buffer sizes, packet/bytes counts etc, should be uintxx_t - but object sizes should be size_t. Answer to: What happens if len output length? Maybe we copy the snprintf definition (except output also ending zero). Return number chars written (incl. str ending zero), otherwise return number of chars that would have been outputted (return len and clip output). -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] odp_cpumask.h
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, January 28, 2015 2:03 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: LNG ODP Mailman List Subject: Re: [lng-odp] odp_cpumask.h On 28 January 2015 at 12:55, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Wednesday, January 28, 2015 1:29 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: LNG ODP Mailman List Subject: Re: [lng-odp] odp_cpumask.h On 28 January 2015 at 12:21, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Wednesday, January 28, 2015 12:48 PM To: LNG ODP Mailman List Subject: [lng-odp] odp_cpumask.h * @param strOutput buffer * @param lenSize of string length (incl. ending zero) */ void odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int len); Why don't we use size_t for thelen parameter? -- Ola It's an object size, so it can be changed to size_t (similar to e.g. snprintf()). Packet data len/offsets, buffer sizes, packet/bytes counts etc, should be uintxx_t - but object sizes should be size_t. Answer to: What happens if len output length? Maybe we copy the snprintf definition (except output also ending zero). Return number chars written (incl. str ending zero), otherwise return number of chars that would have been outputted (return len and clip output). This is more complicated to check for and goes against the convention of returning 0 for errors. I would prefer my suggestion with returning -(minimum required buffer size), there's a clear separation between success and error. And that we add a define with a suggested buffer size which will be usable when the CPU mask is full (all bits set), this seems to be 128 when using Linux cpu_set_t for the implementation. Of course ODP could use a smaller max size as well. About error from functions that return len. I'd have input param and return type the same, so that compiler don't complain when comparing those (maybe your audio was breaking on call yesterday on that part). No I didn't hear, my wifi router stopped working and had to be reset... e.g. size_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, size_t len); Better to use ssize_t then? The point is that the same type is used for len and return value. Explicitly signed type for len would not be intuitive. size_t len, out; char str[SIZE]; len = sizeof(str); out = odp_cpumask_to_str(mask, str, len); if (out len) { Simple yes. But we just defined the convention that we use negative values to indicate failures. Why not follow that here? To use positive values to indicate both success and error conditions seems confusing to me. snprintf is not a good example here. The same, unsigned type - so that compiler does not complain when comparing those two. size_t a; ssize_t b; if (a b) gcc -W -Wall ... main.c:17:8: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] if (a b) -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] odp_cpumask.h
(maybe your audio was breaking on call yesterday on that part). I have tested mixing size_t and ssize_t and neither gcc nor clang complained. I was using -Wall -ansi -pedantic. Missing -W from there ? -Wall is not enough... ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v5 07/17] api: packet: Removed odp_packet_to_buffer
I don’t have time to rebase it today. I’d propose to revert the conflicting patch from the repo and rebase that instead. It saves a day or two, plus stops conflicting new development (usage of buffers instead of events). - Petri From: ext Bill Fischofer [mailto:bill.fischo...@linaro.org] Sent: Tuesday, January 27, 2015 12:17 AM To: Mike Holmes Cc: Petri Savolainen; lng-odp Subject: Re: [lng-odp] [PATCH v5 07/17] api: packet: Removed odp_packet_to_buffer We need to halt merges until events are merged. That's why it's critical path. We should be able to fix this as a one-off but we can't keep rebasing it. Everything else should rebase on events. We'll have the same merge-barrier all stop issue with the API directory change. Bill On Mon, Jan 26, 2015 at 3:57 PM, Mike Holmes mike.hol...@linaro.orgmailto:mike.hol...@linaro.org wrote: This no longer applies to tip classification/odp_classification_tests.c: In function ‘enqueue_loop_interface’: classification/odp_classification_tests.c:108:2: error: implicit declaration of function ‘odp_packet_to_buffer’ [-Werror=implicit-function-declaration] odp_queue_enq(defqueue, odp_packet_to_buffer(pkt)); ^ classification/odp_classification_tests.c:108:2: error: nested extern declaration of ‘odp_packet_to_buffer’ [-Werror=nested-externs] On 26 January 2015 at 08:05, Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org wrote: Removed packet to buffer conversion. packet - event - buffer conversions are temporary. Signed-off-by: Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org --- example/generator/odp_generator.c| 2 +- example/ipsec/odp_ipsec.c| 8 platform/linux-generic/include/api/odp_packet.h | 9 - platform/linux-generic/include/odp_packet_internal.h | 9 + platform/linux-generic/odp_crypto.c | 4 ++-- platform/linux-generic/odp_packet.c | 2 +- platform/linux-generic/odp_packet_io.c | 6 +++--- test/validation/buffer/odp_packet_test.c | 2 +- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 547366a..5df8868 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -448,7 +448,7 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) odp_atomic_inc_u64(counters.ip); rlen += sprintf(msg, receive Packet proto:IP ); - buf = odp_buffer_addr(odp_packet_to_buffer(pkt)); + buf = odp_packet_data(pkt); ip = (odph_ipv4hdr_t *)(buf + odp_packet_l3_offset(pkt)); rlen += sprintf(msg + rlen, id %d , odp_be_to_cpu_16(ip-id)); diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index a59794a..9fdaeab 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -740,7 +740,7 @@ pkt_disposition_e do_ipsec_in_classify(odp_packet_t pkt, *skip = FALSE; if (odp_crypto_operation(params, posted, -odp_packet_to_buffer(pkt))) { + odp_buffer_from_event(odp_packet_to_event(pkt { abort(); } return (posted) ? PKT_POSTED : PKT_CONTINUE; @@ -766,7 +766,7 @@ pkt_disposition_e do_ipsec_in_finish(odp_packet_t pkt, int trl_len = 0; /* Check crypto result */ - event = odp_packet_to_buffer(pkt); + event = odp_buffer_from_event(odp_packet_to_event(pkt)); odp_crypto_get_operation_compl_status(event, auth_rc, cipher_rc); if (!is_crypto_compl_status_ok(cipher_rc)) return PKT_DROP; @@ -974,7 +974,7 @@ pkt_disposition_e do_ipsec_out_seq(odp_packet_t pkt, /* Issue crypto request */ if (odp_crypto_operation(ctx-ipsec.params, posted, -odp_packet_to_buffer(pkt))) { + odp_buffer_from_event(odp_packet_to_event(pkt { abort(); } return (posted) ? PKT_POSTED : PKT_CONTINUE; @@ -998,7 +998,7 @@ pkt_disposition_e do_ipsec_out_finish(odp_packet_t pkt, odph_ipv4hdr_t *ip; /* Check crypto result */ - event = odp_packet_to_buffer(pkt); + event = odp_buffer_from_event(odp_packet_to_event(pkt)); odp_crypto_get_operation_compl_status(event, auth_rc, cipher_rc); if (!is_crypto_compl_status_ok(cipher_rc)) return PKT_DROP; diff --git a/platform/linux-generic/include/api/odp_packet.h b/platform/linux-generic/include/api/odp_packet.h index 92b6016..fa3e321 100644 --- a/platform/linux-generic/include/api/odp_packet.h +++ b/platform/linux-generic/include/api/odp_packet.h @@ -105,15 +105,6 @@ int
Re: [lng-odp] [PATCH] api: unify @return/@retval descriptions and return types
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, January 27, 2015 2:44 PM To: Bill Fischofer Cc: LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH] api: unify @return/@retval descriptions and return types On 27 January 2015 at 12:52, Bill Fischofer bill.fischo...@linaro.org wrote: I think it's good practice for functions to be robust in parameter handling unless they are expected to be used in performance paths. That's the reason why we've said that things like odp_buffer_addr() etc. have undefined behavior if they're passed invalid handles. But shm and pools are things that will typically get set up once during init, and seldom changed (maybe as part of reconfig) so the performance argument is less compelling there. I agree but this is not only about performance. Sprinkling the API's with error codes also forces the user to check those return values which complicates the application logic and probably creates code that will be difficult to get test coverage for. I have a lot of experience with API's that cannot return errors and I really prefer this style. Applications becomes so much simpler. Why should odp_shm_addr() be allowed to return an error code? Most implementations most likely will not even utilize the possibility and applications will not expect an error to happen and so might not even check the return value. How often do you check the return value of printf or close? Just because the functions do not have to check for valid parameters so that they can return corresponding error indications does not mean that implementations cannot and should not check for (in)valid parameters. But if invalid parameters are detected, the error has to be signaled in some other way, e.g. by calling ODP_ABORT (as ODP doesn't have any error handling mechanism for users to hook into). The timer implementation always checks timer pool handles and timer handles for validity. As ODP_ABORT (which does not return control to the caller) is used to report invalid parameters, the applications cannot rely on the ODP implementation handling invalid parameters. In another implementation, the checks could be removed with no change of semantics. As you say that should only be considered for truly performance critical functions. I have also experience with (the same) API that cannot return errors and didn't like it always. Sometimes application has better idea about the severity of the failure and could prefer to back off or retry (the API call), instead of just crashing right there. Also if every call fails through an error handler, it will contain large part of the application logic (without exact information about the error context). There's a difference if a call failed due to a corrupt handle, or if the resource was freed/become unusable in parallel (timing / status failure). The first, should crash right there, the second could return failure (and application could decide what to do next). -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] questions on odp_generator - threads vs. processes
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Monday, January 26, 2015 2:52 PM To: Maxim Uvarov Cc: LNG ODP Mailman List Subject: Re: [lng-odp] questions on odp_generator - threads vs. processes On 26 January 2015 at 13:23, Maxim Uvarov maxim.uva...@linaro.org wrote: Ola, I think it's was there since first version and copy pasted from first example app. In this particular case arguments can be simple allocated with malloc. And this memory will be visible, does not matter fork() or pthread_create() will be used after. Yes it seems like overkill to allocate all memory as shared memory regions (which have some overhead, especially in the kernel). Unless we create a malloc-like memory allocator and make it use a shared memory region. Petri once claimed that ODP implementations need to use shared memory regions in order to support multi-process model. But there is also a fair amount of static data used (e.g. for lookup from handle to e.g. buffer or timer pool etc). I assume only in the case of using fork will the multi-process model work. An application should use shared memory if it needs to be portable across pthreads/forked-processes/multi-processes/bare metal (that would be a nice demo / example). Some implementations could support multi-process model (e.g. DPDK) or bare metal, although linux-generic does not do that currently. -Petri regards, Maxim. On 01/26/2015 02:47 PM, Ola Liljedahl wrote: /* Reserve memory for args from shared mem */ shm = odp_shm_reserve(shm_args, sizeof(args_t), ODP_CACHE_LINE_SIZE, 0); if (shm == ODP_SHM_INVALID) { EXAMPLE_ERR(Error: shared mem alloc failed.\n); exit(EXIT_FAILURE); } args = odp_shm_addr(shm); Why is odp_generator allocating argument storage as shared memory? args might be shared by the worker threads (or processes?). But some of the argument values are allocated through malloc/calloc which seems to defeat the goal of worker processes (instead of worker threads). The generator is always creating worker threads and seems not to have any option for worker processes. odp_cpumask_zero(thd_mask); odp_cpumask_set(thd_mask, cpu); odph_linux_pthread_create(thread_tbl[i], thd_mask, thr_run_func, args-thread[i]); cpu = odp_cpumask_next(cpumask, cpu); When parsing the command line arguments in the main thread: /* allocate storage for the if names */ appl_args-if_names = calloc(appl_args-if_count, sizeof(char *)); Setting up per-thread arguments: args-thread[i].pktio_dev = args-appl.if_names[if_idx] In the worker threads: pktio = odp_pktio_lookup(thr_args-pktio_dev); /** * Thread specific arguments */ typedef struct { char *pktio_dev;/** Interface name to use */ odp_buffer_pool_t pool; /** Buffer pool for packet IO */ int mode; /** Thread mode */ } thread_args_t; ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv5] hugepages: align mmap size for hugepages
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Maxim Uvarov Sent: Monday, January 26, 2015 2:13 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv5] hugepages: align mmap size for hugepages In case of hugepages munmap requires size aligned to page. Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- v5: - fix alloc_hp_size define (somehow arm gcc finds that it can be uninitialized; - remove goto and make if cases more readable; platform/linux-generic/odp_shared_memory.c | 73 +++-- - test/validation/odp_shm.c | 4 ++ 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux- generic/odp_shared_memory.c index 23a9ceb..4689c5d 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -179,27 +179,32 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, int map_flag = MAP_SHARED; /* If already exists: O_EXCL: error, O_TRUNC: truncate to zero */ int oflag = O_RDWR | O_CREAT | O_TRUNC; - uint64_t alloc_size = size + align; + uint64_t alloc_size; uint64_t page_sz, huge_sz; + int ret; +#ifdef MAP_HUGETLB + int need_huge_page = 0; + uint64_t alloc_hp_size; +#endif - huge_sz = odp_sys_huge_page_size(); page_sz = odp_sys_page_size(); + alloc_size = size + align; + +#ifdef MAP_HUGETLB + huge_sz = odp_sys_huge_page_size(); + need_huge_page = (huge_sz alloc_size page_sz); + /* munmap for huge pages requires sizes round up by page */ + alloc_hp_size = (size + align + (huge_sz - 1)) (-huge_sz); +#endif if (flags ODP_SHM_PROC) { /* Creates a file to /dev/shm */ fd = shm_open(name, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd == -1) { ODP_DBG(odp_shm_reserve: shm_open failed\n); return ODP_SHM_INVALID; } - - if (ftruncate(fd, alloc_size) == -1) { - ODP_DBG(odp_shm_reserve: ftruncate failed\n); - return ODP_SHM_INVALID; - } - } else { map_flag |= MAP_ANONYMOUS; } @@ -230,32 +235,47 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, block = odp_shm_tbl-block[i]; block-hdl = to_handle(i); - block-huge = 0; addr= MAP_FAILED; #ifdef MAP_HUGETLB /* Try first huge pages */ - if (huge_sz alloc_size page_sz) { - addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, - map_flag | MAP_HUGETLB, fd, 0); + if (need_huge_page) { + ret = 0; + if (flags ODP_SHM_PROC) + ret = ftruncate(fd, alloc_hp_size); It's an error if ftruncate fails, so just return SHM_INVALID. if (ftruncate(fd, alloc_hp_size) == -1) { ODP_DBG(odp_shm_reserve: ftruncate failed\n); return ODP_SHM_INVALID; } + + if (ret == 0) { This if-clause can be then removed... + addr = mmap(NULL, alloc_hp_size, PROT_READ | PROT_WRITE, + map_flag | MAP_HUGETLB, fd, 0); + if (addr == MAP_FAILED) { + ODP_DBG(odp_shm_reserve: mmap HP failed\n); Depending on system / config there may be only e.g. 4 huge pages available. So it may be pretty common that you run out of huge pages and use normal pages instead. I'd leave the warning out from here. + } else { + block-alloc_size = alloc_hp_size; + block-huge = 1; + block-page_sz = huge_sz; + } + } } #endif /* Use normal pages for small or failed huge page allocations */ if (addr == MAP_FAILED) { - addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, - map_flag, fd, 0); - block-page_sz = page_sz; - } else { - block-huge= 1; - block-page_sz = huge_sz; - } - - if (addr == MAP_FAILED) { - /* Alloc failed */ - odp_spinlock_unlock(odp_shm_tbl-lock); - ODP_DBG(odp_shm_reserve: mmap failed\n); - return ODP_SHM_INVALID; + ret = 0; + if (flags ODP_SHM_PROC) + ret = ftruncate(fd, alloc_size); Same thing, return SHM_INVALID on fruncate failure. -Petri + if (ret == 0) { + addr = mmap(NULL,
Re: [lng-odp] questions on odp_generator - threads vs. processes
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Monday, January 26, 2015 3:37 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: Maxim Uvarov; LNG ODP Mailman List Subject: Re: [lng-odp] questions on odp_generator - threads vs. processes On 26 January 2015 at 14:27, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Monday, January 26, 2015 2:52 PM To: Maxim Uvarov Cc: LNG ODP Mailman List Subject: Re: [lng-odp] questions on odp_generator - threads vs. processes On 26 January 2015 at 13:23, Maxim Uvarov maxim.uva...@linaro.org wrote: Ola, I think it's was there since first version and copy pasted from first example app. In this particular case arguments can be simple allocated with malloc. And this memory will be visible, does not matter fork() or pthread_create() will be used after. Yes it seems like overkill to allocate all memory as shared memory regions (which have some overhead, especially in the kernel). Unless we create a malloc-like memory allocator and make it use a shared memory region. Petri once claimed that ODP implementations need to use shared memory regions in order to support multi-process model. But there is also a fair amount of static data used (e.g. for lookup from handle to e.g. buffer or timer pool etc). I assume only in the case of using fork will the multi-process model work. An application should use shared memory if it needs to be portable across pthreads/forked-processes/multi-processes/bare metal (that would be a nice demo / example). Some implementations could support multi-process model (e.g. DPDK) or bare metal, although linux-generic does not do that currently. What is not clear is if this portability (to bare metal and/or multi-process environments) comes from (specifically) using ODP shared memory or it comes from avoiding using non-portable API's (like malloc except malloc is part of StdC so should always be available if you have a StdC compiler which is required by ODP anyway) and only use ODP functionality. You cannot allocate shared memory with malloc on multi-process model, or inside forked processes (after the fork) and on bare metal it depends (if it's per core or shared). Odp_shm_reserve() would work in all of those cases. -Petri -Petri regards, Maxim. On 01/26/2015 02:47 PM, Ola Liljedahl wrote: /* Reserve memory for args from shared mem */ shm = odp_shm_reserve(shm_args, sizeof(args_t), ODP_CACHE_LINE_SIZE, 0); if (shm == ODP_SHM_INVALID) { EXAMPLE_ERR(Error: shared mem alloc failed.\n); exit(EXIT_FAILURE); } args = odp_shm_addr(shm); Why is odp_generator allocating argument storage as shared memory? args might be shared by the worker threads (or processes?). But some of the argument values are allocated through malloc/calloc which seems to defeat the goal of worker processes (instead of worker threads). The generator is always creating worker threads and seems not to have any option for worker processes. odp_cpumask_zero(thd_mask); odp_cpumask_set(thd_mask, cpu); odph_linux_pthread_create(thread_tbl[i], thd_mask, thr_run_func, args- thread[i]); cpu = odp_cpumask_next(cpumask, cpu); When parsing the command line arguments in the main thread: /* allocate storage for the if names */ appl_args-if_names = calloc(appl_args-if_count, sizeof(char *)); Setting up per-thread arguments: args-thread[i].pktio_dev = args-appl.if_names[if_idx] In the worker threads: pktio = odp_pktio_lookup(thr_args-pktio_dev); /** * Thread specific arguments */ typedef struct { char *pktio_dev;/** Interface name to use */ odp_buffer_pool_t pool; /** Buffer pool for packet IO */ int mode; /** Thread mode */ } thread_args_t; ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing
Re: [lng-odp] [PATCHv4 3/3] hugepages: align mmap size for hugepages
-Original Message- From: ext Maxim Uvarov [mailto:maxim.uva...@linaro.org] Sent: Friday, January 23, 2015 6:25 PM To: Savolainen, Petri (NSN - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv4 3/3] hugepages: align mmap size for hugepages On 01/23/2015 04:54 PM, Savolainen, Petri (NSN - FI/Espoo) wrote: More readable code with one if-clause and no goto: if (fd != -1 ftruncate(fd, alloc_hp_size) != -1) { addr = mmap(NULL, alloc_hp_size, PROT_READ | PROT_WRITE, map_flag | MAP_HUGETLB, fd, 0); } Petri, no that will not work. fd is only if ODP_SHM_PROC. But mmap hugepages should be done not depending ODP_SHM_PROC is provided or not. Maxim. OK. Anyway, I think it's better to return error if ftruncate() fails than try to recover from it. That error return would eliminate also need for that goto, which is good for readability. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v4 00/16] Event introduction
After applying the shm_free bug fix, I can successfully run validation test suite in my system - both for the v0.9 and this patches on top of that pass (in each step). Didn’t see any failure (“make check”, odp_buffer and odp_timer) on any of the patches. I can add 17th patch that modify scheduler implementation on those parts that exceed 80 chars. -Petri From: ext Bill Fischofer [mailto:bill.fischo...@linaro.org] Sent: Sunday, January 25, 2015 12:57 AM To: Petri Savolainen Cc: LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH v4 00/16] Event introduction I don't see any difference between this series and the v3 series. Patch 0005 doesn't apply because it conflicts with an odp_schedule.c change made by update https://patches.linaro.org/43237/ that was merged in 0.9.0. I've posted a v5 level of this section that resolves that. Patches 0002, 0004, 0005, 0007, and 0008 fail checkpatch due to 80 char line lengths. Some of these are resolved in subsequent patches, but odp_schedule.c still has this problem after the last patch is applied. We either need to change our policy on this globally or this series needs to be fixed to be in conformance with the agreed-to checkpatch rules. I would vote for the former, but I'm in the minority. I'm still seeing the odp_timer test fail after the application of patch 0013. All tests pass with the entire series applied, however. I'm not sure why this is the case and I don't think it's critical. With these caveats, for this series: Reviewed-and-tested-by: Bill Fischofer bill.fischo...@linaro.orgmailto:bill.fischo...@linaro.org On Fri, Jan 23, 2015 at 5:42 AM, Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org wrote: This patch set introduces odp_event_t. It replaces odp_buffer_t in many places with odp_event_t. Events are the objects that are transimitted by and scheduled from queues. Event is the new super class for various events (buffers, packets, timeouts, etc). Various event types can be converted to odp_event_t (and back), but not to another event type. Buffer pool is also changed to a generic pool. Pool and event types have been separated. There are matching pool types for buffer, packet and timeout events (as buffer types before). Later on, there can be event types without a matching pool type, and pool types without a matching event type. Some lines are over 80 chars. Those are mainly caused by temporary event - buffer, packet - event - buffer conversions and should be cleaned up from the implementation. This patch set does minimal implementation changes. v2 * Updated validation test suite to use events v3 * Fixed bugs that crashed validation test cases * Breaked over 80 char lines where possible (without re-implementation) v4 * Fixed odp_buffer test to not test timeout alloc before it's implemented * Corrected doxygen warnings Petri Savolainen (16): api: event: Add odp_event_t api: event: odp_schedule and odp_queue_enq api: event: schedule_multi and queue_enq_multi api: event: odp_queue_deq api: event: odp_queue_deq_multi api: buffer: Removed odp_buffer_type api: packet: Removed odp_packet_to_buffer api: packet: Removed odp_packet_from_buffer api: timer: Use odp_event_t instead of odp_buffer_t api: crypto: Use odp_event_t instead of odp_buffer_t linux-generic: crypto: Use packet alloc for packet api: buffer_pool: Rename odp_buffer_pool.h to odp_pool.h api: pool: Rename pool params and remove buffer types api: pool: Rename odp_buffer_pool_ to odp_pool_ api: config: Renamed ODP_CONFIG_BUFFER_POOLS api: timer: Added timeout alloc and free example/generator/odp_generator.c | 38 ++-- example/ipsec/odp_ipsec.c | 70 +++ example/ipsec/odp_ipsec_cache.c| 4 +- example/ipsec/odp_ipsec_cache.h| 2 +- example/ipsec/odp_ipsec_loop_db.c | 2 +- example/ipsec/odp_ipsec_loop_db.h | 12 +- example/ipsec/odp_ipsec_stream.c | 20 +- example/ipsec/odp_ipsec_stream.h | 2 +- example/l2fwd/odp_l2fwd.c | 28 +-- example/packet/odp_pktio.c | 29 ++- example/timer/odp_timer_test.c | 76 platform/linux-generic/Makefile.am | 4 +- platform/linux-generic/include/api/odp.h | 3 +- platform/linux-generic/include/api/odp_buffer.h| 41 ++-- .../linux-generic/include/api/odp_buffer_pool.h| 177 - .../linux-generic/include/api/odp_classification.h | 2 +- platform/linux-generic/include/api/odp_config.h| 4 +- platform/linux-generic/include/api/odp_crypto.h| 16 +- platform/linux-generic/include/api/odp_event.h | 59 ++ platform/linux-generic/include/api/odp_packet.h| 27 +-- platform/linux-generic/include/api/odp_packet_io.h | 4 +-
Re: [lng-odp] [PATCHv4 3/3] hugepages: align mmap size for hugepages
Functionality OK. I'd reorganize the code a bit. See under. Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Maxim Uvarov Sent: Friday, January 23, 2015 2:35 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv4 3/3] hugepages: align mmap size for hugepages In case of hugepages munmap requires size aligned to page. Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- v4: if alloc huge pages failed fall back to normal pages with original size. platform/linux-generic/odp_shared_memory.c | 43 + - test/validation/odp_shm.c | 4 +++ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux- generic/odp_shared_memory.c index 23a9ceb..2004f30 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -179,27 +179,32 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, int map_flag = MAP_SHARED; /* If already exists: O_EXCL: error, O_TRUNC: truncate to zero */ int oflag = O_RDWR | O_CREAT | O_TRUNC; - uint64_t alloc_size = size + align; + uint64_t alloc_size; + uint64_t alloc_hp_size; uint64_t page_sz, huge_sz; + int need_huge_page = 0; - huge_sz = odp_sys_huge_page_size(); page_sz = odp_sys_page_size(); + alloc_size = size + align; + +#ifdef MAP_HUGETLB + huge_sz = odp_sys_huge_page_size(); + need_huge_page = (huge_sz alloc_size page_sz); + if (need_huge_page) { + /* munmap for huge pages requires sizes round up by page */ + alloc_hp_size = (size + align + (huge_sz - 1)) +(-huge_sz); + } +#endif if (flags ODP_SHM_PROC) { /* Creates a file to /dev/shm */ fd = shm_open(name, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd == -1) { ODP_DBG(odp_shm_reserve: shm_open failed\n); return ODP_SHM_INVALID; } - - if (ftruncate(fd, alloc_size) == -1) { - ODP_DBG(odp_shm_reserve: ftruncate failed\n); - return ODP_SHM_INVALID; - } - } else { map_flag |= MAP_ANONYMOUS; } @@ -235,18 +240,31 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, #ifdef MAP_HUGETLB /* Try first huge pages */ - if (huge_sz alloc_size page_sz) { - addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, + if (need_huge_page) { + if (flags ODP_SHM_PROC) { + if (ftruncate(fd, alloc_hp_size) == -1) + goto normal_pages; + } + addr = mmap(NULL, alloc_hp_size, PROT_READ | PROT_WRITE, map_flag | MAP_HUGETLB, fd, 0); } +normal_pages: More readable code with one if-clause and no goto: if (fd != -1 ftruncate(fd, alloc_hp_size) != -1) { addr = mmap(NULL, alloc_hp_size, PROT_READ | PROT_WRITE, map_flag | MAP_HUGETLB, fd, 0); } #endif - /* Use normal pages for small or failed huge page allocations */ if (addr == MAP_FAILED) { + if (flags ODP_SHM_PROC) { + if (ftruncate(fd, alloc_size) == -1) { + odp_spinlock_unlock(odp_shm_tbl-lock); + ODP_DBG(odp_shm_reserve: ftruncate failed\n); + return ODP_SHM_INVALID; + } + } Same reorganization here. -Petri addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, map_flag, fd, 0); + block-alloc_size = alloc_size; block-page_sz = page_sz; } else { + block-alloc_size = alloc_hp_size; block-huge= 1; block-page_sz = huge_sz; } @@ -267,7 +285,6 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, block-name[ODP_SHM_NAME_LEN - 1] = 0; block-size = size; block-align = align; - block-alloc_size = alloc_size; block-flags = flags; block-fd = fd; block-addr = addr; diff --git a/test/validation/odp_shm.c b/test/validation/odp_shm.c index c26925b..4b1a38e 100644 --- a/test/validation/odp_shm.c +++ b/test/validation/odp_shm.c @@ -32,7 +32,11 @@ static void *run_shm_thread(void *arg) CU_ASSERT(0 == info.flags); CU_ASSERT(test_shared_data == info.addr);
Re: [lng-odp] [PATCHv3] linux-generic: Add odp_errno and adapt packet_io and timer implementations to use it
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mario Torrecillas Rodriguez Sent: Wednesday, January 21, 2015 6:14 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv3] linux-generic: Add odp_errno and adapt packet_io and timer implementations to use it Added odp_errno.c and odp_errno.h Changed odp_packet_io and odp_timer to use it. Signed-off-by: Mario Torrecillas Rodriguez mario.torrecillasrodrig...@arm.com --- (This code contribution is provided under the terms of agreement LES-LTM- 21309) Changes from previous version: * Changed doxygen comment * Removed errno.h from API file platform/linux-generic/Makefile.am | 2 + platform/linux-generic/include/api/odp_errno.h | 60 ++ platform/linux-generic/include/odp_internal.h | 1 + platform/linux-generic/odp_errno.c | 35 +++ platform/linux-generic/odp_packet_io.c | 2 +- platform/linux-generic/odp_packet_socket.c | 17 platform/linux-generic/odp_timer.c | 5 ++- 7 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 platform/linux-generic/include/api/odp_errno.h create mode 100644 platform/linux-generic/odp_errno.c diff --git a/platform/linux-generic/Makefile.am b/platform/linux- generic/Makefile.am index a699ea6..1b71b71 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -19,6 +19,7 @@ include_HEADERS = \ $(top_srcdir)/platform/linux- generic/include/api/odp_cpumask.h \ $(top_srcdir)/platform/linux- generic/include/api/odp_crypto.h \ $(top_srcdir)/platform/linux-generic/include/api/odp_debug.h \ + $(top_srcdir)/platform/linux-generic/include/api/odp_errno.h \ $(top_srcdir)/platform/linux-generic/include/api/odp_hints.h \ $(top_srcdir)/platform/linux-generic/include/api/odp_init.h \ $(top_srcdir)/platform/linux- generic/include/api/odp_packet_flags.h \ @@ -80,6 +81,7 @@ __LIB__libodp_la_SOURCES = \ odp_classification.c \ odp_cpumask.c \ odp_crypto.c \ +odp_errno.c \ odp_init.c \ odp_impl.c \ odp_linux.c \ diff --git a/platform/linux-generic/include/api/odp_errno.h b/platform/linux-generic/include/api/odp_errno.h new file mode 100644 index 000..0157720 --- /dev/null +++ b/platform/linux-generic/include/api/odp_errno.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP errno API + */ + +#ifndef ODP_ERRNO_H_ +#define ODP_ERRNO_H_ + +#ifdef __cplusplus +extern C { +#endif + +/** +* Return latest ODP errno +* +* @return ODP errno +* @retval 0 No error +*/ +int odp_errno(void); + +/** +* Set ODP errno to zero +*/ +void odp_errno_zero(void); + +/** +* Print ODP errno +* +* Interprets the value of ODP errno as an error message, and prints it, +* optionally preceding it with the custom message specified in str. +* +* @param str NULL, or pointer to the string to be appended +*/ +void odp_errno_print(const char *str); + +/** +* Error message string +* +* Interprets the value of ODP errno, generating a string with a +* message that describes the error. +* It uses the system definition of errno. +* +* @param errnum Error code +* +* @retval Pointer to the string +*/ +const char *odp_errno_str(int errnum); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index 549d406..b953163 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -18,6 +18,7 @@ extern C { #endif +extern __thread int __odp_errno; int odp_system_info_init(void); diff --git a/platform/linux-generic/odp_errno.c b/platform/linux- generic/odp_errno.c new file mode 100644 index 000..ba080e7 --- /dev/null +++ b/platform/linux-generic/odp_errno.c @@ -0,0 +1,35 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include odp_errno.h +#include odp_internal.h +#include string.h +#include stdio.h + +__thread int __odp_errno; + +int odp_errno(void) +{ + return __odp_errno; +} + +void odp_errno_zero(void) +{ + __odp_errno = 0; +} + +void odp_errno_print(const char *str) +{ + if (str != NULL) + printf(%s , str); + + printf(%s\n, strerror(__odp_errno)); +} + +const char
Re: [lng-odp] [PATCHv2 3/3] hugepages: align mmap size for hugepages
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Maxim Uvarov Sent: Thursday, January 22, 2015 5:45 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv2 3/3] hugepages: align mmap size for hugepages In case of hugepages munmap requires size aligned to page. Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- platform/linux-generic/odp_shared_memory.c | 12 ++-- test/validation/odp_shm.c | 4 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux- generic/odp_shared_memory.c index 23a9ceb..7adbe52 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -179,12 +179,20 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, int map_flag = MAP_SHARED; /* If already exists: O_EXCL: error, O_TRUNC: truncate to zero */ int oflag = O_RDWR | O_CREAT | O_TRUNC; - uint64_t alloc_size = size + align; + uint64_t alloc_size; uint64_t page_sz, huge_sz; - huge_sz = odp_sys_huge_page_size(); page_sz = odp_sys_page_size(); +#ifdef MAP_HUGETLB + huge_sz = odp_sys_huge_page_size(); + /* munmap for huge pages requires sizes round up by page */ + alloc_size = (size + align + (huge_sz - 1)) +(-huge_sz); Huge pages should be used only after certain size limit. Those are scarce resource (much less huge pages than normal 4 kB pages). Currently huge pages are used only if application tries to reserve more than a (4kB) page size. #ifdef MAP_HUGETLB /* Try first huge pages */ if (huge_sz alloc_size page_sz) { addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, map_flag | MAP_HUGETLB, fd, 0); } #endif So, alloc_size rounding up should go inside that if clause. -Petri +#else + alloc_size = size + align; +#endif + if (flags ODP_SHM_PROC) { /* Creates a file to /dev/shm */ fd = shm_open(name, oflag, diff --git a/test/validation/odp_shm.c b/test/validation/odp_shm.c index c26925b..918a77b 100644 --- a/test/validation/odp_shm.c +++ b/test/validation/odp_shm.c @@ -32,7 +32,11 @@ static void *run_shm_thread(void *arg) CU_ASSERT(0 == info.flags); CU_ASSERT(test_shared_data == info.addr); CU_ASSERT(sizeof(test_shared_data_t) = info.size); +#ifdef MAP_HUGETLB CU_ASSERT(odp_sys_page_size() == info.page_size); +#else + CU_ASSERT(odp_sys_huge_page_size() == info.page_size); +#endif odp_shm_print_all(); fflush(stdout); -- 1.8.5.1.163.gd7aced9 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] linux-generic: shm fix unmap for hugepages
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Maxim Uvarov Sent: Thursday, January 22, 2015 5:01 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH] linux-generic: shm fix unmap for hugepages In case of hugepages unmap has to be done with address aligned to page size. Also unmap() has to be done for address returned by mmap(), not for aligned address after that. To reproduce original bug run: echo 4096 /proc/sys/vm/nr_hugepages make check Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- platform/linux-generic/odp_shared_memory.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux- generic/odp_shared_memory.c index 99c5b40..51eba02 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -134,8 +134,14 @@ int odp_shm_free(odp_shm_t shm) odp_spinlock_lock(odp_shm_tbl-lock); shm_block = odp_shm_tbl-block[i]; +#ifdef MAP_HUGETLB + /* round up alloc size by page */ + alloc_size = (shm_block-size + (shm_block-page_sz - 1)) +(-shm_block-page_sz); Could you rebase this on top of my two patches. And then move this calculation to shm_reserve() side, so that the same size gets allocated, saved into block-alloc_size, and the freed here. -Petri +#else alloc_size = shm_block-size + shm_block-align; - ret = munmap(shm_block-addr, alloc_size); +#endif + ret = munmap(shm_block-addr_orig, alloc_size); if (0 != ret) { ODP_DBG(odp_shm_free: munmap failed\n); odp_spinlock_unlock(odp_shm_tbl-lock); -- 1.8.5.1.163.gd7aced9 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv2] linux-generic: Add odp_errno and adapt packet_io and timer implementations to use it
-Original Message- From: ext Mario Torrecillas Rodriguez [mailto:mario.torrecillasrodrig...@arm.com] Sent: Tuesday, January 20, 2015 5:08 PM To: Savolainen, Petri (NSN - FI/Espoo); lng-odp@lists.linaro.org Subject: Re: [lng-odp] [PATCHv2] linux-generic: Add odp_errno and adapt packet_io and timer implementations to use it Thanks for the review Petri. A short comment inlined. On 20/01/2015 13:38, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: --- /dev/null +++ b/platform/linux-generic/include/api/odp_errno.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP errno API + */ + +#ifndef ODP_ERRNO_H_ +#define ODP_ERRNO_H_ + +#ifdef __cplusplus +extern C { +#endif + +#include errno.h This should be removed from API file (only implementation needs it). That¹s there so that both ODP libraries and applications using them can see the errno error definitions. Otherwise things like ³EEXIST² etc will give compile errors. The alternative would be to include both odp_errno.h and errno.h in implementation files and applications. Which option should we go with? I'd leave it out for now. The problem is that errno values are system specific (posix/linux/bare metal/?). The mechanism is portable (read/zero/print ODP errno), values are not. If user needs to include a system errno header by himself, that fact is highlighted. As we are not (yet) specifying a portable range of errnos, so user can more or less log/report the value and not make a decision based on it. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2 4/4] api: move loging out of odp_debug
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mike Holmes Sent: Wednesday, January 21, 2015 1:38 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v2 4/4] api: move loging out of odp_debug Only odp_init needs the logging definitions so remove them from odp_debug.h Signed-off-by: Mike Holmes mike.hol...@linaro.org --- platform/linux-generic/include/api/odp_debug.h | 32 platform/linux-generic/include/api/odp_init.h | 41 +- platform/linux-generic/include/odp_internal.h | 2 +- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/platform/linux-generic/include/api/odp_debug.h b/platform/linux-generic/include/api/odp_debug.h index 4c32500..ce07e85 100644 --- a/platform/linux-generic/include/api/odp_debug.h +++ b/platform/linux-generic/include/api/odp_debug.h @@ -48,38 +48,6 @@ extern C { #define _ODP_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) /** - * ODP log level. - */ -typedef enum odp_log_level { - ODP_LOG_DBG, - ODP_LOG_ERR, - ODP_LOG_UNIMPLEMENTED, - ODP_LOG_ABORT, - ODP_LOG_PRINT -} odp_log_level_e; - -/** - * ODP log function - * - * Instead of direct prints to stdout/stderr all logging in ODP implementation - * should be done via this function or its wrappers. - * ODP platform MUST provide a default *weak* implementation of this function. - * Application MAY override the function if needed by providing a strong - * function. - * - * @param[in] level Log level - * @param[in] fmt printf-style message format - * - * @return The number of characters logged if succeeded. Otherwise returns - * a negative number. - */ -extern int odp_override_log(odp_log_level_e level, const char *fmt, ...); - - -/** Replaceable logging function */ -typedef int (*odp_log_func_t)(odp_log_level_e level, const char *fmt, ...); - -/** * @} */ diff --git a/platform/linux-generic/include/api/odp_init.h b/platform/linux-generic/include/api/odp_init.h index 73c4a3b..ac856df 100644 --- a/platform/linux-generic/include/api/odp_init.h +++ b/platform/linux-generic/include/api/odp_init.h @@ -29,13 +29,52 @@ extern C { #include odp_std_types.h -#include odp_debug.h /** @defgroup odp_initialization ODP INITIALIZATION * Initialisation operations. * @{ */ +/** + * ODP log level. + */ +typedef enum odp_log_level { + ODP_LOG_DBG, + ODP_LOG_ERR, + ODP_LOG_UNIMPLEMENTED, + ODP_LOG_ABORT, + ODP_LOG_PRINT +} odp_log_level_e; + +/** + * ODP log function + * + * Instead of direct prints to stdout/stderr all logging in an ODP + * implementation should be done via this function or its wrappers. + * + * The application can provide this function to the ODP implementation in two + * ways: + * + * - A callback passed in via in odp_init_t and odp_init_global() + * - By overriding the ODP implementation default log function + * odp_override_log(). + * + * @warning The latter option is less portable and GNU linker dependent + * (utilizes function attribute weak). If both are defined, the odp_init_t + * function pointer has priority over the override function. + * + * @param[in] level Log level + * @param[in] fmt printf-style message format + * + * @return The number of characters logged if succeeded. Otherwise returns + * a negative number. + */ +int odp_override_log(odp_log_level_e level, const char *fmt, ...); + + +/** Replaceable logging function */ +typedef int (*odp_log_func_t)(odp_log_level_e level, const char *fmt, ...); + /** ODP initialization data. * Data that is required to initialize the ODP API with the * application specific data such as specifying a logging callback, the log diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index 7401a30..07c9f60 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -18,7 +18,7 @@ extern C { #endif -#include odp_debug.h +#include odp_init.h struct odp_global_data { odp_log_func_t log_fn; -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 4/4] api: move loging out of odp_debug
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mike Holmes Sent: Monday, January 19, 2015 3:56 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH 4/4] api: move loging out of odp_debug Only odp_init needs the logging definitions so remove them from odp_debug.h Signed-off-by: Mike Holmes mike.hol...@linaro.org --- platform/linux-generic/include/api/odp_debug.h | 32 - -- platform/linux-generic/include/api/odp_init.h | 36 +- platform/linux-generic/include/odp_internal.h | 2 +- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/platform/linux-generic/include/api/odp_debug.h b/platform/linux-generic/include/api/odp_debug.h index 4c32500..ce07e85 100644 --- a/platform/linux-generic/include/api/odp_debug.h +++ b/platform/linux-generic/include/api/odp_debug.h @@ -48,38 +48,6 @@ extern C { #define _ODP_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) /** - * ODP log level. - */ -typedef enum odp_log_level { - ODP_LOG_DBG, - ODP_LOG_ERR, - ODP_LOG_UNIMPLEMENTED, - ODP_LOG_ABORT, - ODP_LOG_PRINT -} odp_log_level_e; - -/** - * ODP log function - * - * Instead of direct prints to stdout/stderr all logging in ODP implementation - * should be done via this function or its wrappers. - * ODP platform MUST provide a default *weak* implementation of this function. - * Application MAY override the function if needed by providing a strong - * function. - * - * @param[in] level Log level - * @param[in] fmt printf-style message format - * - * @return The number of characters logged if succeeded. Otherwise returns - * a negative number. - */ -extern int odp_override_log(odp_log_level_e level, const char *fmt, ...); - - -/** Replaceable logging function */ -typedef int (*odp_log_func_t)(odp_log_level_e level, const char *fmt, ...); - -/** * @} */ diff --git a/platform/linux-generic/include/api/odp_init.h b/platform/linux-generic/include/api/odp_init.h index 73c4a3b..b0ea316 100644 --- a/platform/linux-generic/include/api/odp_init.h +++ b/platform/linux-generic/include/api/odp_init.h @@ -29,13 +29,47 @@ extern C { #include odp_std_types.h -#include odp_debug.h /** @defgroup odp_initialization ODP INITIALIZATION * Initialisation operations. * @{ */ +/** + * ODP log level. + */ +typedef enum odp_log_level { + ODP_LOG_DBG, + ODP_LOG_ERR, + ODP_LOG_UNIMPLEMENTED, + ODP_LOG_ABORT, + ODP_LOG_PRINT +} odp_log_level_e; + +/** + * ODP log function + * + * Instead of direct prints to stdout/stderr all logging in ODP implementation + * should be done via this function or its wrappers. I think the callback and weak methods should be documented better, something like this: User can provide this function to the ODP implementation in two ways: as a callback in odp_init_t or by overriding the ODP implementation default log function (odp_override_log()). The latter option is less portable and GNU linker dependent (utilizes function attribute weak). If both are defined, the odp_init_t function pointer has priority over the override function. + * ODP platform MUST provide a default *weak* implementation of this function. + * Application MAY override the function if needed by providing a strong + * function. ... and maybe these notes can be removed then. + * + * @warning The use of the weak replacement is not as portable as using the + * odp_init_global() function parmiters. Typo: parameters -Petri + * + * @param[in] level Log level + * @param[in] fmt printf-style message format + * + * @return The number of characters logged if succeeded. Otherwise returns + * a negative number. + */ +int odp_override_log(odp_log_level_e level, const char *fmt, ...); + + +/** Replaceable logging function */ +typedef int (*odp_log_func_t)(odp_log_level_e level, const char *fmt, ...); + /** ODP initialization data. * Data that is required to initialize the ODP API with the * application specific data such as specifying a logging callback, the log diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index 7401a30..07c9f60 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -18,7 +18,7 @@ extern C { #endif -#include odp_debug.h +#include odp_init.h struct odp_global_data { odp_log_func_t log_fn; -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2 00/16] Event introduction
In my system “make check” seg faults (in odp_init, etc) already with the current code from the repo. -Petri From: ext Mike Holmes [mailto:mike.hol...@linaro.org] Sent: Tuesday, January 20, 2015 3:13 PM To: Petri Savolainen Cc: lng-odp Subject: Re: [lng-odp] [PATCH v2 00/16] Event introduction On 20 January 2015 at 06:17, Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org wrote: This patch set introduces odp_event_t. It replaces odp_buffer_t in many places with odp_event_t. Events are the objects that are transimitted by and scheduled from queues. Event is the new super class for various events (buffers, packets, timeouts, etc). Various event types can be converted to odp_event_t (and back), but not to another event type. Buffer pool is also changed to a generic pool. Pool and event types have been separated. There are matching pool types for buffer, packet and timeout events (as buffer types before). Later on, there can be event types without a matching pool type, and pool types without a matching event type. Some lines are over 80 chars. Those are mainly caused by temporary event - buffer, packet - event - buffer conversions and should be cleaned up from the implementation. This patch set does minimal implementation changes. It is not unreadable to have these changes checkpatch clean, one line that moved to two is very understandable. Also running these patches with make check after applying each one results in failures along the way. Starting fresh and applying all the patches at once and running make check gives PASS: odp_init PASS: odp_queue ../../test-driver: line 107: 18152 Segmentation fault (core dumped) $@ $log_file 21 FAIL: odp_crypto PASS: odp_shm PASS: odp_schedule PASS: odp_pktio_run ../../test-driver: line 107: 21042 Segmentation fault (core dumped) $@ $log_file 21 FAIL: odp_buffer PASS: odp_system FAIL: odp_timer PASS: odp_time PASS: odp_synchronizers make[5]: Entering directory '/home/mike/git/odp/test/validation' make[5]: Nothing to be done for 'all'. make[5]: Leaving directory '/home/mike/git/odp/test/validation' Testsuite summary for OpenDataPlane 0.8.0 # TOTAL: 11 # PASS: 8 # SKIP: 0 # XFAIL: 0 # FAIL: 3 # XPASS: 0 # ERROR: 0 See test/validation/test-suite.log Please report to lng-odp@lists.linaro.orgmailto:lng-odp@lists.linaro.org NB timer is sustable to failure until we get Olas latest code in. Petri Savolainen (16): api: event: Add odp_event_t api: event: odp_schedule and odp_queue_enq api: event: schedule_multi and queue_enq_multi api: event: odp_queue_deq api: event: odp_queue_deq_multi api: buffer: Removed odp_buffer_type api: packet: Removed odp_packet_to_buffer api: packet: Removed odp_packet_from_buffer api: timer: Use odp_event_t instead of odp_buffer_t api: crypto: Use odp_event_t instead of odp_buffer_t linux-generic: crypto: Use packet alloc for packet api: buffer_pool: Rename odp_buffer_pool.h to odp_pool.h api: pool: Rename pool params and remove buffer types api: pool: Rename odp_buffer_pool_ to odp_pool_ api: config: Renamed ODP_CONFIG_BUFFER_POOLS api: timer: Added timeout alloc and free example/generator/odp_generator.c | 38 ++-- example/ipsec/odp_ipsec.c | 70 +++ example/ipsec/odp_ipsec_cache.c| 4 +- example/ipsec/odp_ipsec_cache.h| 2 +- example/ipsec/odp_ipsec_loop_db.c | 2 +- example/ipsec/odp_ipsec_loop_db.h | 12 +- example/ipsec/odp_ipsec_stream.c | 20 +- example/ipsec/odp_ipsec_stream.h | 2 +- example/l2fwd/odp_l2fwd.c | 28 +-- example/packet/odp_pktio.c | 28 +-- example/timer/odp_timer_test.c | 74 platform/linux-generic/Makefile.am | 4 +- platform/linux-generic/include/api/odp.h | 3 +- platform/linux-generic/include/api/odp_buffer.h| 40 ++-- .../linux-generic/include/api/odp_buffer_pool.h| 177 -- .../linux-generic/include/api/odp_classification.h | 2 +- platform/linux-generic/include/api/odp_config.h| 4 +- platform/linux-generic/include/api/odp_crypto.h| 16 +- platform/linux-generic/include/api/odp_event.h | 59 ++ platform/linux-generic/include/api/odp_packet.h| 29 +-- platform/linux-generic/include/api/odp_packet_io.h | 4 +- .../linux-generic/include/api/odp_platform_types.h | 10 +- platform/linux-generic/include/api/odp_pool.h | 202 + platform/linux-generic/include/api/odp_queue.h | 32 ++-- platform/linux-generic/include/api/odp_schedule.h | 32 ++--
Re: [lng-odp] [PATCHv2] linux-generic: Add odp_errno and adapt packet_io and timer implementations to use it
--- /dev/null +++ b/platform/linux-generic/include/api/odp_errno.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP errno API + */ + +#ifndef ODP_ERRNO_H_ +#define ODP_ERRNO_H_ + +#ifdef __cplusplus +extern C { +#endif + +#include errno.h This should be removed from API file (only implementation needs it). + +/** +* Return latest ODP errno +* +* @retval 0 == no error @return ODP errno @retval 0 No error It's likely that == would not look good on Doxygen doc. It's from my mail, sorry about that. -Petri +*/ +int odp_errno(void); + ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2 06/16] api: buffer: Removed odp_buffer_type
Thanks. I'll fix that tomorrow. -Petri -Original Message- From: ext Maxim Uvarov [mailto:maxim.uva...@linaro.org] Sent: Tuesday, January 20, 2015 4:42 PM To: lng-odp@lists.linaro.org; Petri Savolainen Subject: Re: [lng-odp] [PATCH v2 06/16] api: buffer: Removed odp_buffer_type Petri, you just did mistake in test. test/validation/buffer/odp_buffer_pool_test.c pool_alloc_type() case ODP_BUFFER_TYPE_RAW: buf = alloc_buf; case ODP_BUFFER_TYPE_PKT: packet = alloc_packet; Then you calll free for both buf and packet. But in one case you did not allocate packet, in other case you did not allocate buffer. Maxim. On 01/20/2015 05:29 PM, Maxim Uvarov wrote: Core was generated by `./odp_buffer'. Program terminated with signal 11, Segmentation fault. #0 0x00406614 in odp_buf_to_pool (buf=0x134a1300) at ./include/odp_buffer_pool_internal.h:358 358return odp_pool_to_entry(buf-pool_hdl); (gdb) bt #0 0x00406614 in odp_buf_to_pool (buf=0x134a1300) at ./include/odp_buffer_pool_internal.h:358 #1 0x00407964 in odp_buffer_free (buf=2187936352) at odp_buffer_pool.c:518 #2 0x00409666 in odp_packet_free (pkt=2187936352) at odp_packet.c:52 #3 0x0040256e in pool_alloc_type (type=1) at buffer/odp_buffer_pool_test.c:171 #4 0x004025c3 in pool_alloc_buffer_raw () at buffer/odp_buffer_pool_test.c:179 #5 0x7f81826a1f06 in run_single_test (pTest=0x191e0d0, pRunSummary=0x7f81828ab4c0) at TestRun.c:991 #6 0x7f81826a1b3c in run_single_suite (pSuite=0x191c280, pRunSummary=0x7f81828ab4c0) at TestRun.c:876 #7 0x7f818269f98b in CU_run_all_tests () at TestRun.c:367 #8 0x7f81826a3e7d in basic_run_all_tests (pRegistry=0x0) at Basic.c:195 #9 0x7f81826a3c1a in CU_basic_run_tests () at Basic.c:87 #10 0x0040592a in main () at common/odp_cunit_common.c:72 (gdb) p *buf Cannot access memory at address 0x134a1300 (gdb) l 353return (pool_entry_t *)get_pool_entry(pool_handle_to_index(pool)); 354} 355 356static inline pool_entry_t *odp_buf_to_pool(odp_buffer_hdr_t *buf) 357{ 358return odp_pool_to_entry(buf-pool_hdl); 359} 360 361static inline uint32_t odp_buffer_pool_segment_size(odp_buffer_pool_t pool) 362{ (gdb) On 01/20/2015 02:18 PM, Petri Savolainen wrote: Removed odp_buffer_type() from API and made it internal. Signed-off-by: Petri Savolainen petri.savolai...@linaro.org --- platform/linux-generic/include/api/odp_buffer.h| 16 .../linux-generic/include/api/odp_buffer_pool.h| 4 + .../linux-generic/include/odp_buffer_internal.h| 16 platform/linux-generic/odp_buffer.c| 2 +- platform/linux-generic/odp_buffer_pool.c | 4 +- platform/linux-generic/odp_event.c | 4 +- platform/linux-generic/odp_timer.c | 4 +- test/validation/buffer/odp_buffer_pool_test.c | 88 +- test/validation/buffer/odp_buffer_test.c | 4 +- test/validation/buffer/odp_packet_test.c | 15 ++-- test/validation/odp_pktio.c| 16 ++-- test/validation/odp_timer.c| 2 +- 12 files changed, 97 insertions(+), 78 deletions(-) diff --git a/platform/linux-generic/include/api/odp_buffer.h b/platform/linux-generic/include/api/odp_buffer.h index 5f825a2..69d5779 100644 --- a/platform/linux-generic/include/api/odp_buffer.h +++ b/platform/linux-generic/include/api/odp_buffer.h @@ -69,22 +69,6 @@ void *odp_buffer_addr(odp_buffer_t buf); uint32_t odp_buffer_size(odp_buffer_t buf); /** - * Buffer type - * - * @param buf Buffer handle - * - * @return Buffer type - */ -int odp_buffer_type(odp_buffer_t buf); - -#define ODP_BUFFER_TYPE_INVALID (-1) /** Buffer type invalid */ -#define ODP_BUFFER_TYPE_ANY 0 /** Buffer that can hold any other - buffer type */ -#define ODP_BUFFER_TYPE_RAW 1 /** Raw buffer, no additional metadata */ -#define ODP_BUFFER_TYPE_PACKET2 /** Packet buffer */ -#define ODP_BUFFER_TYPE_TIMEOUT 3 /** Timeout buffer */ - -/** * Tests if buffer is valid * * @param buf Buffer handle diff --git a/platform/linux-generic/include/api/odp_buffer_pool.h b/platform/linux-generic/include/api/odp_buffer_pool.h index 8380ac1..68fa69e 100644 --- a/platform/linux-generic/include/api/odp_buffer_pool.h +++ b/platform/linux-generic/include/api/odp_buffer_pool.h @@ -51,6 +51,10 @@ typedef struct odp_buffer_pool_param_t { int buf_type; /** Buffer type */ } odp_buffer_pool_param_t; +#define ODP_BUFFER_TYPE_RAW 1 /** Raw buffer, no additional metadata */ +#define ODP_BUFFER_TYPE_PACKET2 /** Packet buffer */ +#define
Re: [lng-odp] [PATCH 00/15] Event introduction
No, I was considering the abstraction for the fixed size buffer pool only. The new type can used to allocate a buffer pool from hardware fixed size buffer manager without any metadata for queueable. something like, pool = odp_buffer_pool_create(); odp_buffer_t x = odp_buffer_alloc(pool); // for queueable buffers odp_buffer_xxx_t x = odp_buffer_xxx_alloc(pool);// for non queueable buffers, only for storage This can be defined after v1.0. I already separated event (ODP_EVENT_XXX) and pool type (ODP_POOL_XXX) defines for rev2 of the event patch. With that, there can be event types that do not have a matching pool type (no pool, no alloc call), and pool types that do not have a matching event type (no xxx_to_event call = no queues, no scheduling). -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 00/15] Event introduction
True, validation suites are not updated. Those can be updated after merge. -Petri From: ext Bill Fischofer [mailto:bill.fischo...@linaro.org] Sent: Thursday, January 15, 2015 9:58 PM To: Petri Savolainen Cc: LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH 00/15] Event introduction Actually, looks like none of the unit tests are updated by this patch, so tests/validation do not compile with this patch applied. On Thu, Jan 15, 2015 at 1:48 PM, Bill Fischofer bill.fischo...@linaro.orgmailto:bill.fischo...@linaro.org wrote: Initial comment: Patch series applies, however appears incomplete as test/validation/odp_queue.c hasn't been updated: odp_queue.c: In function ‘init_queue_suite’: odp_queue.c:18:2: error: unknown type name ‘odp_buffer_pool_t’ odp_buffer_pool_t pool; ^ odp_queue.c:19:2: error: unknown type name ‘odp_buffer_pool_param_t’ odp_buffer_pool_param_t params; ^ odp_queue.c:21:8: error: request for member ‘buf_size’ in something not a structure or union params.buf_size = 0; ^ odp_queue.c:22:8: error: request for member ‘buf_align’ in something not a structure or union params.buf_align = ODP_CACHE_LINE_SIZE; ^ odp_queue.c:23:8: error: request for member ‘num_bufs’ in something not a structure or union params.num_bufs = 1024 * 10; ^ odp_queue.c:24:8: error: request for member ‘buf_type’ in something not a structure or union params.buf_type = ODP_BUFFER_TYPE_RAW; ^ odp_queue.c:24:21: error: ‘ODP_BUFFER_TYPE_RAW’ undeclared (first use in this function) params.buf_type = ODP_BUFFER_TYPE_RAW; ^ odp_queue.c:24:21: note: each undeclared identifier is reported only once for each function it appears in odp_queue.c:26:2: error: implicit declaration of function ‘odp_buffer_pool_create’ [-Werror=implicit-function-declaration] pool = odp_buffer_pool_create(msg_pool, ODP_SHM_NULL, params); ^ odp_queue.c:26:2: error: nested extern declaration of ‘odp_buffer_pool_create’ [-Werror=nested-externs] odp_queue.c:28:6: error: ‘ODP_BUFFER_POOL_INVALID’ undeclared (first use in this function) if (ODP_BUFFER_POOL_INVALID == pool) { ^ odp_queue.c: In function ‘test_odp_queue_sunnyday’: odp_queue.c:40:2: error: unknown type name ‘odp_buffer_pool_t’ odp_buffer_pool_t msg_pool; ^ odp_queue.c:68:2: error: implicit declaration of function ‘odp_buffer_pool_lookup’ [-Werror=implicit-function-declaration] msg_pool = odp_buffer_pool_lookup(msg_pool); ^ odp_queue.c:68:2: error: nested extern declaration of ‘odp_buffer_pool_lookup’ [-Werror=nested-externs] cc1: all warnings being treated as errors Makefile:843: recipe for target 'odp_queue.o' failed make[2]: *** [odp_queue.o] Error 1 make[2]: Leaving directory '/home/bill/linaro/events/test/validation' Makefile:369: recipe for target 'all-recursive' failed make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory '/home/bill/linaro/events/test' Makefile:454: recipe for target 'all-recursive' failed make: *** [all-recursive] Error 1 bill@ubuntu:~/linaro/events$ On Thu, Jan 15, 2015 at 9:40 AM, Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org wrote: This patches introduces odp_event_t and replaces with that the usage of odp_buffer_t as the super class for other buffer types. What used to be a buffer type is now an event type. There are some lines over 80 char, since those are caused by temporary event - buffer, packet - event - buffer conversions and should be cleaned up from the implementation anyway. Petri Savolainen (15): api: event: Add odp_event_t api: event: odp_schedule and odp_queue_enq api: event: schedule_multi and queue_enq_multi api: event: odp_queue_deq api: event: odp_queue_deq_multi api: buffer: Removed odp_buffer_type api: packet: Removed odp_packet_to_buffer api: packet: Removed odp_packet_from_buffer api: timer: Use odp_event_t instead of odp_buffer_t api: crypto: Use odp_event_t instead of odp_buffer_t linux-generic: crypto: Use packet alloc for packet api: buffer_pool: Rename odp_buffer_pool.h to odp_pool.h api: pool: Rename pool params and remove buffer types api: pool: Rename odp_buffer_pool_ to odp_pool_ api: config: Renamed ODP_CONFIG_BUFFER_POOLS example/generator/odp_generator.c | 38 ++--- example/ipsec/odp_ipsec.c | 70 example/ipsec/odp_ipsec_cache.c| 4 +- example/ipsec/odp_ipsec_cache.h| 2 +- example/ipsec/odp_ipsec_loop_db.c | 2 +- example/ipsec/odp_ipsec_loop_db.h | 12 +- example/ipsec/odp_ipsec_stream.c | 20 +-- example/ipsec/odp_ipsec_stream.h | 2 +- example/l2fwd/odp_l2fwd.c | 28 +-- example/packet/odp_pktio.c | 28 +-- example/timer/odp_timer_test.c | 64 +++ platform/linux-generic/Makefile.am | 4
Re: [lng-odp] [PATCH 00/15] Event introduction
From: ext Bill Fischofer [mailto:bill.fischo...@linaro.org] Sent: Thursday, January 15, 2015 11:26 PM To: Petri Savolainen Cc: LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH 00/15] Event introduction Some more observations after having looked this over in a bit more detail: This patch in its current form is basically a massive rename from buffers to events and changing things like odp_buffer_pool_t to odp_pool_t. Presumably this is intended to be followed by additional patches that surface new capabilities that build on this revised nomenclature, but for now the advantages of this change are unclear. While a patch is good, it would be really helpful to have a description of what the envisioned target looks like so that the motivation behind this rename can be better appreciated. This patch set introduces the new API structure. Implementation changes are minimal since it’s an implementation choice if buffer is used as the base class. Validation should be added and implementation cleaned where needed after this. As we have talked this already multiple times: -Event replaces buffer as the “base class” of things that can be transmitted over queues and scheduled -Event has minimum metadata (only event type == odp_event_type()) -Currently supported event types are: buffer, packet, timeout. Crypto completion event is likely to be the fourth one. -Buffer is just a another event (=raw buffer, no segmentation) -Benefit of the opaque base class is that different event types are more independent (e.g. do not have to implement odp_buffer_size(), odp_buffer_addr(), etc) -There are event types that do not carry data, but only metadata (e.g. timer timeout). Also in future, some event types may not be linked to a pool (user could not allocate, or ask for the pool) -Application cannot access one event type through multiple APIs (e.g. mix odp_buffer_xxx() and odp_packet_xxx() calls when accessing a packet) -Pools are not only for buffers, but for multiple event types (buffers, packets, timeouts, etc) Unless we also get API inline support into v1.0, there will be a performance hit here since as a result of the rename it seems a lot of applications will be making frequent calls to odp_buffer_to_event() and odp_buffer_from_event() that were not needed before. Performance is exactly the same as earlier. There are same number of handle conversions for packet, timeouts, etc (other than raw buffers). The conversion is still most likely a cast. I added some extra conversion into implementation to limit implementation changes (but performance of two type casts instead of one is the same). ev = odp_schedule(); pkt = odp_packet_from_event(ev) vs. buf = odp_schedule(); pkt = odp_packet_from_buffer(buf); There are a few oddities. Why wasn't odp_buffer_pool.c renamed to odp_pool.c since it now implements odp_pool_create(), not odp_buffer_pool_create(), etc.? There also doesn't appear to be any way to manipulate events other than by first converting them to buffers. For example, when an event is obtained from odp_schedule() it can't be freed. Instead, you do an odp_buffer_from_event() followed by an odp_buffer_free() call. This seems awkward. Since .c is implementation. I did minimal implementation change. Others can continue with implementation clean ups where needed. odp_event_free(odp_event_t* ev) can be added, but it would be mostly useful when application wants to blindly drop an event (without checking its type first). Event - buffer conversion is the feature. It promotes usage of correct types when accessing the event. Also (linux-generic) implementation should enforce type correctness and report a build (or run time) error if user tries to e.g. do odp_buffer_addr(event) or odp_packet_data(buf). The odp_pool_param_t (formerly odp_buffer_pool_param_t) is also incomplete since it's not clear how its intended to be used for the various event types. For example, there is a pkt section that has some items but odp_pool_create() still only references the buf section for creating packet events. And the tmo section is null. It’s incomplete to minimize implementation changes at this point. Those packet (and timeout) pool parametesr have to be defined and implementation changed accordingly. This type change enabled per event/pool type parameters, but does not implement those yet (== does not change the current pool param functionality). It seems very late in v1.0 to be contemplating this large a change, especially as it doesn't seem to be fully fleshed out yet. It would seem if we did something partial now applications would still face a step function conversion when the second half of the change was introduced later. So I'm wondering if it might be better if this were deferred to post-v1.0 to allow time for it to be fully developed and introduced as part of a later release? I think we can
Re: [lng-odp] [PATCH 00/15] Event introduction
Yes, agree validation needs to be updated (soon or at the same time). Because the patch set is out now, someone could have picked that up and started that work already yesterday. We just need to decide if we merge this for 0.9 and if so, who updates validation suite and how those are merged. This patch set builds and runs for the default target. ./bootstrap ./configure make -Petri -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Friday, January 16, 2015 12:43 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Bill Fischofer; LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH 00/15] Event introduction Petri this is quite well described but really should be part of the patch description (in the cover letter)? Then no need to have to ask why all this is done. I think we would like the validation suite (and everything else) to build as well... It's a bitch to change API's, I know. Even if the changes in some (more or less subjective) ways are not complete, if everything builds and runs then we know that ODP is in the same state as before the patch was applied. Cleaning up the implementation can and will always continue. On 16 January 2015 at 10:25, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: From: ext Bill Fischofer [mailto:bill.fischo...@linaro.org] Sent: Thursday, January 15, 2015 11:26 PM To: Petri Savolainen Cc: LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH 00/15] Event introduction Some more observations after having looked this over in a bit more detail: This patch in its current form is basically a massive rename from buffers to events and changing things like odp_buffer_pool_t to odp_pool_t. Presumably this is intended to be followed by additional patches that surface new capabilities that build on this revised nomenclature, but for now the advantages of this change are unclear. While a patch is good, it would be really helpful to have a description of what the envisioned target looks like so that the motivation behind this rename can be better appreciated. This patch set introduces the new API structure. Implementation changes are minimal since it’s an implementation choice if buffer is used as the base class. Validation should be added and implementation cleaned where needed after this. As we have talked this already multiple times: -Event replaces buffer as the “base class” of things that can be transmitted over queues and scheduled -Event has minimum metadata (only event type == odp_event_type()) -Currently supported event types are: buffer, packet, timeout. Crypto completion event is likely to be the fourth one. -Buffer is just a another event (=raw buffer, no segmentation) -Benefit of the opaque base class is that different event types are more independent (e.g. do not have to implement odp_buffer_size(), odp_buffer_addr(), etc) -There are event types that do not carry data, but only metadata (e.g. timer timeout). Also in future, some event types may not be linked to a pool (user could not allocate, or ask for the pool) -Application cannot access one event type through multiple APIs (e.g. mix odp_buffer_xxx() and odp_packet_xxx() calls when accessing a packet) -Pools are not only for buffers, but for multiple event types (buffers, packets, timeouts, etc) Unless we also get API inline support into v1.0, there will be a performance hit here since as a result of the rename it seems a lot of applications will be making frequent calls to odp_buffer_to_event() and odp_buffer_from_event() that were not needed before. Performance is exactly the same as earlier. There are same number of handle conversions for packet, timeouts, etc (other than raw buffers). The conversion is still most likely a cast. I added some extra conversion into implementation to limit implementation changes (but performance of two type casts instead of one is the same). ev = odp_schedule(); pkt = odp_packet_from_event(ev) vs. buf = odp_schedule(); pkt = odp_packet_from_buffer(buf); There are a few oddities. Why wasn't odp_buffer_pool.c renamed to odp_pool.c since it now implements odp_pool_create(), not odp_buffer_pool_create(), etc.? There also doesn't appear to be any way to manipulate events other than by first converting them to buffers. For example, when an event is obtained from odp_schedule() it can't be freed. Instead, you do an odp_buffer_from_event() followed by an odp_buffer_free() call. This seems awkward. Since .c is implementation. I did minimal implementation change. Others can continue with implementation clean ups where needed. odp_event_free(odp_event_t* ev) can be added, but it would be mostly useful
Re: [lng-odp] [PATCHv1 1/3] api: crypto: new completion event scheme
Speculating that this will be rebased after event patch... Compl event type definition: odp_event.h /** Invalid event type */ #define ODP_EVENT_TYPE_INVALID (-1) /** Packet event */ #define ODP_EVENT_PACKET (ODP_EVENT_TYPE_INVALID + 1) /** Buffer event */ #define ODP_EVENT_BUFFER (ODP_EVENT_TYPE_INVALID + 2) /** Timeout event */ #define ODP_EVENT_TIMEOUT (ODP_EVENT_TYPE_INVALID + 3) + /** Crypto completion event */ + #define ODP_EVENT_CRYPTO_COMPL (ODP_EVENT_TYPE_INVALID + 4) diff --git a/platform/linux-generic/include/api/odp_crypto.h b/platform/linux-generic/include/api/odp_crypto.h index 337e7cf..3815dee 100644 --- a/platform/linux-generic/include/api/odp_crypto.h +++ b/platform/linux-generic/include/api/odp_crypto.h @@ -141,6 +141,7 @@ typedef struct odp_crypto_session_params { */ typedef struct odp_crypto_op_params { odp_crypto_session_t session; /** Session handle from creation */ + void *ctx; /** User context */ odp_packet_t pkt; /** Input packet buffer */ odp_packet_t out_pkt; /** Output packet buffer */ uint8_t *override_iv_ptr; /** Override session IV pointer */ @@ -210,6 +211,21 @@ typedef struct odp_crypto_compl_status { enum crypto_hw_err hw_err; /** Hardware specific return code */ } odp_crypto_compl_status_t; +/** + * Cryto API completion event + */ +typedef odp_buffer_t odp_crypto_compl_event_t; Event can be dropped from the type name typedef odp_buffer_t odp_crypto_compl_t; + +/** + * Crypto API operation result + */ +typedef struct odp_crypto_op_result { + odp_bool_t ok; /** Request completed successfully */ + void *ctx; /** User context from request */ + odp_packet_t pkt;/** Output packet */ + odp_crypto_compl_status_t cipher_status; /** Cipher status */ + odp_crypto_compl_status_t auth_status; /** Authentication status */ +} odp_crypto_op_result_t; /** * Crypto session creation (synchronous) @@ -225,76 +241,53 @@ odp_crypto_session_create(odp_crypto_session_params_t *params, odp_crypto_session_t *session, enum odp_crypto_ses_create_err *status); +/** + * Release crypto completion event + * + * @param completion_event Completion event we are done accessing + */ +void +odp_crypto_release_compl_event(odp_crypto_compl_event_t completion_event); Shorter and buffer_free/packet_free compatible name? void odp_crypto_compl_free(odp_crypto_compl_t compl); + +/** + * Convert buffer to completion event + * + * @param buffer Generic ODP buffer + * + * @return Completion event + */ +odp_crypto_compl_event_t +odp_crypto_compl_event_from_buffer(odp_buffer_t buffer); From event to compl. Drop event from names. odp_crypto_compl_t odp_crypto_compl_from_event(odp_event_t event); /** * Crypto per packet operation * * Performs the cryptographic operations specified during session creation * on the packet. If the operation is performed synchronously, posted - * will return FALSE and the result of the operation is immediately available - * in the completion event. If posted returns TRUE the result will be - * delivered via the completion queue specified when the session was created. - * - * @todo Resolve if completion_event is necessary, can/should the output - * packet buffer always be used instead. + * will return FALSE and the result of the operation is immediately available. + * If posted returns TRUE the result will be delivered via the completion + * queue specified when the session was created. * * @param paramsOperation parameters * @param postedPointer to return posted, TRUE for async operation - * @param completion_event Event by which the operation results are delivered. + * @param resultResults of operation (when posted returns FALSE) * * @return 0 if successful else -1 */ int odp_crypto_operation(odp_crypto_op_params_t *params, bool *posted, - odp_buffer_t completion_event); + odp_crypto_op_result_t *result); /** - * Crypto per packet operation set user context in completion event + * Crypto per packet operation query result from completion event * * @param completion_event Event containing operation results - * @param ctx User data + * @param resultPointer to result structure */ void -odp_crypto_set_operation_compl_ctx(odp_buffer_t completion_event, -void *ctx); - -/** - * Crypto per packet operation completion status - * - * Accessor function for obtaining operation status from the completion event. - * - * @param completion_event Event containing operation results - * @param auth Pointer to store authentication
Re: [lng-odp] [PATCH 00/15] Event introduction
Maybe it’s better to test first which way results less (and more trivial) merge conflicts. I suspect that event first, directory/file restructure second would be easier job for git merge tool. Once we have decide that events are the way to go, someone can pick-up the job to update validation suite. It’s just matter of optimizing work flow for next couple of weeks. -Petri From: ext Bill Fischofer [mailto:bill.fischo...@linaro.org] Sent: Friday, January 16, 2015 1:13 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Ola Liljedahl; LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH 00/15] Event introduction We definitely need the validation tests to be updated as part of the initial patch, otherwise we have a patch that results in a non-buildable system, which violates our agreed-to patch rules. Given that Anders' API restructure patch is at a more complete state and is needed to support API inlining in a portable manner, I suggest that we integrate that patch first and then rebase this one (in a complete form) on it. This would also ease the conversion issues for other implementations since this change would then ride on the platform-independent API structure that the former patch introduces. On Fri, Jan 16, 2015 at 4:52 AM, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.commailto:petri.savolai...@nsn.com wrote: Yes, agree validation needs to be updated (soon or at the same time). Because the patch set is out now, someone could have picked that up and started that work already yesterday. We just need to decide if we merge this for 0.9 and if so, who updates validation suite and how those are merged. This patch set builds and runs for the default target. ./bootstrap ./configure make -Petri -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.orgmailto:ola.liljed...@linaro.org] Sent: Friday, January 16, 2015 12:43 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Bill Fischofer; LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH 00/15] Event introduction Petri this is quite well described but really should be part of the patch description (in the cover letter)? Then no need to have to ask why all this is done. I think we would like the validation suite (and everything else) to build as well... It's a bitch to change API's, I know. Even if the changes in some (more or less subjective) ways are not complete, if everything builds and runs then we know that ODP is in the same state as before the patch was applied. Cleaning up the implementation can and will always continue. On 16 January 2015 at 10:25, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.commailto:petri.savolai...@nsn.com wrote: From: ext Bill Fischofer [mailto:bill.fischo...@linaro.orgmailto:bill.fischo...@linaro.org] Sent: Thursday, January 15, 2015 11:26 PM To: Petri Savolainen Cc: LNG ODP Mailman List Subject: Re: [lng-odp] [PATCH 00/15] Event introduction Some more observations after having looked this over in a bit more detail: This patch in its current form is basically a massive rename from buffers to events and changing things like odp_buffer_pool_t to odp_pool_t. Presumably this is intended to be followed by additional patches that surface new capabilities that build on this revised nomenclature, but for now the advantages of this change are unclear. While a patch is good, it would be really helpful to have a description of what the envisioned target looks like so that the motivation behind this rename can be better appreciated. This patch set introduces the new API structure. Implementation changes are minimal since it’s an implementation choice if buffer is used as the base class. Validation should be added and implementation cleaned where needed after this. As we have talked this already multiple times: -Event replaces buffer as the “base class” of things that can be transmitted over queues and scheduled -Event has minimum metadata (only event type == odp_event_type()) -Currently supported event types are: buffer, packet, timeout. Crypto completion event is likely to be the fourth one. -Buffer is just a another event (=raw buffer, no segmentation) -Benefit of the opaque base class is that different event types are more independent (e.g. do not have to implement odp_buffer_size(), odp_buffer_addr(), etc) -There are event types that do not carry data, but only metadata (e.g. timer timeout). Also in future, some event types may not be linked to a pool (user could not allocate, or ask for the pool) -Application cannot access one event type through multiple APIs (e.g. mix odp_buffer_xxx() and odp_packet_xxx() calls when accessing a packet) -Pools are not only for buffers, but for multiple event types (buffers, packets, timeouts, etc) Unless we
Re: [lng-odp] [PATCHv3 0/9] implement odp_cpumask to the latest spec
For the entire patch set: Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Anders Roxell Sent: Thursday, January 15, 2015 12:48 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv3 0/9] implement odp_cpumask to the latest spec Hi, Tried to split up Robbies odp_cpumask into smaller and more easily built chunks. Here are the propsed modifcations for ODP 1.0 to coremask and the linux helper routines. v1 - Updated coremask library to use the CPU_xxx libraries directly, renamed APIs to cpumask and updated the linux helper routines to take CPU masks instead of a starting CPU and count. Changed parameter ordering to be consistent with other ODP APIs. Updated the examples/tests to use the modified APIs. v2 - Got in too big of a hurry and forgot to rebase v3 - Split patches to allow applying patches individually. Swapped arguments to CPU mask to/from string routines (to match ODP API conventions) and added missing const to several API paramters in CPU mask and linux files. Robbie King (9): api: cpumask: rename API and use CPU_SET(3) for impl api: cpumask: reorder the input vars to match convention linux-generic: cpumask: remove unneeded define api: cpumask: add odp_cpumask_copy api: cpumask: add odp_cpumask_first api: cpumask: add odp_cpumask_last api: cpumask: add odp_cpumask_next helper: linux: add odph_linux_cpumask_default helper: linux: use cpumask in linux thread/proc example/generator/odp_generator.c | 48 +++--- example/ipsec/odp_ipsec.c | 30 ++-- example/l2fwd/odp_l2fwd.c | 43 +++-- example/packet/odp_pktio.c| 37 ++-- example/timer/odp_timer_test.c| 25 ++- helper/include/odph_linux.h | 28 ++-- platform/linux-generic/Makefile.am| 4 +- platform/linux-generic/include/api/odp.h | 2 +- platform/linux-generic/include/api/odp_coremask.h | 188 - platform/linux-generic/include/api/odp_cpumask.h | 177 platform/linux-generic/include/api/odp_queue.h| 6 +- platform/linux-generic/odp_coremask.c | 109 platform/linux-generic/odp_cpumask.c | 195 ++ platform/linux-generic/odp_linux.c| 107 +--- test/api_test/odp_common.c| 13 +- test/performance/odp_scheduling.c | 30 ++-- test/validation/common/odp_cunit_common.c | 5 +- 17 files changed, 588 insertions(+), 459 deletions(-) delete mode 100644 platform/linux-generic/include/api/odp_coremask.h create mode 100644 platform/linux-generic/include/api/odp_cpumask.h delete mode 100644 platform/linux-generic/odp_coremask.c create mode 100644 platform/linux-generic/odp_cpumask.c -- 2.1.4 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] example: odp_timer_test.c: bug 1068 - odp_timer_test aborts
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Thursday, January 15, 2015 12:07 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH] example: odp_timer_test.c: bug 1068 - odp_timer_test aborts Since the scheduler does not guarantee fairness in scheduling, threads must time out and check if the example is still running. If this is the case, just restart the scheduler loop (not the whole example loop which may have other side effects, e.g. resetting timers with some random tick value), otherwise break out of the example loop which will terminate the example. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) example/timer/odp_timer_test.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 5de499b..dfd6c70 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -126,13 +126,22 @@ static void test_abs_timeouts(int thr, test_args_t *args) } /* Get the next expired timeout */ - /* Use 1.5 second timeout for scheduler */ - uint64_t sched_tmo = odp_schedule_wait_time(15ULL); - buf = odp_schedule(queue, sched_tmo); - /* Check if odp_schedule() timed out, possibly there are no - * remaining timeouts to receive */ + /* We invoke the scheduler in a loop with a timeout because + * we are not guaranteed to receive any more timeouts. The + * scheduler isn't guaranteeing fairness when scheduling + * buffers to threads */ + do { + /* Use 1.5 second timeout for scheduler */ + uint64_t sched_tmo = + odp_schedule_wait_time(15ULL); No need to repeat wait time conversion in the loop. It's better to keep it out side of the loop since this is an example and should demonstrate the correct/elegant way of using the APIs. -Petri + buf = odp_schedule(queue, sched_tmo); + /* Check if odp_schedule() timed out, possibly there + * are no remaining timeouts to receive */ + } while (buf == ODP_BUFFER_INVALID + (int)odp_atomic_load_u32(remain) 0); + if (buf == ODP_BUFFER_INVALID) - continue; /* Re-check the remain counter */ + break; /* No more timeouts */ if (odp_buffer_type(buf) != ODP_BUFFER_TYPE_TIMEOUT) { /* Not a default timeout buffer */ EXAMPLE_ABORT(Unexpected buffer type (%u) received\n, -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 1/2] api: remove odp_compiler.h
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mike Holmes Sent: Wednesday, January 14, 2015 12:06 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH 1/2] api: remove odp_compiler.h Compiler information should be predominately platform specific and not part of the API. The only part of the API needing these definitions is odp_byteorder.h so move the definition there and delete odp_compiler.h Signed-off-by: Mike Holmes mike.hol...@linaro.org --- platform/linux-generic/Makefile.am | 1 - platform/linux-generic/include/api/odp.h | 2 - platform/linux-generic/include/api/odp_byteorder.h | 27 +++- platform/linux-generic/include/api/odp_compiler.h | 51 - - 4 files changed, 26 insertions(+), 55 deletions(-) delete mode 100644 platform/linux-generic/include/api/odp_compiler.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux- generic/Makefile.am index 4535c57..51cf69c 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -14,7 +14,6 @@ include_HEADERS = \ $(top_srcdir)/platform/linux- generic/include/api/odp_buffer_pool.h \ $(top_srcdir)/platform/linux- generic/include/api/odp_byteorder.h \ $(top_srcdir)/platform/linux- generic/include/api/odp_classification.h \ - $(top_srcdir)/platform/linux- generic/include/api/odp_compiler.h \ $(top_srcdir)/platform/linux- generic/include/api/odp_config.h \ $(top_srcdir)/platform/linux- generic/include/api/odp_coremask.h \ $(top_srcdir)/platform/linux- generic/include/api/odp_crypto.h \ diff --git a/platform/linux-generic/include/api/odp.h b/platform/linux- generic/include/api/odp.h index b7b1ca9..920fc58 100644 --- a/platform/linux-generic/include/api/odp.h +++ b/platform/linux-generic/include/api/odp.h @@ -19,10 +19,8 @@ extern C { #endif #include odp_config.h - #include odp_version.h #include odp_std_types.h -#include odp_compiler.h #include odp_align.h #include odp_hints.h #include odp_debug.h diff --git a/platform/linux-generic/include/api/odp_byteorder.h b/platform/linux-generic/include/api/odp_byteorder.h index 5890011..f5514d9 100644 --- a/platform/linux-generic/include/api/odp_byteorder.h +++ b/platform/linux-generic/include/api/odp_byteorder.h @@ -21,7 +21,32 @@ extern C { #include endian.h #include asm/byteorder.h #include odp_std_types.h -#include odp_compiler.h + +/** @addtogroup odp_compiler_optim + * Macro for old compilers + * @{ + */ + +/** @internal GNU compiler version */ +#define GCC_VERSION (__GNUC__ * 1 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +/** + * @internal + * Compiler __builtin_bswap16() is not available on all platforms + * until GCC 4.8.0 - work around this by offering __odp_builtin_bswap16() + * Don't use this function directly, instead see odp_byteorder.h + */ +#if GCC_VERSION 40800 +#define __odp_builtin_bswap16(u16) u16)0x00ff) 8)|(((u16)0xff00) 8)) +#else +#define __odp_builtin_bswap16(u16) __builtin_bswap16(u16) +#endif + +/** + * @} + */ /** @defgroup odp_compiler_optim ODP COMPILER / OPTIMIZATION * Macros that check byte order and byte converting operations. diff --git a/platform/linux-generic/include/api/odp_compiler.h b/platform/linux-generic/include/api/odp_compiler.h deleted file mode 100644 index 71a4431..000 --- a/platform/linux-generic/include/api/odp_compiler.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - - -/** - * @file - * - * Compiler related - */ - -#ifndef ODP_COMPILER_H_ -#define ODP_COMPILER_H_ - -#ifdef __cplusplus -extern C { -#endif - -/** @addtogroup odp_compiler_optim - * Macro for old compilers - * @{ - */ - -/** @internal GNU compiler version */ -#define GCC_VERSION (__GNUC__ * 1 \ - + __GNUC_MINOR__ * 100 \ - + __GNUC_PATCHLEVEL__) - -/** - * @internal - * Compiler __builtin_bswap16() is not available on all platforms - * until GCC 4.8.0 - work around this by offering __odp_builtin_bswap16() - * Don't use this function directly, instead see odp_byteorder.h - */ -#if GCC_VERSION 40800 -#define __odp_builtin_bswap16(u16) u16)0x00ff) 8)|(((u16)0xff00) 8)) -#else -#define __odp_builtin_bswap16(u16) __builtin_bswap16(u16) -#endif - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 2/2] linux-generic: packet_socket: remove include of odp.h
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mike Holmes Sent: Wednesday, January 14, 2015 12:06 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH 2/2] linux-generic: packet_socket: remove include of odp.h Signed-off-by: Mike Holmes mike.hol...@linaro.org Implementations should not include odp.h directly, this is a helper for applications only. --- platform/linux-generic/odp_packet_socket.c | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux- generic/odp_packet_socket.c index da7fb2c..5b30c19 100644 --- a/platform/linux-generic/odp_packet_socket.c +++ b/platform/linux-generic/odp_packet_socket.c @@ -34,7 +34,6 @@ #include errno.h #include sys/syscall.h -#include odp.h #include odp_packet_socket.h #include odp_packet_internal.h #include odp_align_internal.h -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v1] api: Move Pktio related APIs to pktio Header file
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org A patch set (one type of modification per patch) would have been better approach, but I'm OK with this since changes were trivial. -Petri -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Balasubramanian Manoharan Sent: Wednesday, January 14, 2015 8:05 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v1] api: Move Pktio related APIs to pktio Header file The following APIs are setting parameters to pktio handle and are hence moved from classification header to pktio header file. odp_pktio_default_cos_set() odp_pktio_error_cos_set() odp_pktio_skip_set() odp_pktio_headroom_set() This patch also modifies the error return values in API description from -1 to non-zero value Signed-off-by: Balasubramanian Manoharan bala.manoha...@linaro.org --- .../linux-generic/include/api/odp_classification.h | 92 - - platform/linux-generic/include/api/odp_packet_io.h | 55 + .../linux-generic/include/api/odp_platform_types.h | 3 + platform/linux-generic/odp_classification.c| 22 +++--- platform/linux-generic/odp_init.c | 2 +- 5 files changed, 86 insertions(+), 88 deletions(-) diff --git a/platform/linux-generic/include/api/odp_classification.h b/platform/linux-generic/include/api/odp_classification.h index 4c9674b..46189bc 100644 --- a/platform/linux-generic/include/api/odp_classification.h +++ b/platform/linux-generic/include/api/odp_classification.h @@ -22,7 +22,6 @@ extern C { #include odp_std_types.h #include odp_buffer_pool.h #include odp_packet.h -#include odp_packet_io.h #include odp_queue.h /** @defgroup odp_classification ODP CLASSIFICATION @@ -30,11 +29,6 @@ extern C { * @{ */ -/** - * Class of service instance type - */ -typedef uint32_t odp_cos_t; - /** * flow signature type, only used for packet metadata field. @@ -95,7 +89,7 @@ odp_cos_t odp_cos_create(const char *name); * * @param[in]cos_id class-of-service instance. * - * @return 0 on success, -1 on error. + * @return 0 on success, non-zero on error. */ int odp_cos_destroy(odp_cos_t cos_id); @@ -108,7 +102,7 @@ int odp_cos_destroy(odp_cos_t cos_id); * of this specific class of service * will be enqueued. * - * @return 0 on success, -1 on error. + * @return 0 on success, non-zero on error. */ int odp_cos_set_queue(odp_cos_t cos_id, odp_queue_t queue_id); @@ -118,67 +112,13 @@ int odp_cos_set_queue(odp_cos_t cos_id, odp_queue_t queue_id); * @param[in]cos_id class-of-service instance. * @param[in]drop_policy Desired packet drop policy for this class. * - * @return 0 on success, -1 on error. + * @return 0 on success, non-zero on error. * * @note Optional. */ int odp_cos_set_drop(odp_cos_t cos_id, odp_drop_e drop_policy); /** - * Setup per-port default class-of-service. - * - * @param[in]pktio_inIngress port identifier. - * @param[in]default_cos Class-of-service set to all packets arriving - * at the pktio_in ingress port, - * unless overridden by subsequent - * header-based filters. - * - * @return 0 on success, -1 on error. - */ -int odp_pktio_set_default_cos(odp_pktio_t pktio_in, odp_cos_t default_cos); - -/** - * Setup per-port error class-of-service - * - * @param[in]pktio_inIngress port identifier. - * @param[in]error_cos class-of-service set to all packets arriving - * at the pktio_in ingress port - * that contain an error. - * - * @return 0 on success, -1 on error. - * - * @note Optional. - */ -int odp_pktio_set_error_cos(odp_pktio_t pktio_in, odp_cos_t error_cos); - -/** - * Setup per-port header offset - * - * @param[in]pktio_inIngress port identifier. - * @param[in]offset Number of bytes the classifier must skip. - * - * @return 0 on success, -1 on error. - * @note Optional. - * - */ -int odp_pktio_set_skip(odp_pktio_t pktio_in, size_t offset); - -/** - * Specify per-port buffer headroom - * - * @param[in]pktio_inIngress port identifier. - * @param[in]headroomNumber of bytes of space preceding - * packet data to reserve for use as headroom. - * Must not exceed the implementation - * defined ODP_PACKET_MAX_HEADROOM. - * - * @return 0 on success, -1 on
Re: [lng-odp] [PATCH v3 0/2] Remove odp_shcdule_one
The entire patch set Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mike Holmes Sent: Monday, January 12, 2015 10:46 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH v3 0/2] Remove odp_shcdule_one For 1.0 odp_schedule_one has been removed. Mike Holmes (2): test: perf: scheduling: remove odp_schedule_one api: schedule: remove odp_schedule_one platform/linux-generic/include/api/odp_schedule.h | 25 platform/linux-generic/odp_schedule.c | 12 -- test/performance/odp_scheduling.c | 143 - - 3 files changed, 180 deletions(-) -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv2] api: implement odp_pktio_name
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Maxim Uvarov Sent: Tuesday, January 13, 2015 3:17 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv2] api: implement odp_pktio_name Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- v2: fix doxygen header platform/linux-generic/include/api/odp_packet_io.h | 13 + platform/linux-generic/odp_packet_io.c | 11 +++ 2 files changed, 24 insertions(+) diff --git a/platform/linux-generic/include/api/odp_packet_io.h b/platform/linux-generic/include/api/odp_packet_io.h index 0c34f29..c0ced4f 100644 --- a/platform/linux-generic/include/api/odp_packet_io.h +++ b/platform/linux-generic/include/api/odp_packet_io.h @@ -169,6 +169,19 @@ size_t odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, size_t addr_size); /** + * Packet IO interface name + * + * Return the interface name from a pktio handle. This is the + * name that was passed to the odp_pktio_open() call. + * + * @param id ODP Packet IO handle. + * + * @retval Pointer to the interface name. + * @retval NULL if packet handle is invalid. + */ +const char *odp_pktio_name(odp_pktio_t id); + +/** * @} */ diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux- generic/odp_packet_io.c index cd109d2..7b08edf 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -746,3 +746,14 @@ size_t odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, return ETH_ALEN; } + +const char *odp_pktio_name(odp_pktio_t id) +{ + pktio_entry_t *entry; + + entry = get_pktio_entry(id); + if (entry == NULL) + return NULL; + + return entry-s.name; +} -- 1.8.5.1.163.gd7aced9 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] api: implement odp_pktio_name
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Maxim Uvarov Sent: Tuesday, January 13, 2015 1:28 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH] api: implement odp_pktio_name Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- platform/linux-generic/include/api/odp_packet_io.h | 11 +++ platform/linux-generic/odp_packet_io.c | 11 +++ 2 files changed, 22 insertions(+) diff --git a/platform/linux-generic/include/api/odp_packet_io.h b/platform/linux-generic/include/api/odp_packet_io.h index 0c34f29..7c4c19d 100644 --- a/platform/linux-generic/include/api/odp_packet_io.h +++ b/platform/linux-generic/include/api/odp_packet_io.h @@ -168,6 +168,17 @@ int odp_pktio_promisc_mode(odp_pktio_t id); size_t odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, size_t addr_size); +/* Missing Doxygen short description like this: /** Packet IO interface name * -Petri + * Return the interface name from a pktio handle. This is the + * name that was passed to the odp_pktio_open() call. + * + * @param id ODP Packet IO handle. + * + * @retval Pointer to the interface name. + * @retval NULL if packet handle is invalid. + */ +const char *odp_pktio_name(odp_pktio_t id); + /** * @} */ diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux- generic/odp_packet_io.c index cd109d2..7b08edf 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -746,3 +746,14 @@ size_t odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, return ETH_ALEN; } + +const char *odp_pktio_name(odp_pktio_t id) +{ + pktio_entry_t *entry; + + entry = get_pktio_entry(id); + if (entry == NULL) + return NULL; + + return entry-s.name; +} -- 1.8.5.1.163.gd7aced9 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [RFC PATCH] linux-generic: pktio: add loopback device support
+static int random_mac(void *mac_addr, size_t addr_size) +{ + uint32_t ethaddr_l, ethaddr_h; + + srand(odp_time_cycles()); + ethaddr_h = (rand() 0xfeff) | 0x0200; + ethaddr_l = rand(); + + snprintf(mac_addr, addr_size, %02x:%02x:%02x:%02x:%02x:%02x, + ethaddr_h 8, ethaddr_h 0xff, + ethaddr_l 24, (ethaddr_l 16) 0xff, + (ethaddr_l 8) 0xff, ethaddr_l 0xff); + + return 0; +} + Maybe it's better to use constant mac address(es), so that it's easier to spot configuration errors, reproduce problems and test results. Also the locally administered MAC address bit should be set (to avoid collision with globally unique addresses in the case it would leak into network). -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv4 2/3] api: odp_timer.h: updated API, lock-less implementation
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Thursday, January 08, 2015 11:35 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv4 2/3] api: odp_timer.h: updated API, lock-less implementation The timer API is updated according to https://docs.google.com/a/linaro.org/document/d/1bfY_J8ecLJPsFTmYftb0NVmGn B9qkEc_NpcJ87yfaD8 A major change is that timers are allocated and freed separately from timeouts being set and cancelled. The life-length of a timer normally corresponds to the life-length of the associated stateful flow while the life-length of a timeout corresponds to individual packets being transmitted and received. The reference timer implementation is lock-less for platforms with support for 128-bit (16-byte) atomic exchange and CAS operations. Otherwise a lock-based implementation (using as many locks as desired) is used but some operations (e.g. reset reusing existing timeout buffer) may still be lock-less. Updated the example example/timer/odp_timer_test.c according to the updated API. Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) Updated API and odp_timer_test.c with latest review comments from Petri S. example/timer/odp_timer_test.c | 183 ++-- platform/linux-generic/include/api/odp_timer.h | 321 -- .../linux-generic/include/odp_timer_internal.h | 62 +- platform/linux-generic/odp_timer.c | 1054 ++- - 4 files changed, 1133 insertions(+), 487 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 2acf2fc..5de499b 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -26,7 +26,6 @@ #define MAX_WORKERS 32/** Max worker threads */ -#define MSG_POOL_SIZE (4*1024*1024) /** Message pool size */ #define MSG_NUM_BUFS 1 /** Number of timers */ @@ -44,69 +43,125 @@ typedef struct { /** @private Barrier for test synchronisation */ static odp_barrier_t test_barrier; -/** @private Timer handle*/ -static odp_timer_t test_timer; +/** @private Buffer pool handle */ +static odp_buffer_pool_t pool; +/** @private Timer pool handle */ +static odp_timer_pool_t tp; + +/** @private Number of timeouts to receive */ +static odp_atomic_u32_t remain; + +/** @private Timer set status ASCII strings */ +static const char *timerset2str(odp_timer_set_t val) +{ + switch (val) { + case ODP_TIMER_SUCCESS: + return success; + case ODP_TIMER_TOOEARLY: + return too early; + case ODP_TIMER_TOOLATE: + return too late; + case ODP_TIMER_NOBUF: + return no buffer; + default: + return ?; + } +}; + +/** @private Helper struct for timers */ +struct test_timer { + odp_timer_t tim; + odp_buffer_t buf; +}; + +/** @private Array of all timer helper structs */ +static struct test_timer tt[256]; /** @private test timeout */ static void test_abs_timeouts(int thr, test_args_t *args) { - uint64_t tick; uint64_t period; uint64_t period_ns; odp_queue_t queue; - odp_buffer_t buf; - int num; + uint64_t tick; + struct test_timer *ttp; EXAMPLE_DBG( [%i] test_timeouts\n, thr); queue = odp_queue_lookup(timer_queue); period_ns = args-period_us*ODP_TIME_USEC; - period= odp_timer_ns_to_tick(test_timer, period_ns); + period= odp_timer_ns_to_tick(tp, period_ns); EXAMPLE_DBG( [%i] period %PRIu64 ticks, %PRIu64 ns\n, thr, period, period_ns); - tick = odp_timer_current_tick(test_timer); - - EXAMPLE_DBG( [%i] current tick %PRIu64\n, thr, tick); + EXAMPLE_DBG( [%i] current tick %PRIu64\n, thr, + odp_timer_current_tick(tp)); - tick += period; - - if (odp_timer_absolute_tmo(test_timer, tick, queue, ODP_BUFFER_INVALID) - == ODP_TIMER_TMO_INVALID){ - EXAMPLE_DBG(Timeout request failed\n); + ttp = tt[thr - 1]; /* Thread starts at 1 */ + ttp-tim = odp_timer_alloc(tp, queue, ttp); + if (ttp-tim == ODP_TIMER_INVALID) { + EXAMPLE_ERR(Failed to allocate timer\n); return; } + ttp-buf = odp_buffer_alloc(pool); + if (ttp-buf == ODP_BUFFER_INVALID) { + EXAMPLE_ERR(Failed to allocate buffer\n); + return; + } + tick = odp_timer_current_tick(tp); - num = args-tmo_count; - - while (1) { - odp_timeout_t tmo; + while ((int)odp_atomic_load_u32(remain) 0) { + odp_buffer_t buf; +
Re: [lng-odp] [PATCH v2 2/2] api: buffer: Change buffer size from size_t to uint32_t
Ping. This patch should be merged. The patch v2 1/2 api: buffer_pool: Correct buf_size pool param documentation may be hold for now, since event definition will change that part anyway. -Petri -Original Message- From: ext Petri Savolainen [mailto:petri.savolai...@linaro.org] Sent: Tuesday, December 23, 2014 1:29 PM To: lng-odp@lists.linaro.org Cc: Petri Savolainen Subject: [PATCH v2 2/2] api: buffer: Change buffer size from size_t to uint32_t Use uint32_t for buffer size to be align with packet API lenghts and offsets. Signed-off-by: Petri Savolainen petri.savolai...@linaro.org --- platform/linux-generic/include/api/odp_buffer.h | 2 +- platform/linux-generic/include/odp_buffer_internal.h | 2 +- platform/linux-generic/odp_buffer.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/linux-generic/include/api/odp_buffer.h b/platform/linux-generic/include/api/odp_buffer.h index 3c23035..0670464 100644 --- a/platform/linux-generic/include/api/odp_buffer.h +++ b/platform/linux-generic/include/api/odp_buffer.h @@ -44,7 +44,7 @@ void *odp_buffer_addr(odp_buffer_t buf); * * @return Buffer maximum data size */ -size_t odp_buffer_size(odp_buffer_t buf); +uint32_t odp_buffer_size(odp_buffer_t buf); /** * Buffer type diff --git a/platform/linux-generic/include/odp_buffer_internal.h b/platform/linux-generic/include/odp_buffer_internal.h index 60f06c9..a315f00 100644 --- a/platform/linux-generic/include/odp_buffer_internal.h +++ b/platform/linux-generic/include/odp_buffer_internal.h @@ -118,7 +118,7 @@ typedef struct odp_buffer_hdr_t { }; } flags; int type; /* buffer type */ - size_t size; /* max data size */ + uint32_t size; /* max data size */ odp_atomic_u32_t ref_count; /* reference count */ odp_buffer_pool_tpool_hdl; /* buffer pool handle */ union { diff --git a/platform/linux-generic/odp_buffer.c b/platform/linux- generic/odp_buffer.c index dd37ab3..57ba408 100644 --- a/platform/linux-generic/odp_buffer.c +++ b/platform/linux-generic/odp_buffer.c @@ -22,7 +22,7 @@ void *odp_buffer_addr(odp_buffer_t buf) } -size_t odp_buffer_size(odp_buffer_t buf) +uint32_t odp_buffer_size(odp_buffer_t buf) { odp_buffer_hdr_t *hdr = odp_buf_to_hdr(buf); @@ -63,7 +63,7 @@ int odp_buffer_snprint(char *str, uint32_t n, odp_buffer_t buf) len += snprintf(str[len], n-len, addr %p\n,hdr-addr); len += snprintf(str[len], n-len, - size %zu\n, hdr-size); + size %u\n,hdr-size); len += snprintf(str[len], n-len, ref_count%i\n, odp_atomic_load_u32(hdr-ref_count)); -- 2.2.1 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv3 2/3] api: odp_timer.h: updated API, lock-less implementation
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Monday, January 05, 2015 8:24 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv3 2/3] api: odp_timer.h: updated API, lock-less implementation Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) The timer API is updated according to https://docs.google.com/a/linaro.org/document/d/1bfY_J8ecLJPsFTmYftb0NVmGn B9qkEc_NpcJ87yfaD8 A major change is that timers are allocated and freed separately from timeouts being set and cancelled. The life-length of a timer normally corresponds to the life-length of the associated stateful flow while the life-length of a timeout corresponds to individual packets being transmitted and received. The reference timer implementation is lock-less for platforms with support for 128-bit (16-byte) atomic exchange and CAS operations. Otherwise a lock-based implementation (using as many locks as desired) is used but some operations (e.g. reset reusing existing timeout buffer) may still be lock-less. Updated the example example/timer/odp_timer_test.c according to the updated API. Updated the API according to Petri's review comments. --- example/timer/odp_timer_test.c | 177 ++-- platform/linux-generic/include/api/odp_timer.h | 318 -- .../linux-generic/include/odp_timer_internal.h | 59 +- platform/linux-generic/odp_timer.c | 1064 ++- - 4 files changed, 1139 insertions(+), 479 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 2acf2fc..71f72b4 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -26,7 +26,6 @@ #define MAX_WORKERS 32/** Max worker threads */ -#define MSG_POOL_SIZE (4*1024*1024) /** Message pool size */ #define MSG_NUM_BUFS 1 /** Number of timers */ @@ -44,69 +43,119 @@ typedef struct { /** @private Barrier for test synchronisation */ static odp_barrier_t test_barrier; -/** @private Timer handle*/ -static odp_timer_t test_timer; +/** @private Buffer pool handle */ +static odp_buffer_pool_t pool; +/** @private Timer pool handle */ +static odp_timer_pool_t tp; + +/** @private Number of timeouts to receive */ +static odp_atomic_u32_t remain; + +/** @private Timer set status ASCII strings */ +static const char *timerset2str(odp_timer_set_t val) +{ + switch (val) { + case ODP_TIMER_SET_SUCCESS: + return success; + case ODP_TIMER_SET_TOOEARLY: + return too early; + case ODP_TIMER_SET_TOOLATE: + return too late; + case ODP_TIMER_SET_NOBUF: + return no buffer; + default: + return ?; + } +}; + +/** @private Helper struct for timers */ +struct test_timer { + odp_timer_t tim; + odp_buffer_t buf; +}; + +/** @private Array of all timer helper structs */ +static struct test_timer tt[256]; /** @private test timeout */ static void test_abs_timeouts(int thr, test_args_t *args) { - uint64_t tick; uint64_t period; uint64_t period_ns; odp_queue_t queue; - odp_buffer_t buf; - int num; + uint64_t tick; + struct test_timer *ttp; EXAMPLE_DBG( [%i] test_timeouts\n, thr); queue = odp_queue_lookup(timer_queue); period_ns = args-period_us*ODP_TIME_USEC; - period= odp_timer_ns_to_tick(test_timer, period_ns); + period= odp_timer_ns_to_tick(tp, period_ns); EXAMPLE_DBG( [%i] period %PRIu64 ticks, %PRIu64 ns\n, thr, period, period_ns); - tick = odp_timer_current_tick(test_timer); - - EXAMPLE_DBG( [%i] current tick %PRIu64\n, thr, tick); + EXAMPLE_DBG( [%i] current tick %PRIu64\n, thr, + odp_timer_current_tick(tp)); - tick += period; - - if (odp_timer_absolute_tmo(test_timer, tick, queue, ODP_BUFFER_INVALID) - == ODP_TIMER_TMO_INVALID){ - EXAMPLE_DBG(Timeout request failed\n); + ttp = tt[thr - 1]; /* Thread starts at 1 */ + ttp-tim = odp_timer_alloc(tp, queue, ttp); + if (ttp-tim == ODP_TIMER_INVALID) { + EXAMPLE_ERR(Failed to allocate timer\n); return; } + ttp-buf = odp_buffer_alloc(pool); + if (ttp-buf == ODP_BUFFER_INVALID) { + EXAMPLE_ERR(Failed to allocate buffer\n); + return; + } + tick = odp_timer_current_tick(tp); - num = args-tmo_count; - - while (1) { - odp_timeout_t tmo; + while ((int)odp_atomic_load_u32(remain) 0) { + odp_buffer_t buf; + odp_timer_set_t rc; - buf = odp_schedule_one(queue,
Re: [lng-odp] [PATCHv3 2/3] api: odp_timer.h: updated API, lock-less implementation
+/** + * Create a timer pool + * + * @param name Name of the timer pool. The string will be copied. + * @param buf_pool Buffer pool for allocating timeouts Maybe a comment also here for the purpose of this pool. Or just remove it, if there's no clear usage for it. It can be added later again if needed. + * @param params Timer pool parameters. The content will be copied. + * + * @return Timer pool handle if successful, otherwise ODP_TIMER_POOL_INVALID + * and errno set This is the first API to use errno. Errno needs to be changed to odp_errno() (with odp_errno_clear(), odp_errno_print(), odp_errno_str()). That can be done after merge. OK but these functions seem not to exist yet? Yes, those need to be added soon - so that ODP does not share errno with C libraries. + +/** + * Set a timer (absolute time) with a user-provided timeout buffer + * + * Set (arm) the timer to expire at specific time. The timeout + * buffer will be enqueued when the timer expires. + * + * Note: any invalid parameters will be treated as programming errors and will + * cause the application to abort. + * + * @param tim Timer + * @param abs_tck Expiration time in absolute timer ticks + * @param tmo_buf Reference to a buffer variable that points to timeout buffer + * or NULL to reuse the existing timeout buffer Tmo_buf parameter usage needs clarification: - Can this be always NULL, meaning that timer should be set with a tmo buffer allocated from the pool provided in timer_pool_create call? No not in the current design. The idea could be investigated. OK. Maybe then remove the pool param from pool_create. - Is it also an output param? Timer_reset() writes it with old buffer handle value. Yes. Should be fixed. + * + * @retval ODP_TIMER_SET_SUCCESS Operation succeeded + * @retval ODP_TIMER_SET_TOOEARLY Operation failed because expiration tick too + * early + * @retval ODP_TIMER_SET_TOOLATE Operation failed because expiration tick too + * late + * @retval ODP_TIMER_SET_NOBUF Operation failed because timeout buffer not + * specified in call and not present in timer When this actually happens? When trying to reset an expired timer ? Yes. Timer has already expired. The application can decide what to do. Either allocate a new timeout buffer and retry the set operation or it can ignore this situation because it knows the timeout buffer will be received shortly. The application decides. OK. The return codes are a bit long. _SET_ could be dropped without readability issues (e.g. ODP_TIMER_SUCCESS). +/** + * Check for fresh timeout + * If the corresponding timer has been reset or cancelled since this timeout + * was enqueued, the timeout is stale (not fresh). * - * @return 0 if successful + * @param tmo Timeout handle + * @retval 1 Timeout is fresh + * @retval 0 Timeout is stale */ -int odp_timer_cancel_tmo(odp_timer_t timer, odp_timer_tmo_t tmo); +int /*odp_bool_t*/odp_timeout_fresh(odp_timeout_t tmo); Remove /*odp_bool_t*/ OK. Or use odp_bool_t instead of int? true - fresh, false - stale. int as a return type if normally used with 0 for success and 0 for failure. So far odp_bool_t has not been used in return values. This falls into _is_xxx() category and thus would return !0 = true and 0 = false. -Petri ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] api: odp_debug: make ODP_ABORT a weak symbol
Hi, As agreed in the call today, it's better to remove API dependency to non-standard weak symbol feature of GCC. Instead we'll define these two as callback functions for odp_init_global()... typedef struct odp_init_t { int (*odp_log)(odp_log_level_e level, const char *fmt, ...); void (*odp_abort)(void); } odp_init_t; NULL would mean default log/abort implementation (with those user could still override default implementation at his own risk of non-portability). -Petri -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Mike Holmes Sent: Tuesday, January 06, 2015 10:07 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCH] api: odp_debug: make ODP_ABORT a weak symbol Add a weak definition of ODP_ABORT so that it may be overridden by an application. Signed-off-by: Mike Holmes mike.hol...@linaro.org --- platform/linux-generic/include/api/odp_debug.h | 14 ++ platform/linux-generic/include/api/odp_hints.h | 5 + platform/linux-generic/include/odp_debug_internal.h | 4 ++-- platform/linux-generic/odp_weak.c | 5 + 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/include/api/odp_debug.h b/platform/linux-generic/include/api/odp_debug.h index a4ce1d9..dd4eb89 100644 --- a/platform/linux-generic/include/api/odp_debug.h +++ b/platform/linux-generic/include/api/odp_debug.h @@ -12,6 +12,7 @@ #ifndef ODP_DEBUG_H_ #define ODP_DEBUG_H_ +#include odp_hints.h #ifdef __cplusplus extern C { @@ -75,6 +76,19 @@ typedef enum odp_log_level { */ extern int odp_override_log(odp_log_level_e level, const char *fmt, ...); +/** + * ODP abort function + * + * Where a fatal event can be identified within the ODP implementation an + * ODP_ASSERT may used which can be controlled via ODP_DEBUG. In cases where + * an abort must always be called ODP_ABORT may be called directly. In + * both cases these macros will call odp_override_abort + * ODP platform MUST provide a default *weak* implementation of this function. + * Application MAY override the function if needed by providing a strong + * function. + * @note This function must never return. + */ +extern void odp_override_abort(void) ODP_NORETURN; /** diff --git a/platform/linux-generic/include/api/odp_hints.h b/platform/linux-generic/include/api/odp_hints.h index 7f04886..7eb9e36 100644 --- a/platform/linux-generic/include/api/odp_hints.h +++ b/platform/linux-generic/include/api/odp_hints.h @@ -32,6 +32,11 @@ extern C { #define ODP_WEAK_SYMBOL __attribute__((__weak__)) /** + * Function never returns + */ +#define ODP_NORETURN__attribute__((__noreturn__)) + +/** * Hot code section */ #define ODP_HOT_CODE__attribute__((__hot__)) diff --git a/platform/linux-generic/include/odp_debug_internal.h b/platform/linux-generic/include/odp_debug_internal.h index f6180d1..bbbe591 100644 --- a/platform/linux-generic/include/odp_debug_internal.h +++ b/platform/linux-generic/include/odp_debug_internal.h @@ -53,7 +53,7 @@ extern C { #define ODP_ASSERT(cond, msg) \ do { if ((ODP_DEBUG == 1) (!(cond))) { \ ODP_ERR(%s\n, msg); \ - abort(); } \ + odp_override_abort(); } \ } while (0) /** @@ -85,7 +85,7 @@ extern C { #define ODP_ABORT(fmt, ...) \ do { \ ODP_LOG(ODP_LOG_ABORT, fmt, ##__VA_ARGS__); \ - abort(); \ + odp_override_abort(); \ } while (0) /** diff --git a/platform/linux-generic/odp_weak.c b/platform/linux- generic/odp_weak.c index fccbc3f..ce87119 100644 --- a/platform/linux-generic/odp_weak.c +++ b/platform/linux-generic/odp_weak.c @@ -21,3 +21,8 @@ ODP_WEAK_SYMBOL int odp_override_log(odp_log_level_e level ODP_UNUSED, return r; } + +ODP_WEAK_SYMBOL void odp_override_abort(void) +{ + abort(); +} -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2 1/2] api: buffer_pool: Correct buf_size pool param documentation
From: ext Bill Fischofer [mailto:bill.fischo...@linaro.org] Sent: Tuesday, December 23, 2014 2:58 PM To: Petri Savolainen Cc: lng-odp-forward Subject: Re: [lng-odp] [PATCH v2 1/2] api: buffer_pool: Correct buf_size pool param documentation On Tue, Dec 23, 2014 at 5:29 AM, Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org wrote: Buf_size parameter defines minimum buffer/segment length. Use 0 for default length. Signed-off-by: Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org --- .../linux-generic/include/api/odp_buffer_pool.h| 28 +- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/platform/linux-generic/include/api/odp_buffer_pool.h b/platform/linux-generic/include/api/odp_buffer_pool.h index 8380ac1..9329405 100644 --- a/platform/linux-generic/include/api/odp_buffer_pool.h +++ b/platform/linux-generic/include/api/odp_buffer_pool.h @@ -35,19 +35,25 @@ extern C { /** * Buffer pool parameters * Used to communicate buffer pool creation options. + * + * @see ODP_CONFIG_PACKET_BUF_LEN_MIN, ODP_CONFIG_BUFFER_ALIGN_MIN, + * ODP_CONFIG_BUFFER_ALIGN_MAX */ typedef struct odp_buffer_pool_param_t { - uint32_t buf_size; /** Buffer size in bytes. The maximum - number of bytes application will - store in each buffer. For packets, this - is the maximum packet data length, and - configured headroom and tailroom will be - added to this number */ - uint32_t buf_align; /** Minimum buffer alignment in bytes. - Valid values are powers of two. Use 0 - for default alignment. Default will - always be a multiple of 8. */ - uint32_t num_bufs; /** Number of buffers in the pool */ + uint32_t buf_size; /** Minimum buffer size in bytes. For packets, +this is the minimum segment buffer length, +which includes possible head-/tailroom bytes. +Use 0 for the default size of the buffer type +(e.g. for timeouts or min packet segment +length).*/ I continue to have difficulty with understanding how the implementation is expected to use this interpretation of buf_size to calculate how much storage should be reserved for the buffer pool. The implementation needs to know this and under the former definition that was straightforward since the application was specifying how large each buffer may be. Minimums do not do this. Application specifies the minimum size (e.g. 100 bytes). Implementation can round it up to a sensible value (e.g. 128 bytes). odp_buffer_size() and odp_packet_seg_buf_len() return the actual buffer length (e.g. 128 bytes). Pool size is num_bufs * (buf_size + round up + internal headers, per buffer overheads, etc). + uint32_t buf_align; /** Minimum buffer alignment in bytes. Valid values +are powers of two. Use 0 for default +alignment. Default will always be a multiple +of 8. */ + uint32_t num_bufs; /** Number of buffers in the pool. For packets, +this is the total number of segments and the +maximum number of packets (in case that all +packets have a single segment). */ This is not what the implementation needs to know. A buffer is not a segment since a buffer is what anchors the metadata associated with the object. Whether or not we introduce packet segment metadata, packets (single object) have metadata associated with them that are independent of the number of segments they occupy. Conflating these concepts doesn't simplify anything and just confuses the terminology and APIs. Implementation needs to know this. As it says above, in the worst case all packets in the pool have only single segment and thus the max number of packet metadata objects is ‘num_bufs’. Number of segments per packet is not a constant, it depends on received packet lengths (and fluctuates with those) It’s an implementation detail if buffer/packet metadata is stored separately from actual buffer space (or next to it). Typically it’s stored next to the buffer space so that the first cache line of the packet covers both the metadata and the first N bytes of packet data/headroom. When packet consists of multiple segments, the first segment holds per packet meta-data, other segments hold just pointers to the data and next segments. The previous linux-generic implementation was designed like that. -Petri int buf_type; /** Buffer type */ } odp_buffer_pool_param_t; -- 2.2.1
Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Tuesday, December 23, 2014 3:18 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Bill Fischofer; Mike Holmes; lng-odp-forward Subject: Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one On 23 December 2014 at 10:51, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: -Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Monday, December 22, 2014 4:23 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Bill Fischofer; Mike Holmes; lng-odp-forward Subject: Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one On 22 December 2014 at 14:10, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: Because the thread will exit the schedule loop, it has to pause first and then run sched loop until the potential per thread local scheduler cache is empty (see under). In this specific case, the example terminates when the specified number of timeouts have been received and processed. There is no need to pause the scheduler and drain any prescheduled buffers because when the remain counter reaches zero, all threads are done and should terminate. This is a timer example, not a scheduler example. For a scheduler example, we should demonstrate the proper usage of odp_scheduler_pause() and resume. A throughput optimized scheduler may have pre-scheduled multiple buffers (incl tmo notifications) to a thread local cache. Scheduler expects the thread to continue process new buffers infinitely. Only way for application to tell it's going to take a pause on processing those is odp_schedule_pause() call. If application would not do that (and drain any remaining buffers) those queues pre-scheduled to the thread would suffer a long delay (or even deadlock if the thread exits). So it's an issue any thread need to handle before exiting the schedule loop. Also in the test would hang if one thread exits and fails to process all pre-scheduled timeouts. Other threads would wait infinitely those missing tmos. I understand all of this and this is how a proper scheduler example should work. But this example attempts to be a simplified timer example. When the specified number of timeouts have been received, the worker threads and the whole program terminates (and this is definitively completely artificial from a networking perspective). Yes we don't don't do this in a way that's nice to the scheduler but this isn't really the scope of this example IMO. Sure this can be split into two examples (timer and schedule pause). Still those threads would need to synchronize so that all timeouts are received and after the last one each thread exits gracefully (without program hang/crash/memory leak). -Petri If the timer example can't just be a simplified timer example perhaps we should put a bullet in it? -Petri -Petri int done = 0; while (1) { odp_timeout_t tmo; if (done) buf = odp_schedule(queue, ODP_SCHED_NO_WAIT); else buf = odp_schedule(queue, ODP_SCHED_WAIT); if (buf == ODP_BUFFER_INVALID) break; tmo = odp_timeout_from_buffer(buf); tick = odp_timeout_tick(tmo); EXAMPLE_DBG( [%i] timeout, tick %PRIu64\n, thr, tick); odp_buffer_free(buf); num--; if (num == 0) { odp_schedule_pause(); done = 1; continue; } tick += period; odp_timer_absolute_tmo(test_timer, tick, queue, ODP_BUFFER_INVALID); } From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Friday, December 19, 2014 10:38 PM To: Mike Holmes Cc: lng-odp-forward Subject: Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one Typo in the title (odp_schdule_one). Presumably Maxim can fix during merge? On Fri, Dec 19, 2014 at 2:34 PM, Mike Holmes mike.hol...@linaro.org wrote: Signed-off-by: Mike Holmes mike.hol...@linaro.org --- example/timer
Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one
-Original Message- From: ext Ola Liljedahl [mailto:ola.liljed...@linaro.org] Sent: Monday, December 22, 2014 4:23 PM To: Savolainen, Petri (NSN - FI/Espoo) Cc: ext Bill Fischofer; Mike Holmes; lng-odp-forward Subject: Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one On 22 December 2014 at 14:10, Savolainen, Petri (NSN - FI/Espoo) petri.savolai...@nsn.com wrote: Because the thread will exit the schedule loop, it has to pause first and then run sched loop until the potential per thread local scheduler cache is empty (see under). In this specific case, the example terminates when the specified number of timeouts have been received and processed. There is no need to pause the scheduler and drain any prescheduled buffers because when the remain counter reaches zero, all threads are done and should terminate. This is a timer example, not a scheduler example. For a scheduler example, we should demonstrate the proper usage of odp_scheduler_pause() and resume. A throughput optimized scheduler may have pre-scheduled multiple buffers (incl tmo notifications) to a thread local cache. Scheduler expects the thread to continue process new buffers infinitely. Only way for application to tell it's going to take a pause on processing those is odp_schedule_pause() call. If application would not do that (and drain any remaining buffers) those queues pre-scheduled to the thread would suffer a long delay (or even deadlock if the thread exits). So it's an issue any thread need to handle before exiting the schedule loop. Also in the test would hang if one thread exits and fails to process all pre-scheduled timeouts. Other threads would wait infinitely those missing tmos. -Petri -Petri int done = 0; while (1) { odp_timeout_t tmo; if (done) buf = odp_schedule(queue, ODP_SCHED_NO_WAIT); else buf = odp_schedule(queue, ODP_SCHED_WAIT); if (buf == ODP_BUFFER_INVALID) break; tmo = odp_timeout_from_buffer(buf); tick = odp_timeout_tick(tmo); EXAMPLE_DBG( [%i] timeout, tick %PRIu64\n, thr, tick); odp_buffer_free(buf); num--; if (num == 0) { odp_schedule_pause(); done = 1; continue; } tick += period; odp_timer_absolute_tmo(test_timer, tick, queue, ODP_BUFFER_INVALID); } From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Friday, December 19, 2014 10:38 PM To: Mike Holmes Cc: lng-odp-forward Subject: Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one Typo in the title (odp_schdule_one). Presumably Maxim can fix during merge? On Fri, Dec 19, 2014 at 2:34 PM, Mike Holmes mike.hol...@linaro.org wrote: Signed-off-by: Mike Holmes mike.hol...@linaro.org --- example/timer/odp_timer_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 0d6e31a..6d2609a 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -84,7 +84,7 @@ static void test_abs_timeouts(int thr, test_args_t *args) while (1) { odp_timeout_t tmo; - buf = odp_schedule_one(queue, ODP_SCHED_WAIT); + buf = odp_schedule(queue, ODP_SCHED_WAIT); tmo = odp_timeout_from_buffer(buf); tick = odp_timeout_tick(tmo); -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv3 1/2] api: queue: add odp_queue_sched_prio and odp_queue_sched_group
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Ciprian Barbu Sent: Thursday, December 18, 2014 3:35 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv3 1/2] api: queue: add odp_queue_sched_prio and odp_queue_sched_group Signed-off-by: Ciprian Barbu ciprian.ba...@linaro.org --- platform/linux-generic/include/api/odp_queue.h | 22 ++ 1 file changed, 22 insertions(+) diff --git a/platform/linux-generic/include/api/odp_queue.h b/platform/linux-generic/include/api/odp_queue.h index b8ac4bb..ef84d6f 100644 --- a/platform/linux-generic/include/api/odp_queue.h +++ b/platform/linux-generic/include/api/odp_queue.h @@ -222,6 +222,28 @@ odp_queue_type_t odp_queue_type(odp_queue_t queue); odp_schedule_sync_t odp_queue_sched_type(odp_queue_t queue); /** + * Queue priority + * + * @note Passing an invalid queue_handle will result in UNDEFINED behavior + * + * @param queue Queue handle + * + * @return Queue schedule priority + */ +odp_schedule_prio_t odp_queue_sched_prio(odp_queue_t queue); + +/** + * Queue group + * + * @note Passing an invalid queue_handle will result in UNDEFINED behavior + * + * @param queue Queue handle + * + * @return Queue schedule group + */ +odp_schedule_group_t odp_queue_sched_group(odp_queue_t queue); + +/** * @} */ -- 1.8.3.2 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 1/3] api: buffer_pool: Correct buf_size pool param documentation
From: ext Bill Fischofer [mailto:bill.fischo...@linaro.org] Sent: Friday, December 19, 2014 6:09 PM To: Petri Savolainen Cc: lng-odp-forward Subject: Re: [lng-odp] [PATCH 1/3] api: buffer_pool: Correct buf_size pool param documentation On Fri, Dec 19, 2014 at 9:28 AM, Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org wrote: Buf_size parameter defines minimum buffer/segment length. Use 0 for default length. Signed-off-by: Petri Savolainen petri.savolai...@linaro.orgmailto:petri.savolai...@linaro.org --- .../linux-generic/include/api/odp_buffer_pool.h | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/platform/linux-generic/include/api/odp_buffer_pool.h b/platform/linux-generic/include/api/odp_buffer_pool.h index 4da5f84..27e816d 100644 --- a/platform/linux-generic/include/api/odp_buffer_pool.h +++ b/platform/linux-generic/include/api/odp_buffer_pool.h @@ -35,18 +35,19 @@ extern C { /** * Buffer pool parameters * Used to communicate buffer pool creation options. + * + * @see ODP_CONFIG_PACKET_BUF_LEN_MIN, ODP_CONFIG_BUFFER_ALIGN_MIN, + * ODP_CONFIG_BUFFER_ALIGN_MAX */ typedef struct odp_buffer_pool_param_t { - uint32_t buf_size; /** Buffer size in bytes. The maximum - number of bytes application will - store in each buffer. For packets, this - is the maximum packet data length, and - configured headroom and tailroom will be - added to this number */ - uint32_t buf_align; /** Minimum buffer alignment in bytes. - Valid values are powers of two. Use 0 - for default alignment. Default will - always be a multiple of 8. */ + uint32_t buf_size; /** Minimum buffer length in bytes. For packets, +this is the minimum segment buffer length. The +length includes head-/tailroom bytes. Use 0 for +default length. */ This is confusing. Presumably for buffers of type ODP_BUFFER_TYPE_PACKET this is a synonym for ODP_CONFIG_PACKET_BUF_LEN_MIN. However, how is a 0 value to be interpreted for other buffer types? Need to specify that here. In the current code it is legitimate to specify a buf_size of zero as that means that buffers will consist only of metadata. Buffers of type ODP_BUFFER_TYPE_TIMEOUT fall into that category, for example. Since this is a buffer structure, not a packet structure, the documentation should reflect that. User should use zero when -the buffer type has only meta-data -user is going to use the default segment size for packets (== PACKET_BUF_LEN_MIN) Beyond this, as we discussed yesterday, a portable application really has no idea what segment sizes are being used by the underlying implementation, nor should it care. The only application-observable impact of segmentation is on packet addressability. As written, this spec precludes an SoC that has fixed-sized HW-managed segments from being ODP compliant. You've argued that an implementation can restrict acceptable values for this parameter but then the application is just echoing back the ODP_CONFIG variables here, so what is the point of this variable? Most SoCs do not have tight limitations for segment size. When limits are defined with standard config defines, application can adapt to those limits and optimize segmentation for its use cases when limitations are loose (in the common case). The purpose of buf_size and num_bufs is to allow the implementation to calculate the amount of storage it needs to reserve to support the buffer pool. So if an application says I want N buffers of maximum size S that makes sense. Saying I want N things that will be divided into some unspecified number of segments of size S is ambiguous because N is no longer determinate (this was one of the design issues with the original buffer pool implementation). So if num_bufs is no longer determinate, what is it's purpose? It needs more documentation, but for packets it’s total number of segments (for raw buffers and timers it’s number of those things). At the same time, it’s the total number of packets (of single segment). If it would be the total number of any size packets, segmentation would not improve memory usage (which it should do) since implementations would need to reserve memory for the worst case (all packets being the max size) anyway. -Petri + uint32_t buf_align; /** Minimum buffer alignment in bytes. Valid values +are powers of two. Use 0 for default +alignment. Default will always be a multiple +of 8. */ uint32_t num_bufs; /** Number of buffers in the
Re: [lng-odp] [PATCHv3] linux-generic: packet: streamline packet add/rem data
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Thursday, December 18, 2014 1:15 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv3] linux-generic: packet: streamline packet add/rem data Ensure packet parser metadata is copied from old to new packet as part of add/rem data operations. Signed-off-by: Bill Fischofer bill.fischo...@linaro.org --- v3 removes reparsing in all cases platform/linux-generic/include/odp_packet_internal.h | 20 platform/linux-generic/odp_packet.c | 6 -- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 068f969..54a12b5 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -187,6 +187,26 @@ static inline void packet_init(pool_entry_t *pool, (pool-s.headroom + size); } +static inline void copy_packet_parser_metadata(odp_packet_hdr_t *src_hdr, +odp_packet_hdr_t *dst_hdr) +{ + dst_hdr-input_flags= src_hdr-input_flags; + dst_hdr-error_flags= src_hdr-error_flags; + dst_hdr-output_flags = src_hdr-output_flags; + + dst_hdr-l2_offset = src_hdr-l2_offset; + dst_hdr-l3_offset = src_hdr-l3_offset; + dst_hdr-l4_offset = src_hdr-l4_offset; + dst_hdr-payload_offset = src_hdr-payload_offset; + + dst_hdr-vlan_s_tag = src_hdr-vlan_s_tag; + dst_hdr-vlan_c_tag = src_hdr-vlan_c_tag; + dst_hdr-l3_protocol= src_hdr-l3_protocol; + dst_hdr-l3_len = src_hdr-l3_len; + dst_hdr-l4_protocol= src_hdr-l4_protocol; + dst_hdr-l4_len = src_hdr-l4_len; +} + static inline void *packet_map(odp_packet_hdr_t *pkt_hdr, uint32_t offset, uint32_t *seglen) { diff --git a/platform/linux-generic/odp_packet.c b/platform/linux- generic/odp_packet.c index 65e6288..a78b3d1 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -396,12 +396,13 @@ odp_packet_t odp_packet_add_data(odp_packet_t pkt, uint32_t offset, newpkt = ODP_PACKET_INVALID; } else { odp_packet_hdr_t *new_hdr = odp_packet_hdr(newpkt); + new_hdr-input = pkt_hdr-input; new_hdr-buf_hdr.buf_u64 = pkt_hdr-buf_hdr.buf_u64; odp_atomic_store_u32( new_hdr-buf_hdr.ref_count, odp_atomic_load_u32( pkt_hdr-buf_hdr.ref_count)); - _odp_packet_parse(newpkt); + copy_packet_parser_metadata(pkt_hdr, new_hdr); odp_packet_free(pkt); } } @@ -431,12 +432,13 @@ odp_packet_t odp_packet_rem_data(odp_packet_t pkt, uint32_t offset, newpkt = ODP_PACKET_INVALID; } else { odp_packet_hdr_t *new_hdr = odp_packet_hdr(newpkt); + new_hdr-input = pkt_hdr-input; new_hdr-buf_hdr.buf_u64 = pkt_hdr-buf_hdr.buf_u64; odp_atomic_store_u32( new_hdr-buf_hdr.ref_count, odp_atomic_load_u32( pkt_hdr-buf_hdr.ref_count)); - _odp_packet_parse(newpkt); + copy_packet_parser_metadata(pkt_hdr, new_hdr); odp_packet_free(pkt); } } -- 1.8.3.2 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one
Because the thread will exit the schedule loop, it has to pause first and then run sched loop until the potential per thread local scheduler cache is empty (see under). -Petri int done = 0; while (1) { odp_timeout_t tmo; if (done) buf = odp_schedule(queue, ODP_SCHED_NO_WAIT); else buf = odp_schedule(queue, ODP_SCHED_WAIT); if (buf == ODP_BUFFER_INVALID) break; tmo = odp_timeout_from_buffer(buf); tick = odp_timeout_tick(tmo); EXAMPLE_DBG( [%i] timeout, tick %PRIu64\n, thr, tick); odp_buffer_free(buf); num--; if (num == 0) { odp_schedule_pause(); done = 1; continue; } tick += period; odp_timer_absolute_tmo(test_timer, tick, queue, ODP_BUFFER_INVALID); } From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Friday, December 19, 2014 10:38 PM To: Mike Holmes Cc: lng-odp-forward Subject: Re: [lng-odp] [PATCH v2 2/3] example: odp_timer_test: remove use of odp_schdule_one Typo in the title (odp_schdule_one). Presumably Maxim can fix during merge? On Fri, Dec 19, 2014 at 2:34 PM, Mike Holmes mike.hol...@linaro.orgmailto:mike.hol...@linaro.org wrote: Signed-off-by: Mike Holmes mike.hol...@linaro.orgmailto:mike.hol...@linaro.org --- example/timer/odp_timer_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 0d6e31a..6d2609a 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -84,7 +84,7 @@ static void test_abs_timeouts(int thr, test_args_t *args) while (1) { odp_timeout_t tmo; - buf = odp_schedule_one(queue, ODP_SCHED_WAIT); + buf = odp_schedule(queue, ODP_SCHED_WAIT); tmo = odp_timeout_from_buffer(buf); tick = odp_timeout_tick(tmo); -- 2.1.0 ___ lng-odp mailing list lng-odp@lists.linaro.orgmailto:lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCHv7 3/4] api: pktio: remove odp_pktio_set_mtu
Reviewed-by: Petri Savolainen petri.savolai...@linaro.org -Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Maxim Uvarov Sent: Friday, December 19, 2014 1:47 PM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv7 3/4] api: pktio: remove odp_pktio_set_mtu Not all hardware can change MTU size from ODP application. Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- example/packet/odp_pktio.c | 27 -- platform/linux-generic/include/api/odp_packet_io.h | 13 --- platform/linux-generic/odp_packet_io.c | 42 - - 3 files changed, 82 deletions(-) diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c index a323ec2..0a38ec2 100644 --- a/example/packet/odp_pktio.c +++ b/example/packet/odp_pktio.c @@ -70,7 +70,6 @@ typedef struct { char **if_names;/** Array of pointers to interface names */ int mode; /** Packet IO mode */ odp_buffer_pool_t pool; /** Buffer pool for packet IO */ - int mtu;/** Pktio dev MTU */ } appl_args_t; /** @@ -80,7 +79,6 @@ typedef struct { char *pktio_dev;/** Interface name to use */ odp_buffer_pool_t pool; /** Buffer pool for packet IO */ int mode; /** Thread mode */ - int mtu;/** Pktio dev MTU */ } thread_args_t; /** @@ -145,14 +143,6 @@ static void *pktio_queue_thread(void *arg) return NULL; } - /* Change mtu if requested */ - if (thr_args-mtu) { - ret = odp_pktio_set_mtu(pktio, thr_args-mtu); - if (ret != 0) - EXAMPLE_ERR(setting MTU to %d failed\n, - thr_args-mtu); - } - mtu = odp_pktio_mtu(pktio); if (mtu 0) printf(PKTIO: %d, dev %s, MTU: %d\n, @@ -251,7 +241,6 @@ static void *pktio_ifburst_thread(void *arg) unsigned long err_cnt = 0; unsigned long tmp = 0; int mtu; - int ret; thr = odp_thread_id(); thr_args = arg; @@ -273,14 +262,6 @@ static void *pktio_ifburst_thread(void *arg) return NULL; } - /* Change mtu if requested */ - if (thr_args-mtu) { - ret = odp_pktio_set_mtu(pktio, thr_args-mtu); - if (ret != 0) - EXAMPLE_ERR(setting MTU to %d failed\n, - thr_args-mtu); - } - mtu = odp_pktio_mtu(pktio); if (mtu 0) printf(PKTIO: %d, dev %s, MTU: %d\n, @@ -409,7 +390,6 @@ int main(int argc, char *argv[]) args-thread[i].pktio_dev = args-appl.if_names[if_idx]; args-thread[i].pool = pool; args-thread[i].mode = args-appl.mode; - args-thread[i].mtu = args-appl.mtu; if (args-appl.mode == APPL_MODE_PKT_BURST) thr_run_func = pktio_ifburst_thread; @@ -520,13 +500,11 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) {count, required_argument, NULL, 'c'}, {interface, required_argument, NULL, 'i'},/* return 'i' */ {mode, required_argument, NULL, 'm'}, /* return 'm' */ - {mtu, required_argument, NULL, 't'}, /* return 't' */ {help, no_argument, NULL, 'h'}, /* return 'h' */ {NULL, 0, NULL, 0} }; appl_args-mode = -1; /* Invalid, must be changed by parsing */ - appl_args-mtu = 0; while (1) { opt = getopt_long(argc, argv, +c:i:m:t:h, @@ -589,10 +567,6 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) else appl_args-mode = APPL_MODE_PKT_QUEUE; break; - case 't': - appl_args-mtu = atoi(optarg); - break; - case 'h': usage(argv[0]); exit(EXIT_SUCCESS); @@ -666,7 +640,6 @@ static void usage(char *progname) Optional OPTIONS\n -c, --count number Core count.\n -h, --help Display help and exit.\n - -t, --mtuMTU\n environment variables: ODP_PKTIO_DISABLE_SOCKET_MMAP\n ODP_PKTIO_DISABLE_SOCKET_MMSG\n ODP_PKTIO_DISABLE_SOCKET_BASIC\n diff --git a/platform/linux-generic/include/api/odp_packet_io.h b/platform/linux-generic/include/api/odp_packet_io.h index a1ad754..e4577c3 100644 --- a/platform/linux-generic/include/api/odp_packet_io.h +++ b/platform/linux-generic/include/api/odp_packet_io.h @@ -111,19 +111,6 @@ int odp_pktio_inq_remdef(odp_pktio_t id); odp_queue_t
Re: [lng-odp] [PATCHv2] linux-generic: packet: streamline packet add/rem data
-Original Message- From: lng-odp-boun...@lists.linaro.org [mailto:lng-odp- boun...@lists.linaro.org] On Behalf Of ext Bill Fischofer Sent: Wednesday, December 17, 2014 3:57 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [PATCHv2] linux-generic: packet: streamline packet add/rem data Ensure packet perser metadata is copied from old to new packet as part of add/rem data operations that omit packet reparsing. Signed-off-by: Bill Fischofer bill.fischo...@linaro.org --- v2 Ensures that parser metadata is copied if we're not reparsing platform/linux-generic/include/odp_packet_internal.h | 20 platform/linux-generic/odp_packet.c | 12 ++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 068f969..54a12b5 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -187,6 +187,26 @@ static inline void packet_init(pool_entry_t *pool, (pool-s.headroom + size); } +static inline void copy_packet_parser_metadata(odp_packet_hdr_t *src_hdr, +odp_packet_hdr_t *dst_hdr) +{ + dst_hdr-input_flags= src_hdr-input_flags; + dst_hdr-error_flags= src_hdr-error_flags; + dst_hdr-output_flags = src_hdr-output_flags; + + dst_hdr-l2_offset = src_hdr-l2_offset; + dst_hdr-l3_offset = src_hdr-l3_offset; + dst_hdr-l4_offset = src_hdr-l4_offset; + dst_hdr-payload_offset = src_hdr-payload_offset; + + dst_hdr-vlan_s_tag = src_hdr-vlan_s_tag; + dst_hdr-vlan_c_tag = src_hdr-vlan_c_tag; + dst_hdr-l3_protocol= src_hdr-l3_protocol; + dst_hdr-l3_len = src_hdr-l3_len; + dst_hdr-l4_protocol= src_hdr-l4_protocol; + dst_hdr-l4_len = src_hdr-l4_len; +} + static inline void *packet_map(odp_packet_hdr_t *pkt_hdr, uint32_t offset, uint32_t *seglen) { diff --git a/platform/linux-generic/odp_packet.c b/platform/linux- generic/odp_packet.c index 65e6288..43a9419 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -396,12 +396,16 @@ odp_packet_t odp_packet_add_data(odp_packet_t pkt, uint32_t offset, newpkt = ODP_PACKET_INVALID; } else { odp_packet_hdr_t *new_hdr = odp_packet_hdr(newpkt); + new_hdr-input = pkt_hdr-input; new_hdr-buf_hdr.buf_u64 = pkt_hdr-buf_hdr.buf_u64; odp_atomic_store_u32( new_hdr-buf_hdr.ref_count, odp_atomic_load_u32( pkt_hdr-buf_hdr.ref_count)); - _odp_packet_parse(newpkt); + if (offset pkt_hdr-payload_offset) + _odp_packet_parse(newpkt); Handles and pointers must be updated after the operation. User is responsible to update packet meta-data offsets when needed. The operation must not parse the packet again and thus overwrite existing meta-data. E.g. application may have removed all the headers from the packet at this point. Just copy old meta-data to the new packet. From application point of view this operation just added packet length at the offset and returned a new handle to the same packet. Application will update offsets/flags as needed. -Petri + else + copy_packet_parser_metadata(pkt_hdr, new_hdr); odp_packet_free(pkt); } } @@ -431,12 +435,16 @@ odp_packet_t odp_packet_rem_data(odp_packet_t pkt, uint32_t offset, newpkt = ODP_PACKET_INVALID; } else { odp_packet_hdr_t *new_hdr = odp_packet_hdr(newpkt); + new_hdr-input = pkt_hdr-input; new_hdr-buf_hdr.buf_u64 = pkt_hdr-buf_hdr.buf_u64; odp_atomic_store_u32( new_hdr-buf_hdr.ref_count, odp_atomic_load_u32( pkt_hdr-buf_hdr.ref_count)); - _odp_packet_parse(newpkt); + if (offset pkt_hdr-payload_offset) + _odp_packet_parse(newpkt); + else + copy_packet_parser_metadata(pkt_hdr, new_hdr); odp_packet_free(pkt); } } -- 1.8.3.2 ___ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list