This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, master has been updated
via 45caf39520a1f7aac3e40265bc46bc4dba695cbc (commit)
from de255937275a99cebe62f159f3fc7c4b70bc04bb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 45caf39520a1f7aac3e40265bc46bc4dba695cbc
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Thu Jan 17 11:12:16 2019 +0200
linux-gen: dpdk: add a fallback value for the number of numa nodes
numa_num_configured_nodes() may return 0 on some platforms. In that case
use 1 as a replacement value.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 1edd2488..1d322057 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -1197,7 +1197,11 @@ static int dpdk_pktio_init(void)
}
mem_str_len = snprintf(NULL, 0, "%d,", DPDK_MEMORY_MB);
+
+ /* numa_num_configured_nodes() may return 0 on some platforms */
numa_nodes = numa_num_configured_nodes();
+ if (numa_nodes <= 0)
+ numa_nodes = 1;
char mem_str[mem_str_len * numa_nodes];
-----------------------------------------------------------------------
Summary of changes:
platform/linux-generic/pktio/dpdk.c | 4 ++++
1 file changed, 4 insertions(+)
hooks/post-receive
--
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, master has been updated
via de255937275a99cebe62f159f3fc7c4b70bc04bb (commit)
from c419dc00dd13fc2760ae1dbe370a3285893c58f6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit de255937275a99cebe62f159f3fc7c4b70bc04bb
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Wed Jan 16 15:31:51 2019 +0200
test: odp_pktio_ordered: add missing schedule_config initialization
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reported-by: Jari Mustajärvi <jari.mustajarvi(a)nokia-bell-labs.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/test/performance/odp_pktio_ordered.c b/test/performance/odp_pktio_ordered.c
index 15229aeb..51ec03ce 100644
--- a/test/performance/odp_pktio_ordered.c
+++ b/test/performance/odp_pktio_ordered.c
@@ -1130,7 +1130,8 @@ int main(int argc, char *argv[])
/* Parse and store the application arguments */
parse_args(argc, argv, &gbl_args->appl);
- odp_schedule_config(NULL);
+ odp_schedule_config_init(&schedule_config);
+ odp_schedule_config(&schedule_config);
if (gbl_args->appl.in_mode == SCHED_ORDERED) {
/* At least one ordered lock required */
-----------------------------------------------------------------------
Summary of changes:
test/performance/odp_pktio_ordered.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
hooks/post-receive
--
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, master has been updated
via c419dc00dd13fc2760ae1dbe370a3285893c58f6 (commit)
from eac3c037e7547b1ed1a15f0ee2e0daccacc88ec5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c419dc00dd13fc2760ae1dbe370a3285893c58f6
Author: Bill Fischofer <bill.fischofer(a)linaro.org>
Date: Thu Dec 27 10:04:43 2018 -0600
doc: userguide: add documentation for flow aware scheduler mode
Update the ODP User Guide to include information on scheduler
capabilities and configuration and operating in flow aware mode.
Signed-off-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Reviewed-by: Petri Savolainen <petri.savolainen(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc
index 8ed581f5..4ec7cd72 100644
--- a/doc/users-guide/users-guide.adoc
+++ b/doc/users-guide/users-guide.adoc
@@ -965,7 +965,7 @@ same value on all ODP threads, for a given memory block, in this case)
Note that ODP implementations may have restrictions of the amount of memory
which can be allocated with this flag.
-== Queues
+== Queues and the Scheduler
Queues are the fundamental event sequencing mechanism provided by ODP and all
ODP applications make use of them either explicitly or implicitly. Queues are
created via the 'odp_queue_create()' API that returns a handle of type
@@ -1184,11 +1184,179 @@ until the locking order for this lock for all prior events has been resolved
and then enters the critical section. The *odp_schedule_order_unlock()* call
releases the critical section and allows the next order to enter it.
+=== Scheduler Capabilities and Configuration
+As with other ODP components, the ODP scheduler offers a range of capabilities
+and configuration options that are used by applications to control its
+behavior.
+
+The sequence of API calls used by applications that make use of the scheduler
+is as follows:
+
+.ODP API Scheduler Usage
+[source,c]
+-----
+odp_schedule_capability()
+odp_schedule_config_init()
+odp_schedule_config()
+odp_schedule()
+-----
+The `odp_schedule_capability()` API returns an `odp_schedule_capability_t`
+struct that defines various limits and capabilities offered by this
+implementation of the ODP scheduler:
+
+.ODP Scheduler Capabilities
+[source,c]
+-----
+/**
+ * Scheduler capabilities
+ */
+typedef struct odp_schedule_capability_t {
+ /** Maximum number of ordered locks per queue */
+ uint32_t max_ordered_locks;
+
+ /** Maximum number of scheduling groups */
+ uint32_t max_groups;
+
+ /** Number of scheduling priorities */
+ uint32_t max_prios;
+
+ /** Maximum number of scheduled (ODP_BLOCKING) queues of the default
+ * size. */
+ uint32_t max_queues;
+
+ /** Maximum number of events a scheduled (ODP_BLOCKING) queue can store
+ * simultaneously. The value of zero means that scheduled queues do not
+ * have a size limit, but a single queue can store all available
+ * events. */
+ uint32_t max_queue_size;
+
+ /** Maximum flow ID per queue
+ *
+ * Valid flow ID range in flow aware mode of scheduling is from 0 to
+ * this maximum value. So, maximum number of flows per queue is this
+ * value plus one. A value of 0 indicates that flow aware mode is not
+ * supported. */
+ uint32_t max_flow_id;
+
+ /** Lock-free (ODP_NONBLOCKING_LF) queues support.
+ * The specification is the same as for the blocking implementation. */
+ odp_support_t lockfree_queues;
+
+ /** Wait-free (ODP_NONBLOCKING_WF) queues support.
+ * The specification is the same as for the blocking implementation. */
+ odp_support_t waitfree_queues;
+
+} odp_schedule_capability_t;
+-----
+This struct indicates the various scheduling limits supported by this ODP
+implementation. Of note is the `max_flow_id` capability, which indicates
+whether this implementation is able to operate in _flow aware mode_.
+
+==== Flow Aware Scheduling
+A _flow_ is a sequence of events that share some application-specific meaning
+and context. A good example of a flow might be a TCP connection. Various
+events associated with that connection, such as packets containing
+connection data, as well as associated timeout events used for transmission
+control, are logically connected and meaningful to the application processing
+that TCP connection.
+
+Normally a single flow is associated with an ODP queue. That is, all events
+on a given queue belong to the same flow. So the queue id is synonymous with
+the flow id for those events. However, this is not without drawbacks. Queues
+are relatively heavyweight objects and provide both synchronization as well as
+user contexts. The number of queues supported by a given implementation
+(`max_queues`) may be less than the number of flows an application needs to
+be able to process.
+
+To address these needs, ODP allows schedulers to operate in flow aware mode
+in which flow id is maintained separately as part of each event. Two new
+APIs:
+
+* `odp_event_flow_id()`
+* `odp_event_flow_id_set()`
+
+are used to query and set a 32-bit flow id associated with individual events.
+The assignment and interpretation of individual flow ids is under application
+control.
+
+When operating in flow aware mode, it is the combination of flow id and
+queue id that is used by the scheduler in making scheduling decisions. So,
+for example, an Atomic queue would normally be able to dispatch events only a
+single thread at a time. When operating in flow aware mode, however, the
+scheduler will provide this exclusion only when two events on the same atomic
+queue have the same flow id. If they have different flow ids, then they can be
+scheduled concurrently to different threads.
+
+Note that when operating in this mode, any sharing of queue context must be
+done with application-provided synchronization controls (similar to how
+parallel queues behave).
+
+==== Scheduler Configuration
+After determining the scheduler's capabilities, but before starting to use
+the scheduler to process events, applications must configure the scheduler
+by calling `odp_schedule_config()`.
+
+The argument to this call is the `odp_schedule_config_t` struct:
+
+.ODP Scheduler Configuration
+[source,c]
+-----
+/**
+ * Schedule configuration
+ */
+typedef struct odp_schedule_config_t {
+ /** Maximum number of scheduled queues to be supported.
+ *
+ * @see odp_schedule_capability_t
+ */
+ uint32_t num_queues;
+
+ /** Maximum number of events required to be stored simultaneously in
+ * scheduled queue. This number must not exceed 'max_queue_size'
+ * capability. A value of 0 configures default queue size supported by
+ * the implementation.
+ */
+ uint32_t queue_size;
+
+ /** Maximum flow ID per queue
+ *
+ * This value must not exceed 'max_flow_id' capability. Flow aware
+ * mode of scheduling is enabled when the value is greater than 0.
+ * The default value is 0.
+ *
+ * Application can assign events to specific flows by calling
+ * odp_event_flow_id_set() before enqueuing events into a scheduled
+ * queue. When in flow aware mode, the event flow id value affects
+ * scheduling of the event and synchronization is maintained per flow
+ * within each queue.
+ *
+ * Depeding on implementation, there may be much more flows supported
+ * than queues, as flows are lightweight entities.
+ *
+ * @see odp_schedule_capability_t, odp_event_flow_id()
+ */
+ uint32_t max_flow_id;
+
+} odp_schedule_config_t;
+-----
+The `odp_schedule_config_init()` API should be used to initialize this
+struct to its default values. The application then sets whatever
+overrides it needs prior to calling `odp_schedule_config()` to activate
+them. Note that `NULL` may be passed as the argument to `odp_schedule_config()`
+if the application simply wants to use the implementation-defined default
+configuration. In the default configuration, the scheduler does not operate in
+flow aware mode.
+
+Once configured, `odp_schedule()` calls can be made to get events. It is
+a programming error to attempt to use the scheduler before it has been
+configured.
+
=== Queue Scheduling Summary
NOTE: Both ordered and parallel queues improve throughput over atomic queues
due to parallel event processing, but require that the application take
-steps to ensure context data synchronization if needed.
+steps to ensure context data synchronization if needed. The same is true for
+atomic queues when the scheduler is operating in flow aware mode.
include::users-guide-packet.adoc[]
-----------------------------------------------------------------------
Summary of changes:
doc/users-guide/users-guide.adoc | 172 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 170 insertions(+), 2 deletions(-)
hooks/post-receive
--
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, api-next has been updated
via 2c93306bd2efe1a5716067609949eccd67d493a3 (commit)
from 00385dbab270b585291cf197f62cd4d7f92c2af9 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2c93306bd2efe1a5716067609949eccd67d493a3
Author: Bill Fischofer <bill.fischofer(a)linaro.org>
Date: Fri Dec 28 11:41:02 2018 -0600
doc: userguide: add section for compression support
Add section to User's Guide for compression and
decompression support
Signed-off-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Reviewed-by: Petri Savolainen <petri.savolainen(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/doc/users-guide/Makefile.am b/doc/users-guide/Makefile.am
index 6b2e818d..f5386dfa 100644
--- a/doc/users-guide/Makefile.am
+++ b/doc/users-guide/Makefile.am
@@ -2,6 +2,7 @@ include ../Makefile.inc
SRC = users-guide.adoc \
users-guide-cls.adoc \
+ users-guide-comp.adoc \
users-guide-crypto.adoc \
users-guide-ipsec.adoc \
users-guide-packet.adoc \
diff --git a/doc/users-guide/users-guide-comp.adoc b/doc/users-guide/users-guide-comp.adoc
new file mode 100644
index 00000000..11a39a0c
--- /dev/null
+++ b/doc/users-guide/users-guide-comp.adoc
@@ -0,0 +1,168 @@
+== Compression services
+ODP provides APIs to perform compression and decompression operations required
+by applications. ODP compression APIs are session based and provide
+compression algorithm offload services, with and without associated
+integrity hashing. This section covers the main compression APIs.
+
+ODP provides support for the following compression algorithms:
+
+`ODP_COMP_ALG_NONE`::
+The null compression algorithm. Used for testing as well as to
+specify hash-only operations.
+`ODP_COMP_ALG_DEFLATE`::
+The deflate compression algorithm specified by
+https://www.ietf.org/rfc/rfc1951.txt[RFC 1951].
+`ODP_COMP_ALG_ZLIB`::
+The ZLIB compression algorithm specified by
+https://www.ietf.org/rfc/rfc1950.txt[RFC 1950].
+`ODP_COMP_ALG_LZS`::
+The LZS compression algorithm as specified by ANSI X3.241.
+
+The following hash algorithms are also defined to be used in conjunction
+with these compression algorithms:
+
+`ODP_COMP_HASH_ALG_NONE`::
+A dummy that specifies no associated hashing is to be performed.
+`ODP_COMP_HASH_ALG_SHA1`::
+SHA-1 hashing with a 64-bit digest length.
+`ODP_COMP_HASH_ALG_SHA256`::
+SHA-2 hashing with a 256-bit digest length.
+
+=== Compression Sessions
+ODP compression services are session based and operate on input packets and
+deliver output packets. A compression session (`odp_comp_session_t`) provides
+the context for controlling the operations performed on packets. All of the
+packets processed by a session share the parameters that define the
+session.
+
+ODP supports synchronous and asynchronous compression sessions. For
+asynchronous sessions, the output of a compression operation is posted to
+a queue defined as the completion queue in its session parameters.
+
+Other session parameters include: the type of operation (compression or
+decompression), the operating mode (synchronous or asynchronous), the
+compression and hashing algorithms to be used, as well as any parameters
+needed by those algorithms to configure them. For asynchronous compression
+sessions, the application also specifies whether queue order must be
+maintained. Additional throughput may be achieved in some implementations if
+strict ordering is not required.
+
+The parameters that describe the characteristics of a compression session
+are encoded in the `odp_comp_session_param_t` struct that is passed to the
+`odp_comp_session_create()` API. A successful call returns an
+`odp_comp_session_t` handle that is then used as an input parameter to
+compression operation calls.
+
+When an application is finished with a compression session, the
+`odp_comp_session_destroy()` API is used to release the resources
+associated with an `odp_comp_session_t`.
+
+=== Compression operations
+After session creation, a compression operation can be applied to a packet
+in one of two ways: synchronous and asynchronous, depending on how the
+session was created.
+
+==== Synchronous compression operations
+Synchronous compression operations take the following form:
+
+.Invoking synchronous compression operations
+[source,c]
+-----
+int odp_comp_op(const odp_packet_t pkt_in[], odp_packet_t pkt_out[],
+ int num_pkt, const odp_comp_packet_op_param_t param[]);
+-----
+An input packet array is compressed/decompressed into a supplied output
+packet array under the control of a supplied parameter struct.
+
+The supplied `odp_comp_packet_op_param_t` struct looks as follows:
+
+.ODP compression parameter structure
+[source,c]
+-----
+/**
+ * Compression per packet operation parameters
+ */
+typedef struct odp_comp_packet_op_param_t {
+ /** Session handle */
+ odp_comp_session_t session;
+
+ /** Input data range to process. where,
+ *
+ * offset - starting offset
+ * length - length of data for compression operation
+ * */
+ odp_packet_data_range_t in_data_range;
+
+ /** Output packet data range.
+ * Indicates where processed packet will be written. where,
+ *
+ * offset - starting offset
+ * length - length of buffer available for output
+ *
+ * Output packet data is not modified outside of this provided data
+ * range. If output data length is not sufficient for compression
+ * operation ODP_COMP_STATUS_OUT_OF_SPACE_TERM error will occur
+ */
+ odp_packet_data_range_t out_data_range;
+} odp_comp_packet_op_param_t;
+-----
+Note that this struct points to the session used to control the operation and
+specifies the input and output packet data ranges to be used for the
+operation. For input, the output data range must be sufficiently sized to
+contain the result of the operation to avoid an out of space error. Upon
+output, this range is updated to reflect the actual data written. This
+information can then be used to trim off any excess padding before
+continuing processing of the output packet(s).
+
+==== Asynchronous compression operations
+Asynchronous compression operations are invoked with a slightly
+different API:
+
+.Invoking asynchronous compression operations
+[source,c]
+-----
+int odp_comp_op_enq(const odp_packet_t pkt_in[], odp_packet_t pkt_out[],
+ int num_pkt, const odp_comp_packet_op_param_t param[]);
+-----
+Here the session pointed to by the `odp_comp_packet_op_param_t` indicates
+the completion queue to be used for the operation, so a zero return from
+`odp_comp_op_enq()` means only that the operation was successfully
+initiated.
+
+The resulting completion queue can then be polled either directly
+via `odp_queue_deq()` or indirectly via the scheduler. The result is
+presented as an event of type `ODP_EVENT_PACKET` with subtype
+`ODP_EVENT_PACKET_COMP`.
+
+When receiving this event, the `odp_comp_packet_from_event()` API is used to
+convert the event into a usable `odp_packet_t`, and the `odp_comp_result()`
+API is used to retrieve the `odp_comp_packet_result_t` metadata associated
+with this packet. This struct looks as follows:
+
+.Compression output result
+[source,c]
+-----
+/**
+ * Compression packet operation result
+ */
+typedef struct odp_comp_packet_result_t {
+ /** Operation status code */
+ odp_comp_status_t status;
+
+ /** Input packet handle */
+ odp_packet_t pkt_in;
+
+ /** Output packet data range
+ * Specifies offset and length of data resulting from compression
+ * operation. When hashing is configured output_data_range.len equals
+ * length of output data + length of digest.
+ */
+ odp_packet_data_range_t output_data_range;
+} odp_comp_packet_result_t;
+-----
+Note that if the originating `odp_comp_op_enq()` call specified an array of
+input packets, each of these generates a separate result event. The order of
+these events on the completion queue associated with the compression session is
+controlled by the session's `packet_order` flag. If this flag is set then the
+results will be in the same order as the original input list. If not, then
+results are free to be reordered to make them available as soon as possible.
diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc
index 8ed581f5..dce457ff 100644
--- a/doc/users-guide/users-guide.adoc
+++ b/doc/users-guide/users-guide.adoc
@@ -1200,6 +1200,8 @@ include::users-guide-crypto.adoc[]
include::users-guide-ipsec.adoc[]
+include::users-guide-comp.adoc[]
+
include::users-guide-tm.adoc[]
include::users-guide-cls.adoc[]
-----------------------------------------------------------------------
Summary of changes:
doc/users-guide/Makefile.am | 1 +
doc/users-guide/users-guide-comp.adoc | 168 ++++++++++++++++++++++++++++++++++
doc/users-guide/users-guide.adoc | 2 +
3 files changed, 171 insertions(+)
create mode 100644 doc/users-guide/users-guide-comp.adoc
hooks/post-receive
--
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, master has been updated
via eac3c037e7547b1ed1a15f0ee2e0daccacc88ec5 (commit)
from 87a81d8b4feb08fdf60a960ac2b003233fc0ae3b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit eac3c037e7547b1ed1a15f0ee2e0daccacc88ec5
Author: Petri Savolainen <petri.savolainen(a)linaro.org>
Date: Fri Jan 4 16:21:02 2019 +0200
dependencies: add libconfig package name
Added apt-get and yum package names for libconfig.
Signed-off-by: Petri Savolainen <petri.savolainen(a)linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/DEPENDENCIES b/DEPENDENCIES
index 10a9861c..d5214663 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -19,7 +19,13 @@ Prerequisites for building the OpenDataPlane (ODP) API
3. Required packages
- Libraries currently required to link: openssl, libatomic, libconfig
+ Libraries currently required to link: libconfig, openssl, libatomic
+
+ On Debian/Ubuntu systems:
+ $ sudo apt-get install libconfig-dev
+
+ On CentOS/RedHat/Fedora systems:
+ $ sudo yum install libconfig-devel
It is possible to build ODP without OpenSSL by passing flag
--without-openssl to configure script. However this will result in
-----------------------------------------------------------------------
Summary of changes:
DEPENDENCIES | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
hooks/post-receive
--
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, api-next has been updated
via 525f6e6b3adf629df89d195fbb1959b40ecc8a0d (commit)
via d044b11d7010cc328cca986849a1414c1e46fb53 (commit)
via 9c0ad641faeabbede48fd09b7c91f753186163bd (commit)
via d7913a845c72753758121111cc5da381198ba0f6 (commit)
from 43dd326bf4777a01a0fa75c9c9055376d246e44b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 525f6e6b3adf629df89d195fbb1959b40ecc8a0d
Author: Petri Savolainen <petri.savolainen(a)linaro.org>
Date: Tue Dec 18 16:37:23 2018 +0200
linux-gen: sched: dummy flow aware implementation
Implement flow aware scheduling API with least possible changes.
Scheduler does not care about flow IDs, but synchronizes still
on queue level. This is functionally correct, but does provide
parallelism between different flows of a queue. So, application
does not benefit from using flows, but functions correctly.
Maximum number of flows per queue is limited to 256 just to
minimize number of bytes used in buffer header.
Signed-off-by: Petri Savolainen <petri.savolainen(a)linaro.org>
Reviewed-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov(a)linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/platform/linux-generic/include/odp_buffer_internal.h b/platform/linux-generic/include/odp_buffer_internal.h
index c6e1345d..5e0b2bcc 100644
--- a/platform/linux-generic/include/odp_buffer_internal.h
+++ b/platform/linux-generic/include/odp_buffer_internal.h
@@ -54,6 +54,9 @@ ODP_STATIC_ASSERT(ODP_CONFIG_POOLS <= (0xFF + 1), "TOO_MANY_POOLS");
/* Check that buffer index fit into bit field */
ODP_STATIC_ASSERT(CONFIG_POOL_MAX_NUM <= (0xFFFFFF + 1), "TOO_LARGE_POOL");
+/* Type size limits number of flow IDs supported */
+#define BUF_HDR_MAX_FLOW_ID 255
+
/* Common buffer header */
struct ODP_ALIGNED_CACHE odp_buffer_hdr_t {
/* Combined pool and buffer index */
@@ -94,6 +97,9 @@ struct ODP_ALIGNED_CACHE odp_buffer_hdr_t {
/* Event type. Maybe different than pool type (crypto compl event) */
int8_t event_type;
+ /* Event flow id */
+ uint8_t flow_id;
+
/* Initial buffer tail pointer */
uint8_t *buf_end;
@@ -120,6 +126,20 @@ static inline odp_buffer_t buf_from_buf_hdr(odp_buffer_hdr_t *hdr)
return (odp_buffer_t)hdr;
}
+static inline uint32_t event_flow_id(odp_event_t ev)
+{
+ odp_buffer_hdr_t *buf_hdr = (odp_buffer_hdr_t *)(uintptr_t)ev;
+
+ return buf_hdr->flow_id;
+}
+
+static inline void event_flow_id_set(odp_event_t ev, uint32_t flow_id)
+{
+ odp_buffer_hdr_t *buf_hdr = (odp_buffer_hdr_t *)(uintptr_t)ev;
+
+ buf_hdr->flow_id = flow_id;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/linux-generic/odp_event.c b/platform/linux-generic/odp_event.c
index bdde93e1..efcbc1e2 100644
--- a/platform/linux-generic/odp_event.c
+++ b/platform/linux-generic/odp_event.c
@@ -59,17 +59,14 @@ int odp_event_type_multi(const odp_event_t event[], int num,
return i;
}
-/* For now ODP generic does not support flow awareness,
- * so all flow ids are zero. */
-uint32_t odp_event_flow_id(odp_event_t event ODP_UNUSED)
+uint32_t odp_event_flow_id(odp_event_t event)
{
- return 0;
+ return event_flow_id(event);
}
-void odp_event_flow_id_set(odp_event_t event ODP_UNUSED,
- uint32_t flow_id ODP_UNUSED)
+void odp_event_flow_id_set(odp_event_t event, uint32_t flow_id)
{
- /* Do nothing */
+ event_flow_id_set(event, flow_id);
}
void odp_event_free(odp_event_t event)
diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c
index e5a9cfc7..6176c951 100644
--- a/platform/linux-generic/odp_schedule_basic.c
+++ b/platform/linux-generic/odp_schedule_basic.c
@@ -1579,6 +1579,7 @@ static int schedule_capability(odp_schedule_capability_t *capa)
capa->max_prios = schedule_num_prio();
capa->max_queues = ODP_CONFIG_QUEUES - NUM_INTERNAL_QUEUES;
capa->max_queue_size = queue_glb->config.max_queue_size;
+ capa->max_flow_id = BUF_HDR_MAX_FLOW_ID;
return 0;
}
commit d044b11d7010cc328cca986849a1414c1e46fb53
Author: Petri Savolainen <petri.savolainen(a)linaro.org>
Date: Tue Dec 18 09:55:12 2018 +0200
validation: sched: add flow aware test case
Move scheduler config call into the test suite as some test
cases need non-default config. Scheduler configuration can be
set only once, so all test cases share the config. Flow aware
mode is enabled, when capability allows that.
Signed-off-by: Petri Savolainen <petri.savolainen(a)linaro.org>
Reviewed-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov(a)linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/test/validation/api/scheduler/scheduler.c b/test/validation/api/scheduler/scheduler.c
index 27377580..bdcd7b2d 100644
--- a/test/validation/api/scheduler/scheduler.c
+++ b/test/validation/api/scheduler/scheduler.c
@@ -8,6 +8,7 @@
#include <odp_api.h>
#include "odp_cunit_common.h"
+#include <odp/helper/odph_api.h>
#define MAX_WORKERS_THREADS 32
#define MAX_ORDERED_LOCKS 2
@@ -24,6 +25,9 @@
#define TEST_QUEUE_SIZE_NUM_EV 50
+#define MAX_FLOWS 16
+#define FLOW_TEST_NUM_EV (10 * MAX_FLOWS)
+
#define GLOBALS_SHM_NAME "test_globals"
#define MSG_POOL_NAME "msg_pool"
#define QUEUE_CTX_POOL_NAME "queue_ctx_pool"
@@ -62,6 +66,7 @@ typedef struct {
odp_pool_t pool;
odp_pool_t queue_ctx_pool;
uint32_t max_sched_queue_size;
+ uint64_t num_flows;
odp_ticketlock_t lock;
odp_spinlock_t atomic_lock;
struct {
@@ -1846,6 +1851,32 @@ static int scheduler_suite_init(void)
odp_pool_t pool;
thread_args_t *args;
odp_pool_param_t params;
+ uint64_t num_flows;
+ odp_schedule_capability_t sched_capa;
+ odp_schedule_config_t sched_config;
+
+ if (odp_schedule_capability(&sched_capa)) {
+ printf("odp_schedule_capability() failed\n");
+ return -1;
+ }
+
+ num_flows = 0;
+ odp_schedule_config_init(&sched_config);
+
+ /* Enable flow aware scheduling */
+ if (sched_capa.max_flow_id > 0) {
+ num_flows = MAX_FLOWS;
+ if ((MAX_FLOWS - 1) > sched_capa.max_flow_id)
+ num_flows = sched_capa.max_flow_id + 1;
+
+ sched_config.max_flow_id = num_flows - 1;
+ }
+
+ /* Configure the scheduler. All test cases share the config. */
+ if (odp_schedule_config(&sched_config)) {
+ printf("odp_schedule_config() failed.\n");
+ return -1;
+ }
odp_pool_param_init(¶ms);
params.buf.size = BUF_SIZE;
@@ -1872,6 +1903,8 @@ static int scheduler_suite_init(void)
memset(globals, 0, sizeof(test_globals_t));
+ globals->num_flows = num_flows;
+
globals->num_workers = odp_cpumask_default_worker(&mask, 0);
if (globals->num_workers > MAX_WORKERS)
globals->num_workers = MAX_WORKERS;
@@ -1975,6 +2008,127 @@ static int scheduler_suite_term(void)
return 0;
}
+static int check_flow_aware_support(void)
+{
+ if (globals->num_flows == 0) {
+ printf("\nTest: scheduler_test_flow_aware: SKIPPED\n");
+ return ODP_TEST_INACTIVE;
+ }
+
+ return ODP_TEST_ACTIVE;
+}
+
+static void scheduler_test_flow_aware(void)
+{
+ odp_schedule_capability_t sched_capa;
+ odp_schedule_config_t sched_config;
+ odp_pool_param_t pool_param;
+ odp_pool_t pool;
+ odp_queue_param_t queue_param;
+ odp_queue_t queue, from;
+ uint32_t j, queue_size, num, num_flows, flow_id;
+ odp_buffer_t buf;
+ odp_event_t ev;
+ int i, ret;
+ uint32_t flow_stat[MAX_FLOWS];
+ odp_schedule_sync_t sync[] = {ODP_SCHED_SYNC_PARALLEL,
+ ODP_SCHED_SYNC_ATOMIC,
+ ODP_SCHED_SYNC_ORDERED};
+
+ /* Test should be skipped when no flows */
+ CU_ASSERT_FATAL(globals->num_flows);
+ CU_ASSERT_FATAL(odp_schedule_capability(&sched_capa) == 0);
+
+ num_flows = globals->num_flows;
+
+ queue_size = FLOW_TEST_NUM_EV;
+ odp_schedule_config_init(&sched_config);
+ if (sched_config.queue_size &&
+ queue_size > sched_config.queue_size)
+ queue_size = sched_config.queue_size;
+
+ odp_pool_param_init(&pool_param);
+ pool_param.buf.size = 100;
+ pool_param.buf.align = 0;
+ pool_param.buf.num = FLOW_TEST_NUM_EV;
+ pool_param.type = ODP_POOL_BUFFER;
+
+ pool = odp_pool_create("test_flow_aware", &pool_param);
+
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ for (i = 0; i < 3; i++) {
+ memset(flow_stat, 0, sizeof(flow_stat));
+ flow_id = 0;
+
+ odp_queue_param_init(&queue_param);
+ queue_param.type = ODP_QUEUE_TYPE_SCHED;
+ queue_param.sched.prio = odp_schedule_default_prio();
+ queue_param.sched.sync = sync[i];
+ queue_param.sched.group = ODP_SCHED_GROUP_ALL;
+ queue_param.size = queue_size;
+
+ queue = odp_queue_create("test_flow_aware", &queue_param);
+
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ for (j = 0; j < queue_size; j++) {
+ buf = odp_buffer_alloc(pool);
+ CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
+
+ ev = odp_buffer_to_event(buf);
+
+ odp_event_flow_id_set(ev, flow_id);
+ CU_ASSERT(odp_event_flow_id(ev) == flow_id);
+
+ ret = odp_queue_enq(queue, ev);
+ CU_ASSERT(ret == 0);
+
+ if (ret) {
+ odp_event_free(ev);
+ continue;
+ }
+
+ flow_stat[flow_id]++;
+
+ flow_id++;
+ if (flow_id == num_flows)
+ flow_id = 0;
+ }
+
+ num = 0;
+ for (j = 0; j < 100 * FLOW_TEST_NUM_EV; j++) {
+ ev = odp_schedule(&from, ODP_SCHED_NO_WAIT);
+
+ if (ev == ODP_EVENT_INVALID)
+ continue;
+
+ CU_ASSERT(from == queue);
+
+ flow_id = odp_event_flow_id(ev);
+ flow_stat[flow_id]--;
+
+ odp_event_free(ev);
+ num++;
+ }
+
+ CU_ASSERT(num == queue_size);
+
+ for (j = 0; j < num_flows; j++) {
+ CU_ASSERT(flow_stat[j] == 0);
+ if (flow_stat[j])
+ printf("flow id %" PRIu32 ", missing %" PRIi32
+ " events\n", j, flow_stat[j]);
+ }
+
+ drain_queues();
+ CU_ASSERT_FATAL(odp_queue_destroy(queue) == 0);
+ }
+
+ CU_ASSERT(odp_pool_destroy(pool) == 0);
+}
+
+/* Default scheduler config */
odp_testinfo_t scheduler_suite[] = {
ODP_TEST_INFO(scheduler_test_capa),
ODP_TEST_INFO(scheduler_test_wait_time),
@@ -1985,6 +2139,8 @@ odp_testinfo_t scheduler_suite[] = {
ODP_TEST_INFO(scheduler_test_groups),
ODP_TEST_INFO(scheduler_test_pause_resume),
ODP_TEST_INFO(scheduler_test_ordered_lock),
+ ODP_TEST_INFO_CONDITIONAL(scheduler_test_flow_aware,
+ check_flow_aware_support),
ODP_TEST_INFO(scheduler_test_parallel),
ODP_TEST_INFO(scheduler_test_atomic),
ODP_TEST_INFO(scheduler_test_ordered),
@@ -2025,6 +2181,32 @@ odp_suiteinfo_t scheduler_suites[] = {
ODP_SUITE_INFO_NULL,
};
+static int global_init(odp_instance_t *inst)
+{
+ odp_init_t init_param;
+ odph_helper_options_t helper_options;
+
+ if (odph_options(&helper_options)) {
+ fprintf(stderr, "error: odph_options() failed.\n");
+ return -1;
+ }
+
+ odp_init_param_init(&init_param);
+ init_param.mem_model = helper_options.mem_model;
+
+ if (0 != odp_init_global(inst, &init_param, NULL)) {
+ fprintf(stderr, "error: odp_init_global() failed.\n");
+ return -1;
+ }
+
+ if (0 != odp_init_local(*inst, ODP_THREAD_CONTROL)) {
+ fprintf(stderr, "error: odp_init_local() failed.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
int ret;
@@ -2033,6 +2215,7 @@ int main(int argc, char *argv[])
if (odp_cunit_parse_options(argc, argv))
return -1;
+ odp_cunit_register_global_init(global_init);
ret = odp_cunit_register(scheduler_suites);
if (ret == 0)
commit 9c0ad641faeabbede48fd09b7c91f753186163bd
Author: Petri Savolainen <petri.savolainen(a)linaro.org>
Date: Tue Dec 18 12:56:10 2018 +0200
linux-gen: sched: check that config has been done
Check always on slow path functions that schedule config has
been called. Fast path functions do the check only when
debugging is enabled.
Signed-off-by: Petri Savolainen <petri.savolainen(a)linaro.org>
Reviewed-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov(a)linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c
index 48f232e6..e5a9cfc7 100644
--- a/platform/linux-generic/odp_schedule_basic.c
+++ b/platform/linux-generic/odp_schedule_basic.c
@@ -597,7 +597,10 @@ static int schedule_init_queue(uint32_t queue_index,
int i;
int prio = prio_level_from_api(sched_param->prio);
- ODP_ASSERT(_odp_schedule_configured);
+ if (_odp_schedule_configured == 0) {
+ ODP_ERR("Scheduler has not been configured\n");
+ return -1;
+ }
pri_set_queue(queue_index, prio);
sched->queue[queue_index].grp = sched_param->group;
diff --git a/platform/linux-generic/odp_schedule_if.c b/platform/linux-generic/odp_schedule_if.c
index cb52f155..ba903e58 100644
--- a/platform/linux-generic/odp_schedule_if.c
+++ b/platform/linux-generic/odp_schedule_if.c
@@ -24,10 +24,7 @@ extern const schedule_api_t schedule_scalable_api;
const schedule_fn_t *sched_fn;
const schedule_api_t *sched_api;
-
-#ifdef ODP_DEBUG
int _odp_schedule_configured;
-#endif
uint64_t odp_schedule_wait_time(uint64_t ns)
{
@@ -51,7 +48,10 @@ int odp_schedule_config(const odp_schedule_config_t *config)
int ret;
odp_schedule_config_t defconfig;
- ODP_ASSERT(!_odp_schedule_configured);
+ if (_odp_schedule_configured) {
+ ODP_ERR("Scheduler has been configured already\n");
+ return -1;
+ }
if (!config) {
odp_schedule_config_init(&defconfig);
@@ -59,10 +59,9 @@ int odp_schedule_config(const odp_schedule_config_t *config)
}
ret = sched_api->schedule_config(config);
-#ifdef ODP_DEBUG
+
if (ret >= 0)
_odp_schedule_configured = 1;
-#endif
return ret;
}
diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c
index eec88a60..e7b37895 100644
--- a/platform/linux-generic/odp_schedule_sp.c
+++ b/platform/linux-generic/odp_schedule_sp.c
@@ -375,10 +375,10 @@ static int init_queue(uint32_t qi, const odp_schedule_param_t *sched_param)
odp_schedule_group_t group = sched_param->group;
int prio = 0;
-#ifdef ODP_DEBUG
- if (!_odp_schedule_configured)
- ODP_ABORT("Scheduler not configured!\n");
-#endif
+ if (_odp_schedule_configured == 0) {
+ ODP_ERR("Scheduler has not been configured\n");
+ return -1;
+ }
if (group < 0 || group >= NUM_GROUP)
return -1;
commit d7913a845c72753758121111cc5da381198ba0f6
Author: Petri Savolainen <petri.savolainen(a)linaro.org>
Date: Mon Dec 17 16:03:02 2018 +0200
api: sched: max_flow_id capability
Change max number of flows to max flow ID. This way implementation
can utilize full 32 bits of flow ID space.
Also, note explicitly that odp_schedule_config() must be called
only once.
Signed-off-by: Petri Savolainen <petri.savolainen(a)linaro.org>
Reviewed-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov(a)linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/include/odp/api/spec/schedule.h b/include/odp/api/spec/schedule.h
index 43292124..fa66f260 100644
--- a/include/odp/api/spec/schedule.h
+++ b/include/odp/api/spec/schedule.h
@@ -271,8 +271,8 @@ void odp_schedule_config_init(odp_schedule_config_t *config);
*
* Initialize and configure scheduler with global configuration options
* to schedule events across different scheduled queues.
- * This function must be called before scheduler is used (any other scheduler
- * function is called except odp_schedule_capability() and
+ * This function must be called only once and before scheduler is used
+ * (any other scheduler function is called except odp_schedule_capability() and
* odp_schedule_config_init()) or any queues are created (by application itself
* or by other ODP modules).
* An application can pass NULL value to use default configuration. It will
diff --git a/include/odp/api/spec/schedule_types.h b/include/odp/api/spec/schedule_types.h
index 3648c64e..2acec0db 100644
--- a/include/odp/api/spec/schedule_types.h
+++ b/include/odp/api/spec/schedule_types.h
@@ -196,12 +196,13 @@ typedef struct odp_schedule_capability_t {
* events. */
uint32_t max_queue_size;
- /** Maximum supported flows per queue.
- * Specifies the maximum number of flows per queue supported by the
- * implementation. A value of 0 indicates flow aware mode is not
- * supported.
- */
- uint32_t max_flows;
+ /** Maximum flow ID per queue
+ *
+ * Valid flow ID range in flow aware mode of scheduling is from 0 to
+ * this maximum value. So, maximum number of flows per queue is this
+ * value plus one. A value of 0 indicates that flow aware mode is not
+ * supported. */
+ uint32_t max_flow_id;
/** Lock-free (ODP_NONBLOCKING_LF) queues support.
* The specification is the same as for the blocking implementation. */
@@ -230,21 +231,24 @@ typedef struct odp_schedule_config_t {
*/
uint32_t queue_size;
- /** Number of flows per queue to be supported. Scheduler enables flow
- * aware mode when flow count is configured greater than 1 (up to
- * 'max_flows' capability).
+ /** Maximum flow ID per queue
*
- * Flows are lightweight entities and events can be assigned to
- * specific flows by the application using odp_event_flow_id_set()
- * before enqueuing the event into the scheduler. This value is ignored
- * unless scheduler supports flow aware mode.
+ * This value must not exceed 'max_flow_id' capability. Flow aware
+ * mode of scheduling is enabled when the value is greater than 0.
+ * The default value is 0.
*
- * This number should be less than maximum flow supported by the
- * implementation. The default value is zero.
+ * Application can assign events to specific flows by calling
+ * odp_event_flow_id_set() before enqueuing events into a scheduled
+ * queue. When in flow aware mode, the event flow id value affects
+ * scheduling of the event and synchronization is maintained per flow
+ * within each queue.
*
- * @see odp_schedule_capability_t
+ * Depeding on implementation, there may be much more flows supported
+ * than queues, as flows are lightweight entities.
+ *
+ * @see odp_schedule_capability_t, odp_event_flow_id()
*/
- uint32_t num_flows;
+ uint32_t max_flow_id;
} odp_schedule_config_t;
-----------------------------------------------------------------------
Summary of changes:
include/odp/api/spec/schedule.h | 4 +-
include/odp/api/spec/schedule_types.h | 38 +++--
.../linux-generic/include/odp_buffer_internal.h | 20 +++
platform/linux-generic/odp_event.c | 11 +-
platform/linux-generic/odp_schedule_basic.c | 6 +-
platform/linux-generic/odp_schedule_if.c | 11 +-
platform/linux-generic/odp_schedule_sp.c | 8 +-
test/validation/api/scheduler/scheduler.c | 183 +++++++++++++++++++++
8 files changed, 244 insertions(+), 37 deletions(-)
hooks/post-receive
--
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, master has been updated
via 83eef57df54653245402237837c9e95d1bf3aff4 (commit)
from 6c06c34a051342b2d25444ac65348acc30828b11 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 83eef57df54653245402237837c9e95d1bf3aff4
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Fri Dec 14 10:40:34 2018 +0200
linux-gen: dpdk: fix build with no pmd drivers
Match pattern was added to DPDK_PMDS if no pmd drivers were found.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/m4/odp_dpdk.m4 b/m4/odp_dpdk.m4
index 1072bf2d..2f6662e2 100644
--- a/m4/odp_dpdk.m4
+++ b/m4/odp_dpdk.m4
@@ -6,6 +6,10 @@ AC_DEFUN([ODP_DPDK_PMDS], [dnl
AS_VAR_SET([DPDK_PMDS], ["-Wl,--whole-archive,"])
for filename in "$1"/librte_pmd_*.a; do
cur_driver=`basename "$filename" .a | sed -e 's/^lib//'`
+
+# Match pattern is filled to 'filename' once if no matches are found
+AS_IF([test "x$cur_driver" = "xrte_pmd_*"], [break])
+
AS_VAR_APPEND([DPDK_PMDS], [-l$cur_driver,])
AS_CASE([$cur_driver],
[rte_pmd_nfp], [AS_VAR_APPEND([DPDK_LIBS], [" -lm"])],
-----------------------------------------------------------------------
Summary of changes:
m4/odp_dpdk.m4 | 4 ++++
1 file changed, 4 insertions(+)
hooks/post-receive
--