I've posted a v3 that incorporates your review comments.  We can discuss
with Petri any proposed changes to the doxygen on the APIs while at BKK.
Thanks.

On Thu, Mar 3, 2016 at 11:44 AM, Christophe Milard <
[email protected]> wrote:

> I know the comments are copied from the source, but thy are just copied
> (not referenced), right?
>  I mean, if it does not get fixed here, there will be 2 places to fix...
> If you have the courage, maybe the source comment can be fixed in a earlyer
> patch.
> These comments are relatively minor details. Fix what you can: This text
> is much better that the emptiness that was before.
>
> On 3 March 2016 at 17:12, Bill Fischofer <[email protected]>
> wrote:
>
>>
>>
>> On Thu, Mar 3, 2016 at 4:00 AM, Christophe Milard <
>> [email protected]> wrote:
>>
>>> On 2016-03-02 04:35, Bill Fischofer wrote:
>>> > Signed-off-by: Bill Fischofer <[email protected]>
>>> > ---
>>> >  doc/users-guide/users-guide-pktio.adoc | 605
>>> +++++++++++++++++++++++++++++++++
>>> >  doc/users-guide/users-guide.adoc       |   2 +
>>> >  2 files changed, 607 insertions(+)
>>> >  create mode 100644 doc/users-guide/users-guide-pktio.adoc
>>> >
>>> > diff --git a/doc/users-guide/users-guide-pktio.adoc
>>> b/doc/users-guide/users-guide-pktio.adoc
>>> > new file mode 100644
>>> > index 0000000..29fb6a9
>>> > --- /dev/null
>>> > +++ b/doc/users-guide/users-guide-pktio.adoc
>>> > @@ -0,0 +1,605 @@
>>> > +== PktIO Processing
>>> > +Before packets can be manipulated they typically need to be
>>> _received_ and
>>> > +after they are manipulated they need to be _transmitted_. The ODP
>>> abstraction
>>> > +that captures these operations is the *Packet I/O (PktIO)*.
>>> > +PktIOs are represented by handles of type *odp_pktio_t* and
>>> > +represent a logical I/O interface that is mapped in an
>>> implementation-defined
>>> > +manner to an underlying integrated I/O adapter or NIC.
>>> > +
>>> > +PktIO objects are manipulated through various state transitions via
>>> > ++odp_pktio_xxx()+ API calls as shown below:
>>> > +
>>> > +.ODP PktIO Finite State Machine
>>> > +image::../images/pktio_fsm.svg[align="center"]
>>> > +
>>> > +PktIOs begin in the *Unallocated* state. From here a call
>>> +odp_pktio_open()+
>>> > +is used to create an *odp_pktio_t* handle that is used in all
>>> subsequent calls
>>> > +to manipulate the object. This call puts the PktIO into the
>>> *Unconfigured*
>>> > +state. To become operational, a PktIO must first be
>>> > +*configured* for Input, Output, or both Input and Output via the
>>> > ++odp_pktin_queue_config()+ and/or +odp_pktout_queue_config()+ APIs,
>>> and then
>>> > +*started* via the +odp_pktio_start()+ to make it *Ready*.
>>> > +
>>> > +Following the completion of I/O processing, the +odp_pktio_stop()+
>>> API returns
>>> > +the PktIO to the *Configured* state. From here it may be
>>> *Reconfigured* via
>>> > +additional +odp_pktin_queue_config()+ and/or
>>> +odp_pktout_queue_config()+ calls,
>>> > +or *Closed* via the +odp_pktio_close()+ API to return the PktIO to the
>>> > +*Unallocated* state.
>>> > +
>>> > +=== PktIO Allocation
>>> > +PktIO objects begin life by being _opened_ via the call:
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Open a packet IO interface
>>> > + *
>>> > + * An ODP program can open a single packet IO interface per device,
>>> attempts
>>>
>>> what is a device here? a (possibly physical) interface? if we have a NIC
>>> board with 2
>>> physical inerfaces, how many pktio can on open on it?
>>> maybe: "An ODP program can open a single packet IO per interface"...?
>>>
>>
>> You're not commenting on this document, but on the
>> include/odp/api/spec/packet_io.h file that I'm just excerpting snippets
>> from here. We can improve that commentary, but that would be a separate
>> patch.  I'd prefer to keep these two separate at this point and make any
>> doxygen changes as a separate patch series.
>>
>
> yes I know. see my comment on the top.
>
>
>>
>>> > + * to open an already open device will fail, returning
>>> ODP_PKTIO_INVALID with
>>> > + * errno set. Use odp_pktio_lookup() to obtain a handle to an already
>>> open
>>>
>>> "opened" instead of open?
>>>
>>
>> Same comment as above.
>>
>>
>>>
>>> > + * device. Packet IO parameters provide interface level configuration
>>> options.
>>> > + *
>>> > + * Packet input queue configuration must be setup with
>>> > + * odp_pktin_queue_config() before odp_pktio_start() is called. When
>>> packet
>>> > + * input mode is ODP_PKTIN_MODE_DISABLED, odp_pktin_queue_config()
>>> call is
>>> > + * optional and will ignore all parameters.
>>> > + *
>>> > + * Packet output queue configuration must be setup with
>>> > + * odp_pktout_queue_config() before odp_pktio_start() is called. When
>>> packet
>>> > + * output mode is ODP_PKTOUT_MODE_DISABLED or ODP_PKTOUT_MODE_TM,
>>> > + * odp_pktout_queue_config() call is optional and will ignore all
>>> parameters.
>>> > + *
>>>
>>> Is is not clear at this stage of reading what are the packet input and
>>> output modes.
>>> I assume that they are parameters to the pktio_open function (in param)
>>> as this
>>> is the only thing that is done before the configuration, maybe that
>>> should
>>> be clarified before. (this assumption gets confirmed later on in the doc)
>>> Simply adding "Pktio in/output mode will be discussed in the next
>>> section" before
>>> this code frgament would make sense.
>>>
>>
>> Same comment as above.
>>
>>
>>>
>>> > + * Packet receive and transmit on the interface is enabled with a
>>> call to
>>> > + * odp_pktio_start(). If not specified otherwise, any interface level
>>> > + * configuration must not be changed when the interface is active
>>> (between start
>>> > + * and stop calls).
>>> > + *
>>> > + * In summary, a typical pktio interface setup sequence is ...
>>> > + *   * odp_pktio_open()
>>> > + *   * odp_pktin_queue_config()
>>> > + *   * odp_pktout_queue_config()
>>> > + *   * odp_pktio_start()
>>> > + *
>>> > + * ... and tear down sequence is:
>>> > + *   * odp_pktio_stop()
>>> > + *   * odp_pktio_close()
>>> > + *
>>> > + * @param name   Packet IO device name
>>> > + * @param pool   Default pool from which to allocate storage for
>>> packets
>>> > + *               received over this interface, must be of type
>>> ODP_POOL_PACKET
>>> > + * @param param  Packet IO parameters
>>> > + *
>>> > + * @return Packet IO handle
>>> > + * @retval ODP_PKTIO_INVALID on failure
>>> > + *
>>> > + * @note The device name "loop" is a reserved name for a loopback
>>> device used
>>> > + *    for testing purposes.
>>> > + *
>>> > + * @note Packets arriving via this interface assigned to a CoS by the
>>> > + *    classifier are received into the pool associated with that CoS.
>>> This
>>> > + *    will occur either because this pktio is assigned a default CoS
>>> via
>>> > + *    the odp_pktio_default_cos_set() routine, or because a matching
>>> PMR
>>> > + *    assigned the packet to a specific CoS. The default pool
>>> specified
>>> > + *    here is applicable only for those packets that are not assigned
>>> to a
>>> > + *    more specific CoS.
>>> > + *
>>> > + * @see odp_pktio_start(), odp_pktio_stop(), odp_pktio_close()
>>> > + */
>>> > +odp_pktio_t odp_pktio_open(const char *name, odp_pool_t pool,
>>> > +                           const odp_pktio_param_t *param);
>>> > +-----
>>> > ++odp_pktio_open()+ takes three arguments: a *name*, which is an
>>> > +implementation-defined string that identifies the logical interface
>>> to be
>>> > +opened, a *pool* that identifies the ODP pool that storage for
>>> received
>>> > +packets should be allocated from, and a *param* structure that
>>> specifies
>>> > +I/O options to be associated with this PktIO instance.
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Packet IO parameters
>>> > + *
>>> > + * In minimum, user must select input and output modes. Use 0 for
>>> defaults.
>>> > + * Initialize entire struct with zero to maintain API compatibility.
>>> > + */
>>> > +typedef struct odp_pktio_param_t {
>>> > +     /** Packet input mode
>>> > +       *
>>> > +       * The default value is ODP_PKTIN_MODE_DIRECT. */
>>> > +     odp_pktin_mode_t in_mode;
>>> > +     /** Packet output mode
>>> > +       *
>>> > +       * The default value is ODP_PKTOUT_MODE_DIRECT. */
>>> > +     odp_pktout_mode_t out_mode;
>>> > +} odp_pktio_param_t;
>>> > +-----
>>> > +ODP defines *loop* as a reserved name to indicate that this PktIO
>>> represents
>>>
>>> I think "loop" should be quoted as it is a string.
>>>
>>
>> It's bolded for that purpose, but I have no objection to adding quotes.
>> Of course there will always be those who see and try to type the quotes and
>> then wonder why it didn't work.  :)
>>
>>>
>>> > +a loopback interface. Loopback interfaces are useful as a means of
>>> recycling
>>> > +packets back for reclassification after decryption or decapsulation,
>>> as well as
>>> > +for diagnostic or testing purposes.  The *pool* specifies the default
>>> pool to
>>>
>>> "Loopback interfaces are useful as a means of recycling packets back for
>>> reclassification after decryption or decapsulation". I don't understand
>>> what you
>>> mean by that... should I? ;-)
>>>
>>
>> These are two common reasons why you'd use a loopback interface in
>> non-testing mode.  Until you decrypt an IPSEC packet you really have no
>> idea what's really in it. Similar considerations apply to tunneled packets
>> that need to be decapsulated before the "real" packet is visible.
>>
>
> I understand that, but I cannot see how a loopback interface would help
> here. You can explain at BKK !
>
>>
>>
>>>
>>> > +use for packet allocation if not overridden by the classifier due to a
>>> > +specific or default Class-of-Service (CoS) match on the packet. The
>>> *param*
>>> > +struct, in turn, specifies the input and output *modes* of the PktIO.
>>> > +
>>> > +=== PktIO Input and Output Modes
>>> > +PktIO objects support four different Input and Output modes, that may
>>> be
>>> > +specified independently at *open* time.
>>> > +
>>> > +.PktIO Input Modes
>>> > +* +ODP_PKTIN_MODE_DIRECT+
>>> > +* +ODP_PKTIN_MODE_QUEUE+
>>> > +* +ODP_OKTIN_MODE_SCHED+
>>> > +* +ODP_PKTIN_MODE_DISABLED+
>>> > +
>>> > +.PktIO Output Modes
>>> > +* +ODP_PKTOUT_MODE_DIRECT+
>>> > +* +ODP_PKTOUT_MODE_QUEUE+
>>> > +* +ODP_PKTOUT_MODE_TM+
>>> > +* +ODP_PKTOUT_MODE_DISABLED+
>>> > +
>>> > +The DISABLED modes indicate that either input or output is prohibited
>>> on this
>>> > +PktIO. Attempts to receive packets on a PktIO whose +in_mode+ is
>>> DISABLED
>>> > +return no packets while packets sent to a PktIO whose +out_mode+ is
>>> DISABLED
>>> > +are discarded.
>>> > +
>>> > +==== Direct I/O Modes
>>> > +DIRECT I/O is the default mode for PktIO objects. It is designed to
>>> support
>>> > +poll-based packet processing, which is often found in legacy
>>> applications
>>> > +being ported to ODP, and can also be a preferred mode for some types
>>> of
>>> > +packet processing. By supporting poll-based I/O processing, ODP
>>> provides
>>> > +maximum flexibility to the data plane application writer.
>>> > +
>>> > +===== Direct RX Processing
>>> > +The processing of DIRECT input is shown below:
>>> > +
>>> > +.PktIO DIRECT Mode Receive Processing
>>> > +image::../images/pktin_direct_recv.svg[align="center"]
>>> > +
>>>
>>> From this picture, I understand that a each rx pktio queue is
>>> "associated"
>>> to a RX thread at odp_pktin_queue_config time. however, it does not feel
>>> like
>>> that at all in the rest of the document: odp_pktin_recv() take a queue
>>> handle
>>> as parameter, hence allowing any ODP thread to read packets from any
>>> queue
>>> at any time... (the "operation mode", -not really defined for RX- also
>>> implies
>>> that such an association does not exist, at least in unsafe mode)
>>>
>>
>> That is correct.  The intent is to allow applications to have a
>> one-to-one map between threads and RX queues, but ODP does not constrain
>> applications to follow such a design. odp_pktin_queue_config() simply says
>> how many RX queues to create/associated with the PktIO.  The discipline of
>> how threads use these queues is up to the application.  I can add another
>> paragraph here if that isn't clear in context.
>>
>
> My understanding is that ODP does not impose any queue-thread
> relationship, but the application will probably want to have this
> queue-thread relationship. This relationship is actually visible at 2
> places as I understand it: When reading packet from the queue (the queue ID
> is passed) and when selecting the safe/unsafe mode (choosing safe meaning
> that One queue will be read by a single thread). I don't see where the
>  odp_pktin_queue_config() function is involved at all in the relationship
> (appart for configuring N queues, but no relation is made there right?).
>
>
>>> > +In DIRECT mode, received packets are stored in one or more special
>>> PktIO queues
>>> > +of type *odp_pktin_queue_t* and are retrieved by threads calling the
>>> > ++odp_pktin_recv()+ API.
>>> > +
>>> > +Once opened, setting up a DIRECT mode PktIO is performed by the
>>> > ++odp_pktin_queue_config()+ API.
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Configure packet input queues
>>> > + *
>>> > + * Setup a number of packet input queues and configure those. The
>>> maximum number
>>> > + * of queues is platform dependent and can be queried with
>>> > + * odp_pktio_capability(). Use odp_pktin_queue_param_init() to
>>> initialize
>>> > + * parameters into their default values. Default values are also used
>>> when
>>> > + * 'param' pointer is NULL.
>>> > + *
>>> > + * Queue handles for input queues can be requested with
>>> odp_pktin_queue() or
>>> > + * odp_pktin_event_queue() after this call. All requested queues are
>>> setup on
>>> > + * success, no queues are setup on failure. Each call reconfigures
>>> input queues
>>> > + * and may invalidate all previous queue handles.
>>> > + *
>>> > + * @param pktio    Packet IO handle
>>> > + * @param param    Packet input queue configuration parameters. Uses
>>> defaults
>>> > + *                 when NULL.
>>> > + *
>>> > + * @retval 0 on success
>>> > + * @retval <0 on failure
>>> > + *
>>> > + * @see odp_pktio_capability(), odp_pktin_queue(),
>>> odp_pktin_event_queue()
>>> > + */
>>> > +int odp_pktin_queue_config(odp_pktio_t pktio,
>>> > +                        const odp_pktin_queue_param_t *param);
>>> > +-----
>>> > +The second argument to this call is the *odp_pktin_queue_param_t*
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Packet input queue parameters
>>> > + */
>>> > +typedef struct odp_pktin_queue_param_t {
>>> > +     /** Operation mode
>>> > +       *
>>> > +       * The default value is ODP_PKTIO_OP_MT. Application may enable
>>> > +       * performance optimization by defining ODP_PKTIO_OP_MT_UNSAFE
>>> when
>>> > +       * applicable. */
>>> > +     odp_pktio_op_mode_t op_mode;
>>>
>>> Has the "operation mode" been defined anywhere?
>>> not sure what it is. neither do I
>>> know what ODP_PKTIO_OP_MT means at this stage of reading...
>>> This is defined only when talking about TX, later on...
>>> It should be defined here (and possibly reminded for TX)
>>>
>>
>> Doxygen comments again--not part of this patch series
>>
>>
>>>
>>> > +
>>> > +     /** Enable flow hashing
>>> > +       * 0: Do not hash flows
>>> > +       * 1: Hash flows to input queues */
>>> > +     odp_bool_t hash_enable;
>>> > +
>>> > +     /** Protocol field selection for hashing. Multiple protocols can
>>> be
>>> > +       * selected. */
>>> > +     odp_pktin_hash_proto_t hash_proto;
>>> > +
>>> > +     /** Number of input queues to be created. More than one input
>>> queue
>>> > +       * require input hashing or classifier setup. Hash_proto is
>>> ignored
>>> > +       * when hash_enable is zero or num_queues is one. This value
>>> must be
>>> > +       * between 1 and interface capability. Queue type is defined by
>>> the
>>> > +       * input mode. The default value is 1. */
>>> > +     unsigned num_queues;
>>> > +
>>> > +     /** Queue parameters for creating input queues in
>>> ODP_PKTIN_MODE_QUEUE
>>> > +       * or ODP_PKTIN_MODE_SCHED modes. Scheduler parameters are
>>> considered
>>> > +       * only in ODP_PKTIN_MODE_SCHED mode. */
>>> > +     odp_queue_param_t queue_param;
>>> > +
>>> > +} odp_pktin_queue_param_t;
>>> > +-----
>>> > +Note that the *queue_param* field of this struct is ignored in DIRECT
>>> mode.
>>> > +The purpose of +odp_pktin_queue_config()+ is to specify the number of
>>> PktIn
>>> > +queues to be created and to set their attributes.
>>> > +
>>> > +===== Hash Processing
>>> > +Another feature of DIRECT mode input is the provision of a *hash*
>>> function  used
>>> > +to distribute incoming packets among the PktIO's PktIn queues. If the
>>> > ++hash_enable+ field of the *odp_pktin_queue_param_t* is 1,
>>> > +then the +hash_proto+ field is used to specify which field(s) of
>>> incoming
>>> > +packets should be used as input to an implementation-defined packet
>>> > +distribution hash function.
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Packet input hash protocols
>>> > + *
>>> > + * The list of protocol header field combinations, which are included
>>> into
>>> > + * packet input hash calculation.
>>> > + */
>>> > +typedef union odp_pktin_hash_proto_t {
>>> > +     /** Protocol header fields for hashing */
>>> > +     struct {
>>> > +             /** IPv4 addresses and UDP port numbers */
>>> > +             uint32_t ipv4_udp : 1;
>>> > +             /** IPv4 addresses and TCP port numbers */
>>> > +             uint32_t ipv4_tcp : 1;
>>> > +             /** IPv4 addresses */
>>> > +             uint32_t ipv4     : 1;
>>> > +             /** IPv6 addresses and UDP port numbers */
>>> > +             uint32_t ipv6_udp : 1;
>>> > +             /** IPv6 addresses and TCP port numbers */
>>> > +             uint32_t ipv6_tcp : 1;
>>> > +             /** IPv6 addresses */
>>> > +             uint32_t ipv6     : 1;
>>> > +     } proto;
>>> > +
>>> > +     /** All bits of the bit field structure */
>>> > +     uint32_t all_bits;
>>> > +} odp_pktin_hash_proto_t;
>>> > +-----
>>> > +Note that the hash function used in PktIO poll mode operation is
>>> intended to
>>> > +provide simple packet distribution among multiple PktIn queues
>>> associated with
>>> > +the PktIO. It does not have the sophistication of the *ODP
>>> Classifier*, however
>>> > +it also does not incur the setup requirements of pattern matching
>>> rules,
>>> > +making it a simpler choice for less sophisticated applications. Note
>>> that
>>> > +ODP does not specify how the hash is to be performed. That is left to
>>> each
>>> > +implementation. The hash only specifies which input packet fields are
>>> of
>>> > +interest to the application and should be considered by the hash
>>> function in
>>> > +deciding how to distribute packets among PktIn queues. The only
>>> expectation
>>> > +is that packets that have the same hash values should all be mapped
>>> to the
>>> > +same PktIn queue.
>>> > +
>>> > +===== PktIn Queues
>>> > +A *PktIn Queue* is a special type of queue that is used internally by
>>> PktIOs
>>> > +operating in DIRECT mode. Applications cannot perform enqueues to
>>> these queues,
>>> > +however they may obtain references to them via the
>>> +odp_pktin_queue()+ API
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Direct packet input queues
>>> > + *
>>> > + * Returns the number of input queues configured for the interface in
>>> > + * ODP_PKTIN_MODE_DIRECT mode. Outputs up to 'num' queue handles when
>>> the
>>> > + * 'queues' array pointer is not NULL. If return value is larger than
>>> 'num',
>>> > + * there are more queues than the function was allowed to output. If
>>> return
>>> > + * value (N) is less than 'num', only queues[0 ... N-1] have been
>>> written.
>>> > + *
>>> > + * Packets from these queues are received with odp_pktin_recv().
>>> > + *
>>> > + * @param      pktio    Packet IO handle
>>> > + * @param[out] queues   Points to an array of queue handles for output
>>> > + * @param      num      Maximum number of queue handles to output
>>> > + *
>>> > + * @return Number of packet input queues
>>> > + * @retval <0 on failure
>>> > + */
>>> > +int odp_pktin_queue(odp_pktio_t pktio, odp_pktin_queue_t queues[],
>>> int num);
>>> > +-----
>>> > +Once configured, prior to receiving packets the PktIO must be placed
>>> into the
>>> > +*Ready* state via a call to +odp_pktio_start()
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Start packet receive and transmit
>>> > + *
>>> > + * Activate packet receive and transmit on a previously opened or
>>> stopped
>>> > + * interface. The interface can be stopped with a call to
>>> odp_pktio_stop().
>>> > + *
>>> > + * @param pktio  Packet IO handle
>>> > + *
>>> > + * @retval 0 on success
>>> > + * @retval <0 on failure
>>> > + *
>>> > + * @see odp_pktio_open(), odp_pktio_stop()
>>> > + */
>>> > +int odp_pktio_start(odp_pktio_t pktio);
>>> > +-----
>>> > +Once started, the PktIn queue handles are used as arguments to
>>> > ++odp_pktin_recv()+ to receive packets from the PktIO.
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Receive packets directly from an interface input queue
>>> > + *
>>> > + * Receives up to 'num' packets from the pktio interface input queue.
>>> When
>>> > + * input queue parameter 'op_mode' has been set to
>>> ODP_PKTIO_OP_MT_UNSAFE,
>>> > + * the operation is optimized for single thread operation per queue
>>> and the same
>>> > + * queue must not be accessed simultaneously from multiple threads.
>>> > + *
>>> > + * @param      queue      Packet input queue handle for receiving
>>> packets
>>> > + * @param[out] packets[]  Packet handle array for output of received
>>> packets
>>> > + * @param      num        Maximum number of packets to receive
>>> > + *
>>> > + * @return Number of packets received
>>> > + * @retval <0 on failure
>>> > + *
>>> > + * @see odp_pktin_queue()
>>> > + */
>>> > +int odp_pktin_recv(odp_pktin_queue_t queue, odp_packet_t packets[],
>>> int num);
>>>
>>> This means that any thread can read from any queue at any time, right?
>>> (does not match my understanding of figure 13)
>>>
>>
>> That is correct.  As noted above, ODP just provides the tools.
>> Applications must use these tools intelligently.
>>
>>
>>>
>>> > +-----
>>> > +
>>> > +===== Direct TX Processing
>>> > +A PktIO operating in DIRECT mode performs TX processing as shown here:
>>> > +
>>> > +.PktIO DIRECT Mode Transmit Processing
>>> > +image::../images/pktout_direct_send.svg[align="center"]
>>> > +
>>> > +Direct TX processing operates similarly to Direct RX processing.
>>> Following
>>> > +open, the +odp_pktout_queue_config()+ API is used to create and
>>> configure
>>> > +one or more *PktOut queues* to be used to support packet transmission
>>> by
>>> > +this PktIO
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Configure packet output queues
>>> > + *
>>> > + * Setup a number of packet output queues and configure those. The
>>> maximum
>>> > + * number of queues is platform dependent and can be queried with
>>> > + * odp_pktio_capability(). Use odp_pktout_queue_param_init() to
>>> initialize
>>> > + * parameters into their default values. Default values are also used
>>> when
>>> > + * 'param' pointer is NULL.
>>> > + *
>>> > + * Queue handles for output queues can be requested with
>>> odp_pktout_queue() or
>>> > + * odp_pktout_event_queue() after this call. All requested queues are
>>> setup on
>>> > + * success, no queues are setup on failure. Each call reconfigures
>>> output queues
>>> > + * and may invalidate all previous queue handles.
>>> > + *
>>> > + * @param pktio    Packet IO handle
>>> > + * @param param    Packet output queue configuration parameters. Uses
>>> defaults
>>> > + *                 when NULL.
>>> > + *
>>> > + * @retval 0 on success
>>> > + * @retval <0 on failure
>>> > + *
>>> > + * @see odp_pktio_capability(), odp_pktout_queue(),
>>> odp_pktout_event_queue()
>>> > + */
>>> > +int odp_pktout_queue_config(odp_pktio_t pktio,
>>> > +                         const odp_pktout_queue_param_t *param);
>>> > +-----
>>> > +As with +odp_pktin_queue_config()+, the configuration of PktOut queues
>>> > +involves the use of a parameter struct:
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Packet output queue parameters
>>> > + *
>>> > + * These parameters are used in ODP_PKTOUT_MODE_DIRECT and
>>> > + * ODP_PKTOUT_MODE_QUEUE modes.
>>> > + */
>>> > +typedef struct odp_pktout_queue_param_t {
>>> > +     /** Operation mode
>>> > +       *
>>> > +       * The default value is ODP_PKTIO_OP_MT. Application may enable
>>> > +       * performance optimization by defining ODP_PKTIO_OP_MT_UNSAFE
>>> when
>>> > +       * applicable. */
>>> > +     odp_pktio_op_mode_t op_mode;
>>> > +
>>> > +     /** Number of output queues to be created. The value must be
>>> between
>>> > +       * 1 and interface capability. The default value is 1. */
>>> > +     unsigned num_queues;
>>> > +
>>> > +} odp_pktout_queue_param_t;
>>> > +-----
>>> > +As with direct input, direct output uses one or more special output
>>> queues
>>> > +of type *odp_pktout_queue_t* that area created and configured by this
>>> call.
>>>
>>> typo: "area" / "are"
>>>
>>>
>> Good catch.  Thanks.
>>
>>
>>> > +
>>> > +As with PktIn queues, the handles for these created PktOut queues may
>>> be
>>> > +retrieved by the +odp_pktout_queue()+ API:
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Direct packet output queues
>>> > + *
>>> > + * Returns the number of output queues configured for the interface in
>>> > + * ODP_PKTOUT_MODE_DIRECT mode. Outputs up to 'num' queue handles
>>> when the
>>> > + * 'queues' array pointer is not NULL. If return value is larger than
>>> 'num',
>>> > + * there are more queues than the function was allowed to output. If
>>> return
>>> > + * value (N) is less than 'num', only queues[0 ... N-1] have been
>>> written.
>>> > + *
>>> > + * Packets are sent to these queues with odp_pktout_send().
>>> > + *
>>> > + * @param      pktio    Packet IO handle
>>> > + * @param[out] queues   Points to an array of queue handles for output
>>> > + * @param      num      Maximum number of queue handles to output
>>> > + *
>>> > + * @return Number of packet output queues
>>> > + * @retval <0 on failure
>>> > + */
>>> > +int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[],
>>> int num);
>>> > +-----
>>> > +Once the PktIO has been configured for output and started via
>>> > ++odp_pktio_start()+, packets may be transmitted to the PktIO by
>>> calling
>>> > +_odp_pktout_send()+:
>>>
>>> "+" missing before _odp_pktout_send()+. (The + you see is from the
>>> patch!)
>>>
>>
>> Thank you.
>>
>>
>>>
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Send packets directly to an interface output queue
>>> > + *
>>> > + * Sends out a number of packets to the interface output queue. When
>>> > + * output queue parameter 'op_mode' has been set to
>>> ODP_PKTIO_OP_MT_UNSAFE,
>>> > + * the operation is optimized for single thread operation per queue
>>> and the same
>>> > + * queue must not be accessed simultaneously from multiple threads.
>>>
>>> The above should be stated when discussing RX!
>>>
>>
>> Noted.  v3 will add additional detail to the narrative.
>>
>>
>>>
>>> > + *
>>> > + * A successful call returns the actual number of packets sent. If
>>> return value
>>> > + * is less than 'num', the remaining packets at the end of packets[]
>>> array
>>> > + * are not consumed, and the caller has to take care of them.
>>> > + *
>>> > + * @param queue        Packet output queue handle for sending packets
>>> > + * @param packets[]    Array of packets to send
>>> > + * @param num          Number of packets to send
>>> > + *
>>> > + * @return Number of packets sent
>>> > + * @retval <0 on failure
>>> > + */
>>> > +int odp_pktout_send(odp_pktout_queue_t queue, odp_packet_t packets[],
>>> int num);
>>> > +-----
>>> > +Note that the argument to this call specifies the PktOut queue to
>>> that the
>>>
>>> is "to that" english? (was expecting "to which") here. If it is, ignore
>>> this
>>> comment!
>>>
>>
>> "to" is an extraneous word here. Good catch.
>>
>>
>>>
>>> > +packet is to be added to rather than the PktIO itself. This permits
>>> multiple
>>> > +threads (presumably operating on different cores) a more efficient
>>> means of
>>> > +separating I/O processing destined for the same interface.
>>> > +
>>> > +==== Queued I/O Modes
>>> > +To provide additional flexibility when operating in poll mode, PktIOs
>>> may also
>>> > +be opened in QUEUE Mode. The difference between DIRECT and QUEUE mode
>>> is that
>>> > +QUEUE mode uses standard ODP event queues to service packets.
>>> > +
>>> > +===== Queue RX Processing
>>> > +The processing for QUEUE input processing is shown below:
>>> > +
>>> > +.PktIO QUEUE Mode Receive Processing
>>> > +image::../images/pktin_queue_recv.svg[align="center"]
>>>
>>> same comment: this figure seems to imply that one can create an
>>> association
>>> between the queues and the threads at odp_pktin_qyeye_config time...
>>>
>>
>> No, it's showing how the created queues can be used most efficiently.
>> I'll expand the comments around this in v3.
>>
>>
>>>
>>> > +
>>> > +In QUEUE mode, received packets are stored in one or more standard
>>> ODP queues.
>>> > +The difference is that these queues are not created directly by the
>>> > +application. Instead, they are created in response to an
>>> > ++odp_pktin_queue_config()+ call.
>>> > +
>>> > +As with DIRECT mode, the +odp_pktin_queue_param_t+ specified to this
>>> call
>>> > +indicates whether an input hash should be used and if so which
>>> field(s) of
>>> > +the packet should be considered as input to the has function.
>>> > +
>>> > +The main difference between DIRECT and QUEUE RX processing is that
>>> because
>>> > +the PktIO uses standard ODP event queues, other parts of the
>>> application can
>>> > +use +odp_queue_enq()+ API calls to enqueue packets to these queues for
>>> > +"RX" processing in addition to those originating from the PktIO
>>> interface
>>> > +itself. To obtain the handles of these input queues, the
>>> > ++odp_pktin_event_queue()+ API is used:
>>> > +[source,c]
>>> > +-----
>>> > +/**
>>> > + * Event queues for packet input
>>> > + *
>>> > + * Returns the number of input queues configured for the interface in
>>> > + * ODP_PKTIN_MODE_QUEUE and ODP_PKTIN_MODE_SCHED modes. Outputs up to
>>> 'num'
>>> > + * queue handles when the 'queues' array pointer is not NULL. If
>>> return value is
>>> > + * larger than 'num', there are more queues than the function was
>>> allowed to
>>> > + * output. If return value (N) is less than 'num', only queues[0 ...
>>> N-1] have
>>> > + * been written.
>>> > + *
>>> > + * Packets (and other events) from these queues are received with
>>> > + * odp_queue_deq(), odp_schedule(), etc calls.
>>> > + *
>>> > + * @param      pktio    Packet IO handle
>>> > + * @param[out] queues   Points to an array of queue handles for output
>>> > + * @param      num      Maximum number of queue handles to output
>>> > + *
>>> > + * @return Number of packet input queues
>>> > + * @retval <0 on failure
>>> > + */
>>> > +int odp_pktin_event_queue(odp_pktio_t pktio, odp_queue_t queues[],
>>> int num);
>>> > +-----
>>> > +Similarly, threads receive packets from PktIOs operating in QUEUE
>>> mode by
>>> > +making standard +odp_queue_deq()+ calls to one of the event queues
>>> associated
>>> > +with the PktIO.
>>> > +
>>> > +===== Queue TX Processing
>>> > +Transmit processing for PktIOs operating in QUEUE mode is shown below:
>>> > +
>>> > +.PktIO QUEUE Mode Transmit Processing
>>> > +image::../images/pktout_queue_send.svg[align="center]
>>> > +
>>> > +For TX processing QUEUE mode behaves similar to DIRECT mode except
>>> that
>>> > +output queues are regular ODP event queues that receive packets via
>>> > ++odp_queue_enq()+ calls rather than special PktOut queues that use
>>> > ++odp_pktout_send()+. Again, these queues are created via a call to
>>> > ++odp_pktout_queue_config()+ following +odp_pktio_open()+.
>>> > +
>>> > +The main reason for selecting QUEUE mode for output is flexibility.
>>> If an
>>> > +application is designed to use a _pipeline model_ where packets flow
>>> through
>>> > +a series of processing stages via queues, then having the PktIO in
>>> QUEUE
>>> > +mode means that the application can always use the same enq APIs to
>>> pass packets
>>> > +from one stage to the next, including the final transmit output stage.
>>> > +
>>> > +==== Scheduled I/O Modes
>>> > +The final PktIO mode supported integrates RX and TX processing with
>>> the ODP
>>> > +_event model_.  For RX processing this involves the use of the
>>> *Scheduler*
>>> > +while for TX processing this involves the use of the *Traffic
>>> Manager*.
>>> > +
>>> > +Scheduled RX Processing is further divided based on whether or not the
>>> > +Classifier is used.
>>> > +
>>> > +===== Scheduled RX Processing
>>> > +When a PktIO is opened with +ODP_PKTIN_MODE_SCHED+, it indicates that
>>> the
>>> > +input queues created by a subsequent +odp_pktin_queue_config()+ call
>>> are to
>>> > +be used as input to the *ODP Scheduler*.
>>> > +
>>> > +.PktIO SCHED Mode Receive Processing
>>> > +image::../images/pktin_sched_recv.svg[align="center']
>>> > +
>>> > +For basic use, SCHED mode simply associates the PktIO input event
>>> queues
>>> > +created by +odp_pktin_queue_config()+ with the scheduler. Hashing may
>>> still be
>>> > +employed to distribute input packets among multiple input queues.
>>> However
>>> > +instead of these being plain queues they are scheduled queues and have
>>> > +associated scheduling attributes like priority, scheduler group, and
>>> > +synchronization mode (parallel, atomic, ordered). SCHED mode thus
>>> provides
>>> > +both packet distribution (via the optional hash) as well as
>>> scalability via
>>> > +the ODP event model.
>>> > +
>>> > +In its fullest form, PktIOs operating in SCHED mode use the *ODP
>>> Classifier*
>>> > +to permit fine-grained flow separation on *Class of Service (CoS)*
>>> boundaries.
>>> > +
>>> > +.PktIO SCHED Mode Receive Processing with Classification
>>> > +image::../images/pktin_sched_cls.svg[align="center"]
>>>
>>> The diagram and the text confuses me a bit, here: my understanding was
>>> that:
>>> 1)the classifier associates a cos to each incoming packet using a set of
>>> PMRs.
>>> 2)Each cos maps to a pair {RXpool, RXqueue}. This Mapping is settled
>>> during the
>>> classifier setup. Packets with a given cos are stored on odp_packets
>>> allocated
>>> from the corresponding pool, and placed in the corresponding queue.
>>>
>>
>> That is correct.  What's unclear about that here?  The point is that the
>> queues shown here may either be those that the application creates via it's
>> own odp_queue_create() calls or those created by odp_pktin_queue_config().
>> If the latter, the application will use odp_pktin_queue() to retrieve their
>> handle to be passed when it creates the CoS it's to be associated with.
>> Remember, multiple CoSes can add packets to the same queue--this is not a
>> 1-to-1 association here.
>>
>
> Maybe the figure wants to show too much. I don't really see what's going
> on there. But maybe it is part of the classifier.
>
> Anyway. see U at BKK!
>
> /Christophe.
>
>>
>>
>>>
>>> > +
>>> > +In this mode of operation, the hash function of
>>> +odp_pktin_queue_config()+ is
>>> > +not used. Instead, the event queues created by this call, as well as
>>> any
>>> > +additional event queues created via separate +odp_queue_create()+
>>> calls are
>>> > +associated with classes of service via +odp_cls_cos_create()+ calls.
>>> > +
>>> > +===== Scheduled TX Processing
>>> > +Scheduled transmit processing is performed via the *ODP Traffic
>>> Manager* and
>>> > +is requested when a PktIO is opened with an +out_mode+ of
>>> +ODP_PKTOUT_MODE_TM+.
>>> > +
>>> > +For TX processing via the Traffic Manager, applications use the
>>> +odp_tm_enq()+
>>> > +API:
>>> > +[source,c]
>>> > +-----
>>> > +/** The odp_tm_enq() function is used to add packets to a given TM
>>> system.
>>> > + * Note that the System Metadata associated with the pkt needed by
>>> the TM
>>> > + * system is (a) a drop_eligible bit, (b) a two bit "pkt_color", (c)
>>> a 16-bit
>>> > + * pkt_len, and MAYBE? (d) a signed 8-bit shaper_len_adjust.
>>> > + *
>>> > + * If there is a non-zero shaper_len_adjust, then it is added to the
>>> pkt_len
>>> > + * after any non-zero shaper_len_adjust that is part of the shaper
>>> profile.
>>> > + *
>>> > + * The pkt_color bits are a result of some earlier
>>> Metering/Marking/Policing
>>> > + * processing (typically ingress based), and should not be confused
>>> with the
>>> > + * shaper_color produced from the TM shaper entities within the
>>> tm_inputs and
>>> > + * tm_nodes.
>>> > + *
>>> > + * @param[in] tm_queue  Specifies the tm_queue (and indirectly the TM
>>> system).
>>> > + * @param[in] pkt       Handle to a packet.
>>> > + * @return              Returns 0 upon success, < 0 upon failure. One
>>> of the
>>> > + *                      more common failure reasons is WRED dropage.
>>> > + */
>>> > +int odp_tm_enq(odp_tm_queue_t tm_queue, odp_packet_t pkt);
>>> > +-----
>>> > +See the *Traffic Manager* section of this document for full
>>> information about
>>> > +Traffic Manager configuration and operation.
>>> > diff --git a/doc/users-guide/users-guide.adoc
>>> b/doc/users-guide/users-guide.adoc
>>> > index d476225..ea24eaf 100644
>>> > --- a/doc/users-guide/users-guide.adoc
>>> > +++ b/doc/users-guide/users-guide.adoc
>>> > @@ -1023,6 +1023,8 @@ a valid UDP packet. Applications are expected to
>>> exercise appropriate care
>>> >  when changing packet metadata to ensure that the resulting metadata
>>> changes
>>> >  reflect the actual changed packet structure that the application has
>>> made.
>>> >
>>> > +include::users-guide-pktio.adoc[]
>>> > +
>>> >  == Cryptographic services
>>> >
>>> >  ODP provides support for cryptographic operations required by various
>>> security
>>> > --
>>> > 2.5.0
>>> >
>>> > _______________________________________________
>>> > lng-odp mailing list
>>> > [email protected]
>>> > https://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>> Interresting reading, and nice to see the user doc growing! Thanks!
>>>
>>
>> Thanks for the careful review and questions.
>>
>>
>>>
>>> Christophe
>>>
>>
>>
>
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to