Using patch: lng-odp_PATCHv3_doc_userguide_add_application_programming_section.mbox Trying to apply patch Patch applied Applying: doc: userguide: add application programming section /home/mike/git/check-odp/build/odp-apply/.git/rebase-apply/patch:446: indent with spaces. odp_event_t ev; /home/mike/git/check-odp/build/odp-apply/.git/rebase-apply/patch:613: indent with spaces. odp_init_local(); /home/mike/git/check-odp/build/odp-apply/.git/rebase-apply/patch:616: indent with spaces. while (1) { /home/mike/git/check-odp/build/odp-apply/.git/rebase-apply/patch:617: indent with spaces. ev = odp_schedule(&which_q, ODP_SCHED_WAIT); warning: 4 lines add whitespace errors. 0001-doc-userguide-add-application-programming-section.patch: unified diff output, UTF-8 Unicode text
When I look at all these with git show I see a tab got in there rather than a space which is inconsistent with the rest of the text. Do you have the .gitconfig whitespace = trailing-space,space-before-tab,indent-with-non-tab,error-all if not you may not be seeing some things. On 8 December 2015 at 17:36, Bill Fischofer <bill.fischo...@linaro.org> wrote: > Complete the reformatting to standard asciidoc style, expand the > ODP Application Programming section, and include a reorganized and > expanded discussion of ODP queues. > > Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org> > --- > doc/users-guide/users-guide.adoc | 451 > +++++++++++++++++++++++++++++++-------- > 1 file changed, 359 insertions(+), 92 deletions(-) > > diff --git a/doc/users-guide/users-guide.adoc > b/doc/users-guide/users-guide.adoc > index cf77fa0..d660fb8 100644 > --- a/doc/users-guide/users-guide.adoc > +++ b/doc/users-guide/users-guide.adoc > @@ -8,16 +8,19 @@ OpenDataPlane (ODP) Users-Guide > Abstract > -------- > This document is intended to guide a new ODP application developer. > -Further details about ODP may be found at the http://opendataplane.org[ODP] > home page. > +Further details about ODP may be found at the http://opendataplane.org > [ODP] > +home page. > > .Overview of a system running ODP applications > image::../images/overview.png[align="center"] > > -ODP is an API specification that allows many implementations to provide > platform independence, automatic hardware acceleration and CPU scaling to > high performance networking applications. > -This document describes how to write an application that can successfully > take advantage of the API. > +ODP is an API specification that allows many implementations to provide > +platform independence, automatic hardware acceleration and CPU scaling to > +high performance networking applications. This document describes how to > +write an application that can successfully take advantage of the API. > > :numbered: > -== Introduction == > +== Introduction > .OpenDataPlane Components > image::../images/odp_components.png[align="center"] > > @@ -42,7 +45,7 @@ ODP API specification--that is the responsibility of > each ODP implementation. > * Application-centric. Covers functional needs of data plane > applications. > * Ensures portability by specifying the functional behavior of ODP. > * Defined jointly and openly by application writers and platform > implementers. > -* Archiected to be implementable on a wide range of platforms efficiently > +* Architected to be implementable on a wide range of platforms efficiently > * Sponsored, governed, and maintained by the Linaro Networking Group (LNG) > > .ODP Implementations > @@ -68,7 +71,7 @@ where the application will run on a target platform > chosen by someone else. > * One size does not fit all--supporting multiple implementations allows > ODP > to adapt to widely differing internals among platforms. > * Anyone can create an ODP implementation tailored to their platform > -* Distribution and mainteinance of each implementation is as owner wishes > +* Distribution and maintenance of each implementation is as owner wishes > - Open source or closed source as business needs determine > - Have independent release cycles and service streams > * Allows HW and SW innovation in how ODP APIs are implemented on each > platform. > @@ -100,7 +103,7 @@ drivers supported by DPDK. > they are derived from a reference implementation. > > .ODP Validation Test Suite > -Third, to enure consistency between different ODP implementations, ODP > +Third, to ensure consistency between different ODP implementations, ODP > consists of a validation suite that verifies that any given > implementation of > ODP faithfully provides the specified functional behavior of each ODP API. > As a separate open source component, the validation suite may be used by > @@ -115,16 +118,16 @@ ODP API specification. > * Key to ensuring application portability across all ODP implementations > * Tests that ODP implementations conform to the specified functional > behavior > of ODP APIs. > -* Can be run at any time by users and vendors to validat implementations > -od ODP. > +* Can be run at any time by users and vendors to validate implementations > +of ODP. > > -=== ODP API Specification Versioning === > +=== ODP API Specification Versioning > As an evolving standard, the ODP API specification is released under an > incrementing version number, and corresponding implementations of ODP, as > well > as the validation suite that verifies API conformance, are linked to this > -version number. ODP versions are specified using a stanard three-level > +version number. ODP versions are specified using a standard three-level > number (major.minor.fixlevel) that are incremented according to the > degree of > -change the level represents. Increments to the fixlevel represent > clarification > +change the level represents. Increments to the fix level represent > clarification > of the specification or other minor changes that do not affect either the > syntax or semantics of the specification. Such changes in the API > specification > are expected to be rare. Increments to the minor level > @@ -136,26 +139,26 @@ the major level represent significant structural > changes that most likely > require some level of application source code change, again as documented > in > the release notes for that version. > > -=== ODP Implementation Versioning === > +=== ODP Implementation Versioning > ODP implementations are free to use whatever release naming/numbering > conventions they wish, as long as it is clear what level of the ODP API a > given > release implements. A recommended convention is to use the same three > level > numbering scheme where the major and minor numbers correspond to the ODP > API > -level and the fixlevel represents an implementation-defined service level > +level and the fix level represents an implementation-defined service level > associated with that API level implementation. The LNG-supplied ODP > reference > implementations follow this convention. > > -=== ODP Validation Test Suite Versioning === > +=== ODP Validation Test Suite Versioning > The ODP validation test suite follows these same naming conventions. The > major > and minor release numbers correspond to the ODP API level that the suite > -validates and the fixlevel represents the service level of the validation > +validates and the fix level represents the service level of the validation > suite itself for that API level. > > -=== ODP Design Goals === > +=== ODP Design Goals > ODP has three primary goals that follow from its component structure. The > first > is application portability across a wide range of platforms. These > platforms > differ in terms of processor instruction set architecture, number and > types of > -application processing cores, memory oranization, as well as the number > and > +application processing cores, memory organization, as well as the number > and > type of platform specific hardware acceleration and offload features that > are available. ODP applications can move from one conforming > implementation > to another with at most a recompile. > @@ -175,7 +178,7 @@ of processing cores that are available to realize > application function. The > result is that an application written to this model does not require > redesign > as it scales from 4, to 40, to 400 cores. > > -== Organization of this Document == > +== Organization of this Document > This document is organized into several sections. The first presents a > high > level overview of the ODP API component areas and their associated > abstract > data types. This section introduces ODP APIs at a conceptual level. > @@ -190,14 +193,14 @@ full reference specification for each API. The > latter is intended to be used > by ODP application programmers, as well as implementers, to understand the > precise syntax and semantics of each API. > > -== ODP API Concepts == > +== ODP API Concepts > ODP programs are built around several conceptual structures that every > -appliation programmer needs to be familiar with to use ODP effectively. > The > +application programmer needs to be familiar with to use ODP effectively. > The > main ODP concepts are: > Thread, Event, Queue, Pool, Shared Memory, Buffer, Packet, PktIO, Timer, > and Synchronizer. > > -=== Thread === > +=== Thread > The thread is the fundamental programming unit in ODP. ODP applications > are > organized into a collection of threads that perform the work that the > application is designed to do. ODP threads may or may not share memory > with > @@ -209,7 +212,7 @@ A control thread is a supervisory thread that organizes > the operation of worker threads. Worker threads, by contrast, exist to > perform the main processing logic of the application and employ a run to > completion model. Worker threads, in particular, are intended to operate > on > -dedicated processing cores, especially in many core proessing > environments, > +dedicated processing cores, especially in many core processing > environments, > however a given implementation may multitask multiple threads on a single > core if desired (typically on smaller and lower performance target > environments). > @@ -219,7 +222,7 @@ _thread mask_ and _scheduler group_ that determine > where they can run and > the type of work that they can handle. These will be discussed in greater > detail later. > > -=== Event === > +=== Event > Events are what threads process to perform their work. Events can > represent > new work, such as the arrival of a packet that needs to be processed, or > they > can represent the completion of requests that have executed > asynchronously. > @@ -232,7 +235,7 @@ References to events are via handles of abstract type > +odp_event_t+. Cast > functions are provided to convert these into specific handles of the > appropriate type represented by the event. > > -=== Queue === > +=== Queue > A queue is a message passing channel that holds events. Events can be > added to a queue via enqueue operations or removed from a queue via > dequeue > operations. The endpoints of a queue will vary depending on how it is > used. > @@ -244,7 +247,7 @@ stateful processing on events as well as stateless > processing. > > Queues are represented by handles of abstract type +odp_queue_t+. > > -=== Pool === > +=== Pool > A pool is a shared memory area from which elements may be drawn. Pools > represent the backing store for events, among other things. Pools are > typically created and destroyed by the application during initialization > and > @@ -256,32 +259,32 @@ are Buffer and Packet. > > Pools are represented by handles of abstract type +odp_pool_t+. > > -=== Shared Memory === > +=== Shared Memory > Shared memory represents raw blocks of storage that are sharable between > threads. They are the building blocks of pools but can be used directly by > ODP applications if desired. > > Shared memory is represented by handles of abstract type +odp_shm_t+. > > -=== Buffer === > +=== Buffer > A buffer is a fixed sized block of shared storage that is used by ODP > components and/or applications to realize their function. Buffers contain > zero or more bytes of application data as well as system maintained > metadata that provide information about the buffer, such as its size or > the > pool it was allocated from. Metadata is an important ODP concept because > it > allows for arbitrary amounts of side information to be associated with an > -ODP object. Most ODP objects have assocaited metadata and this metadata is > +ODP object. Most ODP objects have associated metadata and this metadata is > manipulated via accessor functions that act as getters and setters for > -this information. Getter acces functions permit an application to read > +this information. Getter access functions permit an application to read > a metadata item, while setter access functions permit an application to > write > a metadata item. Note that some metadata is inherently read only and thus > no setter is provided to manipulate it. When object have multiple > metadata > items, each has its own associated getter and/or setter access function to > inspect or manipulate it. > > -Buffers are represened by handles of abstract type +odp_buffer_t+. > +Buffers are represented by handles of abstract type +odp_buffer_t+. > > -=== Packet === > +=== Packet > Packets are received and transmitted via I/O interfaces and represent > the basic data that data plane applications manipulate. > Packets are drawn from pools of type +ODP_POOL_PACKET+. > @@ -294,7 +297,7 @@ with each packet for its own use. > > Packets are represented by handles of abstract type +odp_packet_t+. > > -=== PktIO === > +=== PktIO > PktIO is how ODP represents I/O interfaces. A pktio object is a logical > port capable of receiving and/or transmitting packets. This may be > directly > supported by the underlying platform as an integrated feature, > @@ -302,7 +305,7 @@ or may represent a device attached via a PCIE or other > bus. > > PktIOs are represented by handles of abstract type +odp_pktio_t+. > > -=== Timer === > +=== Timer > Timers are how ODP applications measure and respond to the passage of > time. > Timers are drawn from specialized pools called timer pools that have their > own abstract type (+odp_timer_pool_t+). Applications may have many timers > @@ -310,7 +313,7 @@ active at the same time and can set them to use either > relative or absolute > time. When timers expire they create events of type +odp_timeout_t+, which > serve as notifications of timer expiration. > > -=== Synchronizer === > +=== Synchronizer > Multiple threads operating in parallel typically require various > synchronization services to permit them to operate in a reliable and > coordinated manner. ODP provides a rich set of locks, barriers, and > similar > @@ -325,7 +328,7 @@ flow of work through an ODP application. These include > the Classifier, > Scheduler, and Traffic Manager. These components relate to the three > main stages of packet processing: Receive, Process, and Transmit. > > -=== Classifier === > +=== Classifier > The *Classifier* provides a suite of APIs that control packet receive (RX) > processing. > > @@ -362,8 +365,8 @@ Note that the use of the classifier is optional. > Applications may directly > receive packets from a corresponding PktIO input queue via direct polling > if they choose. > > -=== Scheduler === > -The *Scheduler* provides a suite of APIs that control scalabable event > +=== Scheduler > +The *Scheduler* provides a suite of APIs that control scalable event > processing. > > .ODP Scheduler and Event Processing > @@ -391,10 +394,10 @@ scheduled back to a thread to continue processing > with the results of the > requested asynchronous operation. > > Threads themselves can enqueue events to queues for downstream processing > -by other threads, permitting flexibility in how applicaitions structure > +by other threads, permitting flexibility in how applications structure > themselves to maximize concurrency. > > -=== Traffic Manager === > +=== Traffic Manager > The *Traffic Manager* provides a suite of APIs that control traffic > shaping and > Quality of Service (QoS) processing for packet output. > > @@ -413,23 +416,33 @@ goals. Again, the advantage here is that on many > platforms traffic management > functions are implemented in hardware, permitting transparent offload of > this work. > > -Glossary > --------- > -[glossary] > -odp_worker:: > - An opd_worker is a type of odp_thread. It will usually be isolated > from the scheduling of any host operating system and is intended for > fast-path processing with a low and predictable latency. Odp_workers will > not generally receive interrupts and will run to completion. > -odp_control:: > - An odp_control is a type of odp_thread. It will be isolated from the > host operating system house keeping tasks but will be scheduled by it and > may receive interrupts. > -odp_thread:: > - An odp_thread is a flow of execution that in a Linux environment > could be a Linux process or thread. > -event:: > - An event is a notification that can be placed in a queue. > - > -The include structure > ---------------------- > -Applications only include the 'include/odp.h file which includes the > 'platform/<implementation name>/include/plat' files to provide a complete > definition of the API on that platform. > -The doxygen documentation defining the behavior of the ODP API is all > contained in the public API files, and the actual definitions for an > implementation will be found in the per platform directories. > -Per-platform data that might normally be a #define can be recovered via > the appropriate access function if the #define is not directly visible to > the application. > +== ODP Application Programming > +At the highest level, an *ODP Application* is a program that uses one or > more > +ODP APIs. Because ODP is a framework rather than a programming > environment, > +applications are free to also use other APIs that may or may not provide > the > +same portability characteristics as ODP APIs. > + > +ODP applications vary in terms of what they do and how they operate, but > in > +general all share the following characteristics: > + > +. They are organized into one or more _threads_ that execute in parallel. > +. These threads communicate and coordinate their activities using various > +_synchronization_ mechanisms. > +. They receive packets from one or more _packet I/O interfaces_. > +. They examine, transform, or otherwise process packets. > +. They transmit packets to one or more _packet I/O interfaces_. > + > +ODP provides APIs to assist in each of these areas. > + > +=== The include structure > +Applications only include the 'include/odp.h' file, which includes the > +'platform/<implementation name>/include/odp' files to provide a complete > +definition of the API on that platform. The doxygen documentation defining > +the behavior of the ODP API is all contained in the public API files, and > the > +actual definitions for an implementation will be found in the per platform > +directories. Per-platform data that might normally be a +#define+ can be > +recovered via the appropriate access function if the #define is not > directly > +visible to the application. > > .Users include structure > ---- > @@ -442,51 +455,305 @@ Per-platform data that might normally be a #define > can be recovered via the appr > │ └── odp.h This file should be the only file included by the > application. > ---- > > -Initialization > --------------- > -IMPORTANT: ODP depends on the application to perform a graceful shutdown, > calling the terminate functions should only be done when the application is > sure it has closed the ingress and subsequently drained all queues etc. > +=== Initialization > +IMPORTANT: ODP depends on the application to perform a graceful shutdown, > +calling the terminate functions should only be done when the application > is > +sure it has closed the ingress and subsequently drained all queues, etc. > + > +=== Startup > +The first API that must be called by an ODP application is > 'odp_init_global()'. > +This takes two pointers. The first, +odp_init_t+, contains ODP > initialization > +data that is platform independent and portable, while the second, > ++odp_platform_init_t+, is passed unparsed to the implementation > +to be used for platform specific data that is not yet, or may never be > +suitable for the ODP API. > + > +Calling odp_init_global() establishes the ODP API framework and MUST be > +called before any other ODP API may be called. Note that it is only called > +once per application. Following global initialization, each thread in turn > +calls 'odp_init_local()' is called. This establishes the local ODP thread > +context for that thread and MUST be called before other ODP APIs may be > +called by that thread. > + > +=== Shutdown > +Shutdown is the logical reverse of the initialization procedure, with > +'odp_term_local()' called for each thread before 'odp_term_global()' is > +called to terminate ODP. > + > +.ODP Application Structure Flow Diagram > +image::../images/resource_management.png[align="center"] > > -Startup > -~~~~~~~~ > -The first API that must be called is 'odp_init_global()'. > -This takes two pointers, odp_init_t contains ODP initialization data that > is platform independent and portable. > -The second odp_platform_init_t is passed un parsed to the implementation > and can be used for platform specific data that is not yet, or may never be > suitable for the ODP API. > +== Common Conventions > +Many ODP APIs share common conventions regarding their arguments and > return > +types. This section highlights some of the more common and frequently used > +conventions. > + > +=== Handles and Special Designators > +ODP resources are represented via _handles_ that have abstract type > +_odp_resource_t_. So pools are represented by handles of type > +odp_pool_t+, > +queues by handles of type +odp_queue_t+, etc. Each such type > +has a distinguished type _ODP_RESOURCE_INVALID_ that is used to indicate a > +handle that does not refer to a valid resource of that type. Resources are > +typically created via an API named _odp_resource_create()_ that returns a > +handle of type _odp_resource_t_ that represents the created object. This > +returned handle is set to _ODP_RESOURCE_INVALID_ if, for example, the > +resource could not be created due to resource exhaustion. Invalid > resources > +do not necessarily represent error conditions. For example, > +ODP_EVENT_INVALID+ > +in response to an +odp_queue_deq()+ call to get an event from a queue > simply > +indicates that the queue is empty. > + > +=== Addressing Scope > +Unless specifically noted in the API, all ODP resources are global to the > ODP > +application, whether it runs as a single process or multiple processes. > ODP > +handles therefore have common meaning within an ODP application but have > no > +meaning outside the scope of the application. > + > +=== Resources and Names > +Many ODP resource objects, such as pools and queues, support an > +application-specified character string _name_ that is associated with an > ODP > +object at create time. This name serves two purposes: documentation, and > +lookup. The lookup function is particularly useful to allow an ODP > application > +that is divided into multiple processes to obtain the handle for the > common > +resource. > + > +== Queues > +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 > ++odp_queue_t+ that is used to refer to this queue in all subsequent APIs > that > +reference it. Queues have one of two ODP-defined _types_, POLL, and SCHED > that > +determine how they are used. POLL queues directly managed by the ODP > +application while SCHED queues make use of the *ODP scheduler* to provide > +automatic scalable dispatching and synchronization services. > + > +.Operations on POLL queues > +[source,c] > +---- > +odp_queue_t poll_q1 = odp_queue_create("poll queue 1", > ODP_QUEUE_TYPE_POLL, NULL); > +odp_queue_t poll_q2 = odp_queue_create("poll queue 2", > ODP_QUEUE_TYPE_POLL, NULL); > +... > +odp_event_t ev = odp_queue_deq(poll_q1); > +...do something > +int rc = odp_queue_enq(poll_q2, ev); > +---- > > -The second API that must be called is 'odp_init_local()', this must be > called once per odp_thread, regardless of odp_thread type. Odp_threads may > be of type ODP_THREAD_WORKER or ODP_THREAD_CONTROL > +The key distinction is that dequeueing events from POLL queues is an > +application responsibility while dequeueing events from SCHED queues is > the > +responsibility of the ODP scheduler. > > -Shutdown > -~~~~~~~~~ > -Shutdown is the logical reverse of the initialization procedure, with > 'odp_thread_term()' called for each worker before 'odp_term_global()' is > called. > +.Operations on SCHED queues > +[source,c] > +---- > +odp_queue_param_t qp; > +odp_queue_param_init(&qp); > +odp_schedule_prio_t prio = ...; > +odp_schedule_group_t sched_group = ...; > +qp.sched.prio = prio; > +qp.sched.sync = ODP_SCHED_SYNC_[NONE|ATOMIC|ORDERED]; > +qp.sched.group = sched_group; > +qp.lock_count = n; /* Only relevant for ordered queues */ > +odp_queue_t sched_q1 = odp_queue_create("sched queue 1", > ODP_QUEUE_TYPE_SCHED, &qp); > + > +...thread init processing > + > +while (1) { > + odp_event_t ev; > + odp_queue_t which_q; > + ev = odp_schedule(&which_q, <wait option>); > + ...process the event > +} > +---- > > -image::../images/resource_management.png[align="center"] > +With scheduled queues, events are sent to a queue, and the the sender > chooses > +a queue based on the service it needs. The sender does not need to know > +which ODP thread (on which core) or hardware accelerator will process > +the event, but all the events on a queue are eventually scheduled and > processed. > + > +As can be seen, SCHED queues have additional attributes that are > specified at > +queue create that control how the scheduler is to process events contained > +on them. These include group, priority, and synchronization class. > + > +=== Scheduler Groups > +The scheduler's dispatching job is to return the next event from the > highest > +priority SCHED queue that the caller is eligible to receive events from. > +This latter consideration is determined by the queues _scheduler group_, > which > +is set at queue create time, and by the caller's _scheduler group mask_ > that > +indicates which scheduler group(s) it belongs to. Scheduler groups are > +represented by handles of type +odp_scheduler_group_t+ and are created by > +the *odp_scheduler_group_create()* API. A number of scheduler groups are > +_predefined_ by ODP. These include +ODP_SCHED_GROUP_ALL+ (all threads), > ++ODP_SCHED_GROUP_WORKER+ (all worker threads), and > +ODP_SCHED_GROUP_CONTROL+ > +(all control threads). The application is free to create additional > scheduler > +groups for its own purpose and threads can join or leave scheduler groups > +using the *odp_scheduler_group_join()* and *odp_scheduler_group_leave()* > APIs > + > +=== Scheduler Priority > +The +prio+ field of the +odp_queue_param_t+ specifies the queue's > scheduling > +priority, which is how queues within eligible scheduler groups are > selected > +for dispatch. Queues have a default scheduling priority of NORMAL but can > be > +set to HIGHEST or LOWEST according to application needs. > + > +=== Scheduler Synchronization > +In addition to its dispatching function, which provide automatic > scalability to > +ODP applications in many core environments, the other main function of the > +scheduler is to provide event synchronization services that greatly > simplify > +application programming in a parallel processing environment. A queue's > +SYNC mode determines how the scheduler handles the synchronization > processing > +of multiple events originating from the same queue. > + > +Three types of queue scheduler synchronization area supported: Parallel, > +Atomic, and Ordered. > + > +==== Parallel Queues > +SCHED queues that specify a sync mode of ODP_SCHED_SYNC_NONE are > unrestricted > +in how events are processed. > + > +.Parallel Queue Scheduling > +image::../images/parallel_queue.png[align="center"] > > -Queues > ------- > -There are three queue types, atomic, ordered and parallel. > -A queue belongs to a single odp_worker and a odp_worker may have multiple > queues. > +All events held on parallel queues are eligible to be scheduled > simultaneously > +and any required synchronization between them is the responsibility of the > +application. Events originating from parallel queues thus have the highest > +throughput rate, however they also potentially involve the most work on > the > +part of the application. In the Figure above, four threads are calling > +*odp_schedule()* to obtain events to process. The scheduler has assigned > +three events from the first queue to three threads in parallel. The fourth > +thread is processing a single event from the third queue. The second queue > +might either be empty, of lower priority, or not in a scheduler group > matching > +any of the threads being serviced by the scheduler. > + > +=== Atomic Queues > +Atomic queues simplify event synchronization because only a single event > +from a given atomic queue may be processed at a time. Events scheduled > from > +atomic queues thus can be processed lock free because the locking is being > +done implicitly by the scheduler. > + > +.Atomic Queue Scheduling > +image::../images/atomic_queue.png[align="center"] > > -Events are sent to a queue, and the the sender chooses a queue based on > the service it needs. > -The sender does not need to know which odp_worker (on which core) or HW > accelerator will process the event, but all the events on a queue are > eventually scheduled and processed. > +In this example, no matter how many events may be held in an atomic > queue, only > +one of them can be scheduled at a time. Here two threads process events > from > +two different atomic queues. Note that there is no synchronization between > +different atomic queues, only between events originating from the same > atomic > +queue. The queue context associated with the atomic queue is held until > the > +next call to the scheduler or until the application explicitly releases it > +via a call to *odp_schedule_release_atomic()*. > > -NOTE: Both ordered and parallel queue types improve throughput over an > atomic queue (due to parallel event processing), but the user has to take > care of the context data synchronization (if needed). > +Note that while atomic queues simplify programming, the serial nature of > +atomic queues will impair scaling. > > -Atomic Queue > -~~~~~~~~~~~~ > -Only one event at a time may be processed from a given queue. The > processing maintains order and context data synchronization but this will > impair scaling. > +=== Ordered Queues > +Ordered queues provide the best of both worlds by providing the inherent > +scaleabilty of parallel queues, with the easy synchronization of atomic > +queues. > > -.Overview Atomic Queue processing > -image::../images/atomic_queue.png[align="center"] > +.Ordered Queue Scheduling > +image::../images/ordered_queue.png[align="center"] > > -Ordered Queue > -~~~~~~~~~~~~~ > -An ordered queue will ensure that the sequencing at the output is > identical to that of the input, but multiple events may be processed > simultaneously and the order is restored before the events move to the next > queue > +When scheduling events from an ordered queue, the scheduler dispatches > multiple > +events from the queue in parallel to different threads, however the > scheduler > +also ensures that the relative sequence of these events on output queues > +is identical to their sequence from their originating ordered queue. > + > +As with atomic queues, the ordering guarantees associated with ordered > queues > +refer to events originating from the same queue, not for those > originating on > +different queues. Thus in this figure three thread are processing events > 5, 3, > +and 4, respectively from the first ordered queue. Regardless of how these > +threads complete processing, these events will appear in their original > +relative order on their output queue. > + > +==== Order Preservation > +Relative order is preserved independent of whether events are being sent > to > +different output queues. For example, if some events are sent to output > queue > +A while others are sent to output queue B then the events on these output > +queues will still be in the same relative order as they were on their > +originating queue. Similarly, if the processing consumes events so that > no > +output is issued for some of them (_e.g.,_ as part of IP fragment > reassembly > +processing) then other events will still be correctly ordered with > respect to > +these sequence gaps. Finally, if multiple events are enqueued for a given > +order (_e.g.,_ as part of packet segmentation processing for MTU > +considerations), then each of these events will occupy the originator's > +sequence in the target output queue(s). In this case the relative order > of these > +events will be in the order that the thread issued *odp_queue_enq()* > calls for > +them. > + > +The ordered context associated with the dispatch of an event from an > ordered > +queue lasts until the next scheduler call or until explicitly released by > +the thread calling *odp_schedule_release_ordered()*. This call may be used > +as a performance advisory that the thread no longer requires ordering > +guarantees for the current context. As a result, any subsequent enqueues > +within the current scheduler context will be treated as if the thread was > +operating in a parallel queue context. > + > +==== Ordered Locking > +Another powerful feature of the scheduler's handling of ordered queues is > +*ordered locks*. Each ordered queue has associated with it a number of > ordered > +locks as specified by the _lock_count_ parameter at queue create time. > + > +Ordered locks provide an efficient means to perform in-order sequential > +processing within an ordered context. For example, supposed events with > relative > +order 5, 6, and 7 are executing in parallel by three different threads. An > +ordered lock will enable these threads to synchronize such that they can > +perform some critical section in their originating queue order. The > number of > +ordered locks supported for each ordered queue is implementation > dependent (and > +queryable via the *odp_config_max_ordered_locks_per_queue()* API). If the > +implementation supports multiple ordered locks then these may be used to > +protect different ordered critical sections within a given ordered > context. > + > +==== Summary: Ordered Queues > +To see how these considerations fit together, consider the following code: > + > +.Processing with Ordered Queues > +[source,c] > +---- > +void worker_thread() > +{ > + odp_init_local(); > + ...other initialization processing > + > + while (1) { > + ev = odp_schedule(&which_q, ODP_SCHED_WAIT); > + ...process events in parallel > + odp_schedule_order_lock(0); > + ...critical section processed in order > + odp_schedule_order_unlock(0); > + ...continue processing in parallel > + odp_queue_enq(dest_q, ev); > + } > +} > +---- > > -.Overview Ordered Queue processing > -image::../images/ordered_queue.png[align="center"] > +This represents a simplified structure for a typical worker thread > operating > +on ordered queues. Multiple events are processed in parallel and the use > of > +ordered queues ensures that they will be placed on +dest_q+ in the same > order > +as they originated. While processing in parallel, the use of ordered > locks > +enables critical sections to be processed in order within the overall > parallel > +flow. When a thread arrives at the _odp_schedule_order_lock()_ call, it > waits > +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. > > -Parallel Queue > -~~~~~~~~~~~~~~ > -There are no restrictions on the number of events being processed. > +=== Queue Scheduling Summary > > -.Overview parallel Queue processing > -image::../images/parallel_queue.png[align="center"] > +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. > + > +== Glossary > +[glossary] > +worker thread:: > + A worker is a type of ODP thread. It will usually be isolated from > + the scheduling of any host operating system and is intended for > fast-path > + processing with a low and predictable latency. Worker threads will not > + generally receive interrupts and will run to completion. > +control thread:: > + A control threadis a type of ODP thread. It will be isolated from the > host > + operating system house keeping tasks but will be scheduled by it and > may > + receive interrupts. > +thread:: > + An ODP thread is a flow of execution that in a Linux environment > could be > + a Linux process or thread. > +event:: > + An event is a notification that can be placed in a queue. > +queue:: > + A communication channel that holds events > -- > 2.1.4 > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > https://lists.linaro.org/mailman/listinfo/lng-odp > -- Mike Holmes Technical Manager - Linaro Networking Group Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
_______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp