DPDK patches and discussions
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download: 
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
  2019-09-16 14:53  3%                 ` Ananyev, Konstantin
  2019-09-16 15:08  0%                   ` Ananyev, Konstantin
@ 2019-09-17  6:02  3%                   ` Akhil Goyal
  1 sibling, 0 replies; 200+ results
From: Akhil Goyal @ 2019-09-17  6:02 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev, De Lara Guarch, Pablo, Thomas Monjalon
  Cc: Zhang, Roy Fan, Doherty, Declan, Anoob Joseph


Hi Konstantin,
> 
> Hi Akhil,
> 
> > > > > > > This action type allows the burst of symmetric crypto workload using
> the
> > > > > same
> > > > > > > algorithm, key, and direction being processed by CPU cycles
> > > synchronously.
> > > > > > > This flexible action type does not require external hardware
> involvement,
> > > > > > > having the crypto workload processed synchronously, and is more
> > > > > performant
> > > > > > > than Cryptodev SW PMD due to the saved cycles on removed "async
> > > mode
> > > > > > > simulation" as well as 3 cacheline access of the crypto ops.
> > > > > >
> > > > > > Does that mean application will not call the cryptodev_enqueue_burst
> and
> > > > > corresponding dequeue burst.
> > > > >
> > > > > Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> > > > >
> > > > > > It would be a new API something like process_packets and it will have
> the
> > > > > crypto processed packets while returning from the API?
> > > > >
> > > > > Yes, though the plan is that API will operate on raw data buffers, not
> mbufs.
> > > > >
> > > > > >
> > > > > > I still do not understand why we cannot do with the conventional
> crypto lib
> > > > > only.
> > > > > > As far as I can understand, you are not doing any protocol processing
> or
> > > any
> > > > > value add
> > > > > > To the crypto processing. IMO, you just need a synchronous crypto
> > > processing
> > > > > API which
> > > > > > Can be defined in cryptodev, you don't need to re-create a crypto
> session
> > > in
> > > > > the name of
> > > > > > Security session in the driver just to do a synchronous processing.
> > > > >
> > > > > I suppose your question is why not to have
> > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > The main reason is that would require disruptive changes in existing
> > > cryptodev
> > > > > API
> > > > > (would cause ABI/API breakage).
> > > > > Session for  RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need some
> extra
> > > > > information
> > > > > that normal crypto_sym_xform doesn't contain
> > > > > (cipher offset from the start of the buffer, might be something extra in
> > > future).
> > > >
> > > > Cipher offset will be part of rte_crypto_op.
> > >
> > > fill/read (+ alloc/free) is one of the main things that slowdown current
> crypto-op
> > > approach.
> > > That's why the general idea - have all data that wouldn't change from packet
> to
> > > packet
> > > included into the session and setup it once at session_init().
> >
> > I agree that you cannot use crypto-op.
> > You can have the new API in crypto.
> > As per the current patch, you only need cipher_offset which you can have it as
> a parameter until
> > You get it approved in the crypto xform. I believe it will be beneficial in case of
> other crypto cases as well.
> > We can have cipher offset at both places(crypto-op and cipher_xform). It will
> give flexibility to the user to
> > override it.
> 
> After having another thought on your proposal:
> Probably we can introduce new rte_crypto_sym_xform_types for CPU related
> stuff here?

I also thought of adding new xforms, but that wont serve the purpose for may be all the cases.
You would be needing all information currently available in the current xforms.
So if you are adding new fields in the new xform, the size will be more than that of the union of xforms.
ABI breakage would still be there. 

If you think a valid compression of the AEAD xform can be done, then that can be done for each of the
Xforms and we can have a solution to this issue.

> Let say we can have :
> num rte_crypto_sym_xform_type {
>         RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED = 0, /**< No xform specified
> */
>         RTE_CRYPTO_SYM_XFORM_AUTH,              /**< Authentication xform */
>         RTE_CRYPTO_SYM_XFORM_CIPHER,            /**< Cipher xform  */
>         RTE_CRYPTO_SYM_XFORM_AEAD               /**< AEAD xform  */
> +     RTE_CRYPTO_SYM_XFORM_CPU = INT32_MIN,
> +    RTE_CRYPTO_SYM_XFORM_CPU_AEAD = (RTE_CRYPTO_SYM_XFORM_CPU |
> RTE_CRYPTO_SYM_XFORM_CPU),

Instead of CPU I believe SYNC would be better.

>       /* same for auth and crypto xforms */
> };
> 
> Then we either can re-define some values in struct rte_crypto_aead_xform (via
> unions),
> or even have new  struct rte_crypto_cpu_aead_xform (same for crypto and auth
> xforms).
> Then if PMD wants to support new sync API it would need to recognize new
> xform types
> and internally  it might end up with different session structure (one for sync,
> another for async mode).
> That I think should allow us to introduce cpu_crypto as part of crypto-dev API
> without ABI breakage.
> What do you think?
> Konstantin
> 
> >
> > >
> > > > If you intend not to use rte_crypto_op
> > > > You can pass this as an argument in the new cryptodev API.
> > >
> > > You mean extra parameter in rte_security_process_cpu_crypto_bulk()?
> > > It can be in theory, but that solution looks a bit ugly:
> > > 	why to pass for each call something that would be constant per session?
> > > 	Again having that value constant per session might allow some extra
> > > optimisations
> > > 	That would be hard to achieve for dynamic case.
> > > and not extendable:
> > > Suppose tomorrow will need to add something extra (some new algorithm
> > > support or so).
> > > With what you proposing will need to new parameter to the function,
> > > which means API breakage.
> > >
> > > > Something extra will also cause ABI breakage in security as well.
> > > > So it will be same.
> > >
> > > I don't think it would.
> > > AFAIK, right now this patch doesn't introduce any API/ABI breakage.
> > > Iinside struct rte_security_session_conf we have a union of xforms
> > > depending on session type.
> > > So as long as cpu_crypto_xform wouldn't exceed sizes of other xform -
> > > I believe no ABI breakage will appear.
> > Agreed, it will not break ABI in case of security till we do not exceed current
> size.
> >
> > Saving an ABI/API breakage is more important or placing the code at the
> correct place.
> > We need to find a tradeoff. Others can comment on this.
> > @Thomas Monjalon, @De Lara Guarch, Pablo Any comments?
> >
> > >
> > >
> > > >
> > > > > Also right now there is no way to add new type of crypto_sym_session
> > > without
> > > > > either breaking existing crypto-dev ABI/API or introducing new structure
> > > > > (rte_crypto_sym_cpu_session or so) for that.
> > > >
> > > > What extra info is required in rte_cryptodev_sym_session to get the
> > > rte_crypto_sym_cpu_session.
> > >
> > > Right now - just cipher_offset (see above).
> > > What else in future (if any) - don't know.
> > >
> > > > I don't think there is any.
> > > > I believe the same crypto session will be able to work synchronously as well.
> > >
> > > Exactly the same - problematically, see above.
> > >
> > > > We would only need  a new API to perform synchronous actions.
> > > > That will reduce the duplication code significantly
> > > > in the driver to support 2 different kind of APIs with similar code inside.
> > > > Please correct me in case I am missing something.
> > >
> > > To add new API into crypto-dev would also require changes in the PMD,
> > > it wouldn't come totally free and I believe would require roughly the same
> > > amount of changes.
> >
> > It will be required only in the PMDs which support it and would be minimal.
> > You would need a feature flag, support  for that synchronous API. Session
> information will
> > already be there in the session. The changes wrt cipher_offset need to be
> added
> > but with some default value to identify override will be done or not.
> >
> > >
> > > >
> > > >
> > > > > While rte_security is designed in a way that we can add new session
> types
> > > and
> > > > > related parameters without causing API/ABI breakage.
> > > >
> > > > Yes the intent is to add new sessions based on various protocols that can
> be
> > > supported by the driver.
> > >
> > > Various protocols and different types of sessions (and devices they belong
> to).
> > > Let say right now we have INLINE_CRYPTO, INLINE_PROTO,
> LOOKASIDE_PROTO,
> > > etc.
> > > Here we introduce new type of session.
> >
> > What is the new value add to the existing sessions. The changes that we are
> doing
> > here is just to avoid an API/ABI breakage. The synchronous processing can
> happen on both
> > crypto and security session. This would mean, only the processing API should
> be defined,
> > rest all should be already there in the sessions.
> > In All other cases, INLINE - eth device was not having any format to perform
> crypto op
> > LOOKASIDE - PROTO - add protocol specific sessions which is not available in
> crypto.
> >
> > >
> > > > It is not that we should find it as an alternative to cryptodev and using it
> just
> > > because it will not cause
> > > > ABI/API breakage.
> > >
> > > I am considering this new API as an alternative to existing ones, but as an
> > > extension.
> > > Existing crypto-op API has its own advantages (generic), and I think we
> should
> > > keep it supported by all crypto-devs.
> > > From other side rte_security is an extendable framework that suits the
> purpose:
> > > allows easily (and yes without ABI breakage) introduce new API for special
> type
> > > of crypto-dev (SW based).
> > >
> > >
> >
> > Adding a synchronous processing API is understandable and can be added in
> both
> > Crypto as well as Security, but a new action type for it is not required.
> > Now whether to support that, we have ABI/API breakage, that is a different
> issue.
> > And we may have to deal with it if no other option is there.
> >
> > >
> > >
> > >
> > > > IMO the code should be placed where its intent is.
> > > >
> > > > >
> > > > > BTW, what is your concern with proposed approach (via rte_security)?
> > > > > From my perspective it is a lightweight change and it is totally optional
> > > > > for the crypto PMDs to support it or not.
> > > > > Konstantin
> > > > >
> > > > > > >
> > > > > > > AESNI-GCM and AESNI-MB PMDs are updated with this support.
> There is
> > > a
> > > > > small
> > > > > > > performance test app under
> app/test/security_aesni_gcm(mb)_perftest
> > > to
> > > > > > > prove.
> > > > > > >
> > > > > > > For the new API
> > > > > > > The packet is sent to the crypto device for symmetric crypto
> > > > > > > processing. The device will encrypt or decrypt the buffer based on the
> > > > > session
> > > > > > > data specified and preprocessed in the security session. Different
> > > > > > > than the inline or lookaside modes, when the function exits, the user
> will
> > > > > > > expect the buffers are either processed successfully, or having the
> error
> > > > > number
> > > > > > > assigned to the appropriate index of the status array.
> > > > > > >
> > > > > > > Will update the program's guide in the v1 patch.
> > > > > > >
> > > > > > > Regards,
> > > > > > > Fan
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > > > > > > > Sent: Wednesday, September 4, 2019 11:33 AM
> > > > > > > > To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> > > > > > > > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Doherty,
> > > > > Declan
> > > > > > > > <declan.doherty@intel.com>; De Lara Guarch, Pablo
> > > > > > > > <pablo.de.lara.guarch@intel.com>
> > > > > > > > Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action
> > > type
> > > > > and
> > > > > > > > API
> > > > > > > >
> > > > > > > > Hi Fan,
> > > > > > > >
> > > > > > > > >
> > > > > > > > > This patch introduce new
> > > RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > > > > > > action
> > > > > > > > > type to security library. The type represents performing crypto
> > > > > > > > > operation with CPU cycles. The patch also includes a new API to
> > > > > > > > > process crypto operations in bulk and the function pointers for
> PMDs.
> > > > > > > > >
> > > > > > > > I am not able to get the flow of execution for this action type.
> Could
> > > you
> > > > > > > > please elaborate the flow in the documentation. If not in
> > > documentation
> > > > > > > > right now, then please elaborate the flow in cover letter.
> > > > > > > > Also I see that there are new APIs for processing crypto operations
> in
> > > bulk.
> > > > > > > > What does that mean. How are they different from the existing APIs
> > > which
> > > > > > > > are also handling bulk crypto ops depending on the budget.
> > > > > > > >
> > > > > > > >
> > > > > > > > -Akhil


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
  2019-09-16 14:53  3%                 ` Ananyev, Konstantin
@ 2019-09-16 15:08  0%                   ` Ananyev, Konstantin
  2019-09-17  6:02  3%                   ` Akhil Goyal
  1 sibling, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2019-09-16 15:08 UTC (permalink / raw)
  To: Ananyev, Konstantin, Akhil Goyal, dev, De Lara Guarch, Pablo,
	Thomas Monjalon
  Cc: Zhang, Roy Fan, Doherty, Declan, Anoob Joseph


> Hi Akhil,
> 
> > > > > > > This action type allows the burst of symmetric crypto workload using the
> > > > > same
> > > > > > > algorithm, key, and direction being processed by CPU cycles
> > > synchronously.
> > > > > > > This flexible action type does not require external hardware involvement,
> > > > > > > having the crypto workload processed synchronously, and is more
> > > > > performant
> > > > > > > than Cryptodev SW PMD due to the saved cycles on removed "async
> > > mode
> > > > > > > simulation" as well as 3 cacheline access of the crypto ops.
> > > > > >
> > > > > > Does that mean application will not call the cryptodev_enqueue_burst and
> > > > > corresponding dequeue burst.
> > > > >
> > > > > Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> > > > >
> > > > > > It would be a new API something like process_packets and it will have the
> > > > > crypto processed packets while returning from the API?
> > > > >
> > > > > Yes, though the plan is that API will operate on raw data buffers, not mbufs.
> > > > >
> > > > > >
> > > > > > I still do not understand why we cannot do with the conventional crypto lib
> > > > > only.
> > > > > > As far as I can understand, you are not doing any protocol processing or
> > > any
> > > > > value add
> > > > > > To the crypto processing. IMO, you just need a synchronous crypto
> > > processing
> > > > > API which
> > > > > > Can be defined in cryptodev, you don't need to re-create a crypto session
> > > in
> > > > > the name of
> > > > > > Security session in the driver just to do a synchronous processing.
> > > > >
> > > > > I suppose your question is why not to have
> > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > The main reason is that would require disruptive changes in existing
> > > cryptodev
> > > > > API
> > > > > (would cause ABI/API breakage).
> > > > > Session for  RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need some extra
> > > > > information
> > > > > that normal crypto_sym_xform doesn't contain
> > > > > (cipher offset from the start of the buffer, might be something extra in
> > > future).
> > > >
> > > > Cipher offset will be part of rte_crypto_op.
> > >
> > > fill/read (+ alloc/free) is one of the main things that slowdown current crypto-op
> > > approach.
> > > That's why the general idea - have all data that wouldn't change from packet to
> > > packet
> > > included into the session and setup it once at session_init().
> >
> > I agree that you cannot use crypto-op.
> > You can have the new API in crypto.
> > As per the current patch, you only need cipher_offset which you can have it as a parameter until
> > You get it approved in the crypto xform. I believe it will be beneficial in case of other crypto cases as well.
> > We can have cipher offset at both places(crypto-op and cipher_xform). It will give flexibility to the user to
> > override it.
> 
> After having another thought on your proposal:
> Probably we can introduce new rte_crypto_sym_xform_types for CPU related stuff here?
> Let say we can have :
> num rte_crypto_sym_xform_type {
>         RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED = 0, /**< No xform specified */
>         RTE_CRYPTO_SYM_XFORM_AUTH,              /**< Authentication xform */
>         RTE_CRYPTO_SYM_XFORM_CIPHER,            /**< Cipher xform  */
>         RTE_CRYPTO_SYM_XFORM_AEAD               /**< AEAD xform  */
> +     RTE_CRYPTO_SYM_XFORM_CPU = INT32_MIN,
> +    RTE_CRYPTO_SYM_XFORM_CPU_AEAD = (RTE_CRYPTO_SYM_XFORM_CPU | RTE_CRYPTO_SYM_XFORM_CPU),
Meant
RTE_CRYPTO_SYM_XFORM_CPU_AEAD = (RTE_CRYPTO_SYM_XFORM_CPU | RTE_CRYPTO_SYM_XFORM_AEAD),
of course.

>       /* same for auth and crypto xforms */
> };
> 
> Then we either can re-define some values in struct rte_crypto_aead_xform (via unions),
> or even have new  struct rte_crypto_cpu_aead_xform (same for crypto and auth xforms).
> Then if PMD wants to support new sync API it would need to recognize new xform types
> and internally  it might end up with different session structure (one for sync, another for async mode).
> That I think should allow us to introduce cpu_crypto as part of crypto-dev API without ABI breakage.
> What do you think?
> Konstantin
> 
> >
> > >
> > > > If you intend not to use rte_crypto_op
> > > > You can pass this as an argument in the new cryptodev API.
> > >
> > > You mean extra parameter in rte_security_process_cpu_crypto_bulk()?
> > > It can be in theory, but that solution looks a bit ugly:
> > > 	why to pass for each call something that would be constant per session?
> > > 	Again having that value constant per session might allow some extra
> > > optimisations
> > > 	That would be hard to achieve for dynamic case.
> > > and not extendable:
> > > Suppose tomorrow will need to add something extra (some new algorithm
> > > support or so).
> > > With what you proposing will need to new parameter to the function,
> > > which means API breakage.
> > >
> > > > Something extra will also cause ABI breakage in security as well.
> > > > So it will be same.
> > >
> > > I don't think it would.
> > > AFAIK, right now this patch doesn't introduce any API/ABI breakage.
> > > Iinside struct rte_security_session_conf we have a union of xforms
> > > depending on session type.
> > > So as long as cpu_crypto_xform wouldn't exceed sizes of other xform -
> > > I believe no ABI breakage will appear.
> > Agreed, it will not break ABI in case of security till we do not exceed current size.
> >
> > Saving an ABI/API breakage is more important or placing the code at the correct place.
> > We need to find a tradeoff. Others can comment on this.
> > @Thomas Monjalon, @De Lara Guarch, Pablo Any comments?
> >
> > >
> > >
> > > >
> > > > > Also right now there is no way to add new type of crypto_sym_session
> > > without
> > > > > either breaking existing crypto-dev ABI/API or introducing new structure
> > > > > (rte_crypto_sym_cpu_session or so) for that.
> > > >
> > > > What extra info is required in rte_cryptodev_sym_session to get the
> > > rte_crypto_sym_cpu_session.
> > >
> > > Right now - just cipher_offset (see above).
> > > What else in future (if any) - don't know.
> > >
> > > > I don't think there is any.
> > > > I believe the same crypto session will be able to work synchronously as well.
> > >
> > > Exactly the same - problematically, see above.
> > >
> > > > We would only need  a new API to perform synchronous actions.
> > > > That will reduce the duplication code significantly
> > > > in the driver to support 2 different kind of APIs with similar code inside.
> > > > Please correct me in case I am missing something.
> > >
> > > To add new API into crypto-dev would also require changes in the PMD,
> > > it wouldn't come totally free and I believe would require roughly the same
> > > amount of changes.
> >
> > It will be required only in the PMDs which support it and would be minimal.
> > You would need a feature flag, support  for that synchronous API. Session information will
> > already be there in the session. The changes wrt cipher_offset need to be added
> > but with some default value to identify override will be done or not.
> >
> > >
> > > >
> > > >
> > > > > While rte_security is designed in a way that we can add new session types
> > > and
> > > > > related parameters without causing API/ABI breakage.
> > > >
> > > > Yes the intent is to add new sessions based on various protocols that can be
> > > supported by the driver.
> > >
> > > Various protocols and different types of sessions (and devices they belong to).
> > > Let say right now we have INLINE_CRYPTO, INLINE_PROTO, LOOKASIDE_PROTO,
> > > etc.
> > > Here we introduce new type of session.
> >
> > What is the new value add to the existing sessions. The changes that we are doing
> > here is just to avoid an API/ABI breakage. The synchronous processing can happen on both
> > crypto and security session. This would mean, only the processing API should be defined,
> > rest all should be already there in the sessions.
> > In All other cases, INLINE - eth device was not having any format to perform crypto op
> > LOOKASIDE - PROTO - add protocol specific sessions which is not available in crypto.
> >
> > >
> > > > It is not that we should find it as an alternative to cryptodev and using it just
> > > because it will not cause
> > > > ABI/API breakage.
> > >
> > > I am considering this new API as an alternative to existing ones, but as an
> > > extension.
> > > Existing crypto-op API has its own advantages (generic), and I think we should
> > > keep it supported by all crypto-devs.
> > > From other side rte_security is an extendable framework that suits the purpose:
> > > allows easily (and yes without ABI breakage) introduce new API for special type
> > > of crypto-dev (SW based).
> > >
> > >
> >
> > Adding a synchronous processing API is understandable and can be added in both
> > Crypto as well as Security, but a new action type for it is not required.
> > Now whether to support that, we have ABI/API breakage, that is a different issue.
> > And we may have to deal with it if no other option is there.
> >
> > >
> > >
> > >
> > > > IMO the code should be placed where its intent is.
> > > >
> > > > >
> > > > > BTW, what is your concern with proposed approach (via rte_security)?
> > > > > From my perspective it is a lightweight change and it is totally optional
> > > > > for the crypto PMDs to support it or not.
> > > > > Konstantin
> > > > >
> > > > > > >
> > > > > > > AESNI-GCM and AESNI-MB PMDs are updated with this support. There is
> > > a
> > > > > small
> > > > > > > performance test app under app/test/security_aesni_gcm(mb)_perftest
> > > to
> > > > > > > prove.
> > > > > > >
> > > > > > > For the new API
> > > > > > > The packet is sent to the crypto device for symmetric crypto
> > > > > > > processing. The device will encrypt or decrypt the buffer based on the
> > > > > session
> > > > > > > data specified and preprocessed in the security session. Different
> > > > > > > than the inline or lookaside modes, when the function exits, the user will
> > > > > > > expect the buffers are either processed successfully, or having the error
> > > > > number
> > > > > > > assigned to the appropriate index of the status array.
> > > > > > >
> > > > > > > Will update the program's guide in the v1 patch.
> > > > > > >
> > > > > > > Regards,
> > > > > > > Fan
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > > > > > > > Sent: Wednesday, September 4, 2019 11:33 AM
> > > > > > > > To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> > > > > > > > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Doherty,
> > > > > Declan
> > > > > > > > <declan.doherty@intel.com>; De Lara Guarch, Pablo
> > > > > > > > <pablo.de.lara.guarch@intel.com>
> > > > > > > > Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action
> > > type
> > > > > and
> > > > > > > > API
> > > > > > > >
> > > > > > > > Hi Fan,
> > > > > > > >
> > > > > > > > >
> > > > > > > > > This patch introduce new
> > > RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > > > > > > action
> > > > > > > > > type to security library. The type represents performing crypto
> > > > > > > > > operation with CPU cycles. The patch also includes a new API to
> > > > > > > > > process crypto operations in bulk and the function pointers for PMDs.
> > > > > > > > >
> > > > > > > > I am not able to get the flow of execution for this action type. Could
> > > you
> > > > > > > > please elaborate the flow in the documentation. If not in
> > > documentation
> > > > > > > > right now, then please elaborate the flow in cover letter.
> > > > > > > > Also I see that there are new APIs for processing crypto operations in
> > > bulk.
> > > > > > > > What does that mean. How are they different from the existing APIs
> > > which
> > > > > > > > are also handling bulk crypto ops depending on the budget.
> > > > > > > >
> > > > > > > >
> > > > > > > > -Akhil


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
  2019-09-12 14:12  5%               ` Akhil Goyal
@ 2019-09-16 14:53  3%                 ` Ananyev, Konstantin
  2019-09-16 15:08  0%                   ` Ananyev, Konstantin
  2019-09-17  6:02  3%                   ` Akhil Goyal
  0 siblings, 2 replies; 200+ results
From: Ananyev, Konstantin @ 2019-09-16 14:53 UTC (permalink / raw)
  To: Akhil Goyal, dev, De Lara Guarch, Pablo, Thomas Monjalon
  Cc: Zhang, Roy Fan, Doherty, Declan, Anoob Joseph

Hi Akhil,

> > > > > > This action type allows the burst of symmetric crypto workload using the
> > > > same
> > > > > > algorithm, key, and direction being processed by CPU cycles
> > synchronously.
> > > > > > This flexible action type does not require external hardware involvement,
> > > > > > having the crypto workload processed synchronously, and is more
> > > > performant
> > > > > > than Cryptodev SW PMD due to the saved cycles on removed "async
> > mode
> > > > > > simulation" as well as 3 cacheline access of the crypto ops.
> > > > >
> > > > > Does that mean application will not call the cryptodev_enqueue_burst and
> > > > corresponding dequeue burst.
> > > >
> > > > Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> > > >
> > > > > It would be a new API something like process_packets and it will have the
> > > > crypto processed packets while returning from the API?
> > > >
> > > > Yes, though the plan is that API will operate on raw data buffers, not mbufs.
> > > >
> > > > >
> > > > > I still do not understand why we cannot do with the conventional crypto lib
> > > > only.
> > > > > As far as I can understand, you are not doing any protocol processing or
> > any
> > > > value add
> > > > > To the crypto processing. IMO, you just need a synchronous crypto
> > processing
> > > > API which
> > > > > Can be defined in cryptodev, you don't need to re-create a crypto session
> > in
> > > > the name of
> > > > > Security session in the driver just to do a synchronous processing.
> > > >
> > > > I suppose your question is why not to have
> > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > The main reason is that would require disruptive changes in existing
> > cryptodev
> > > > API
> > > > (would cause ABI/API breakage).
> > > > Session for  RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need some extra
> > > > information
> > > > that normal crypto_sym_xform doesn't contain
> > > > (cipher offset from the start of the buffer, might be something extra in
> > future).
> > >
> > > Cipher offset will be part of rte_crypto_op.
> >
> > fill/read (+ alloc/free) is one of the main things that slowdown current crypto-op
> > approach.
> > That's why the general idea - have all data that wouldn't change from packet to
> > packet
> > included into the session and setup it once at session_init().
> 
> I agree that you cannot use crypto-op.
> You can have the new API in crypto.
> As per the current patch, you only need cipher_offset which you can have it as a parameter until
> You get it approved in the crypto xform. I believe it will be beneficial in case of other crypto cases as well.
> We can have cipher offset at both places(crypto-op and cipher_xform). It will give flexibility to the user to
> override it.

After having another thought on your proposal: 
Probably we can introduce new rte_crypto_sym_xform_types for CPU related stuff here?
Let say we can have :
num rte_crypto_sym_xform_type {
        RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED = 0, /**< No xform specified */
        RTE_CRYPTO_SYM_XFORM_AUTH,              /**< Authentication xform */
        RTE_CRYPTO_SYM_XFORM_CIPHER,            /**< Cipher xform  */
        RTE_CRYPTO_SYM_XFORM_AEAD               /**< AEAD xform  */
+     RTE_CRYPTO_SYM_XFORM_CPU = INT32_MIN,
+    RTE_CRYPTO_SYM_XFORM_CPU_AEAD = (RTE_CRYPTO_SYM_XFORM_CPU | RTE_CRYPTO_SYM_XFORM_CPU),
      /* same for auth and crypto xforms */
};

Then we either can re-define some values in struct rte_crypto_aead_xform (via unions),
or even have new  struct rte_crypto_cpu_aead_xform (same for crypto and auth xforms).
Then if PMD wants to support new sync API it would need to recognize new xform types
and internally  it might end up with different session structure (one for sync, another for async mode).
That I think should allow us to introduce cpu_crypto as part of crypto-dev API without ABI breakage.
What do you think?
Konstantin 
 
> 
> >
> > > If you intend not to use rte_crypto_op
> > > You can pass this as an argument in the new cryptodev API.
> >
> > You mean extra parameter in rte_security_process_cpu_crypto_bulk()?
> > It can be in theory, but that solution looks a bit ugly:
> > 	why to pass for each call something that would be constant per session?
> > 	Again having that value constant per session might allow some extra
> > optimisations
> > 	That would be hard to achieve for dynamic case.
> > and not extendable:
> > Suppose tomorrow will need to add something extra (some new algorithm
> > support or so).
> > With what you proposing will need to new parameter to the function,
> > which means API breakage.
> >
> > > Something extra will also cause ABI breakage in security as well.
> > > So it will be same.
> >
> > I don't think it would.
> > AFAIK, right now this patch doesn't introduce any API/ABI breakage.
> > Iinside struct rte_security_session_conf we have a union of xforms
> > depending on session type.
> > So as long as cpu_crypto_xform wouldn't exceed sizes of other xform -
> > I believe no ABI breakage will appear.
> Agreed, it will not break ABI in case of security till we do not exceed current size.
> 
> Saving an ABI/API breakage is more important or placing the code at the correct place.
> We need to find a tradeoff. Others can comment on this.
> @Thomas Monjalon, @De Lara Guarch, Pablo Any comments?
> 
> >
> >
> > >
> > > > Also right now there is no way to add new type of crypto_sym_session
> > without
> > > > either breaking existing crypto-dev ABI/API or introducing new structure
> > > > (rte_crypto_sym_cpu_session or so) for that.
> > >
> > > What extra info is required in rte_cryptodev_sym_session to get the
> > rte_crypto_sym_cpu_session.
> >
> > Right now - just cipher_offset (see above).
> > What else in future (if any) - don't know.
> >
> > > I don't think there is any.
> > > I believe the same crypto session will be able to work synchronously as well.
> >
> > Exactly the same - problematically, see above.
> >
> > > We would only need  a new API to perform synchronous actions.
> > > That will reduce the duplication code significantly
> > > in the driver to support 2 different kind of APIs with similar code inside.
> > > Please correct me in case I am missing something.
> >
> > To add new API into crypto-dev would also require changes in the PMD,
> > it wouldn't come totally free and I believe would require roughly the same
> > amount of changes.
> 
> It will be required only in the PMDs which support it and would be minimal.
> You would need a feature flag, support  for that synchronous API. Session information will
> already be there in the session. The changes wrt cipher_offset need to be added
> but with some default value to identify override will be done or not.
> 
> >
> > >
> > >
> > > > While rte_security is designed in a way that we can add new session types
> > and
> > > > related parameters without causing API/ABI breakage.
> > >
> > > Yes the intent is to add new sessions based on various protocols that can be
> > supported by the driver.
> >
> > Various protocols and different types of sessions (and devices they belong to).
> > Let say right now we have INLINE_CRYPTO, INLINE_PROTO, LOOKASIDE_PROTO,
> > etc.
> > Here we introduce new type of session.
> 
> What is the new value add to the existing sessions. The changes that we are doing
> here is just to avoid an API/ABI breakage. The synchronous processing can happen on both
> crypto and security session. This would mean, only the processing API should be defined,
> rest all should be already there in the sessions.
> In All other cases, INLINE - eth device was not having any format to perform crypto op
> LOOKASIDE - PROTO - add protocol specific sessions which is not available in crypto.
> 
> >
> > > It is not that we should find it as an alternative to cryptodev and using it just
> > because it will not cause
> > > ABI/API breakage.
> >
> > I am considering this new API as an alternative to existing ones, but as an
> > extension.
> > Existing crypto-op API has its own advantages (generic), and I think we should
> > keep it supported by all crypto-devs.
> > From other side rte_security is an extendable framework that suits the purpose:
> > allows easily (and yes without ABI breakage) introduce new API for special type
> > of crypto-dev (SW based).
> >
> >
> 
> Adding a synchronous processing API is understandable and can be added in both
> Crypto as well as Security, but a new action type for it is not required.
> Now whether to support that, we have ABI/API breakage, that is a different issue.
> And we may have to deal with it if no other option is there.
> 
> >
> >
> >
> > > IMO the code should be placed where its intent is.
> > >
> > > >
> > > > BTW, what is your concern with proposed approach (via rte_security)?
> > > > From my perspective it is a lightweight change and it is totally optional
> > > > for the crypto PMDs to support it or not.
> > > > Konstantin
> > > >
> > > > > >
> > > > > > AESNI-GCM and AESNI-MB PMDs are updated with this support. There is
> > a
> > > > small
> > > > > > performance test app under app/test/security_aesni_gcm(mb)_perftest
> > to
> > > > > > prove.
> > > > > >
> > > > > > For the new API
> > > > > > The packet is sent to the crypto device for symmetric crypto
> > > > > > processing. The device will encrypt or decrypt the buffer based on the
> > > > session
> > > > > > data specified and preprocessed in the security session. Different
> > > > > > than the inline or lookaside modes, when the function exits, the user will
> > > > > > expect the buffers are either processed successfully, or having the error
> > > > number
> > > > > > assigned to the appropriate index of the status array.
> > > > > >
> > > > > > Will update the program's guide in the v1 patch.
> > > > > >
> > > > > > Regards,
> > > > > > Fan
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > > > > > > Sent: Wednesday, September 4, 2019 11:33 AM
> > > > > > > To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> > > > > > > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Doherty,
> > > > Declan
> > > > > > > <declan.doherty@intel.com>; De Lara Guarch, Pablo
> > > > > > > <pablo.de.lara.guarch@intel.com>
> > > > > > > Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action
> > type
> > > > and
> > > > > > > API
> > > > > > >
> > > > > > > Hi Fan,
> > > > > > >
> > > > > > > >
> > > > > > > > This patch introduce new
> > RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > > > > > action
> > > > > > > > type to security library. The type represents performing crypto
> > > > > > > > operation with CPU cycles. The patch also includes a new API to
> > > > > > > > process crypto operations in bulk and the function pointers for PMDs.
> > > > > > > >
> > > > > > > I am not able to get the flow of execution for this action type. Could
> > you
> > > > > > > please elaborate the flow in the documentation. If not in
> > documentation
> > > > > > > right now, then please elaborate the flow in cover letter.
> > > > > > > Also I see that there are new APIs for processing crypto operations in
> > bulk.
> > > > > > > What does that mean. How are they different from the existing APIs
> > which
> > > > > > > are also handling bulk crypto ops depending on the budget.
> > > > > > >
> > > > > > >
> > > > > > > -Akhil


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v3 01/13] ethdev: change promiscuous mode controllers to return errors
  @ 2019-09-14 11:37  3%   ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-14 11:37 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Bernard Iremonger,
	Ori Kam, Bruce Richardson, Radu Nicolau, Akhil Goyal,
	Tomasz Kantecki, Harry van Haaren, Xiaoyun Li, Thomas Monjalon,
	Ferruh Yigit
  Cc: dev, Ivan Ilchenko

From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>

Change rte_eth_promiscuous_enable()/rte_eth_promiscuous_disable()
return value from void to int and return negative errno values
in case of error conditions.
Modify usage of these functions across the ethdev according
to new return type.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst        |  1 -
 doc/guides/rel_notes/release_19_11.rst      |  4 ++
 doc/guides/sample_app_ug/flow_classify.rst  |  6 ++-
 doc/guides/sample_app_ug/flow_filtering.rst | 15 +++++-
 doc/guides/sample_app_ug/rxtx_callbacks.rst |  5 +-
 doc/guides/sample_app_ug/skeleton.rst       |  6 ++-
 lib/librte_ethdev/rte_ethdev.c              | 52 ++++++++++++++++-----
 lib/librte_ethdev/rte_ethdev.h              | 14 +++++-
 8 files changed, 80 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index cbb4c34ef..b2e0a1fc7 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_promiscuous_enable`` and ``rte_eth_promiscuous_disable``
   - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
   - ``rte_eth_dev_stop``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index c8d97f16e..90c03cb8f 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -97,6 +97,10 @@ API Changes
 * ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void`` to
   ``int`` to provide a way to report various error conditions.
 
+* ethdev: changed ``rte_eth_promiscuous_enable`` and
+  ``rte_eth_promiscuous_disable`` return value from ``void`` to ``int`` to
+  provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
diff --git a/doc/guides/sample_app_ug/flow_classify.rst b/doc/guides/sample_app_ug/flow_classify.rst
index 96a5c66d0..7c2b6dcf8 100644
--- a/doc/guides/sample_app_ug/flow_classify.rst
+++ b/doc/guides/sample_app_ug/flow_classify.rst
@@ -315,7 +315,9 @@ Forwarding application is shown below:
                addr.addr_bytes[4], addr.addr_bytes[5]);
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+                return retval;
 
         return 0;
     }
@@ -343,7 +345,7 @@ Finally the RX port is set in promiscuous mode:
 
 .. code-block:: c
 
-    rte_eth_promiscuous_enable(port);
+    retval = rte_eth_promiscuous_enable(port);
 
 The Add Rules function
 ~~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/guides/sample_app_ug/flow_filtering.rst b/doc/guides/sample_app_ug/flow_filtering.rst
index 02fc67550..de3e4ab0b 100644
--- a/doc/guides/sample_app_ug/flow_filtering.rst
+++ b/doc/guides/sample_app_ug/flow_filtering.rst
@@ -193,7 +193,13 @@ application is shown below:
                    }
           }
 
-           rte_eth_promiscuous_enable(port_id);
+           ret = rte_eth_promiscuous_enable(port_id);
+           if (ret != 0) {
+                   rte_exit(EXIT_FAILURE,
+                           ":: cannot enable promiscuous mode: err=%d, port=%u\n",
+                           ret, port_id);
+           }
+
            ret = rte_eth_dev_start(port_id);
            if (ret < 0) {
                    rte_exit(EXIT_FAILURE,
@@ -278,7 +284,12 @@ We are setting the RX port to promiscuous mode:
 
 .. code-block:: c
 
-   rte_eth_promiscuous_enable(port_id);
+   ret = rte_eth_promiscuous_enable(port_id);
+   if (ret != 0) {
+        rte_exit(EXIT_FAILURE,
+                 ":: cannot enable promiscuous mode: err=%d, port=%u\n",
+                 ret, port_id);
+   }
 
 The last step is to start the port.
 
diff --git a/doc/guides/sample_app_ug/rxtx_callbacks.rst b/doc/guides/sample_app_ug/rxtx_callbacks.rst
index 32c120992..0a69ec71a 100644
--- a/doc/guides/sample_app_ug/rxtx_callbacks.rst
+++ b/doc/guides/sample_app_ug/rxtx_callbacks.rst
@@ -117,8 +117,9 @@ comments:
             return retval;
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
-
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+            return retval;
 
         /* Add the callbacks for RX and TX.*/
         rte_eth_add_rx_callback(port, 0, add_timestamps, NULL);
diff --git a/doc/guides/sample_app_ug/skeleton.rst b/doc/guides/sample_app_ug/skeleton.rst
index 59ca511d3..1d0a2760d 100644
--- a/doc/guides/sample_app_ug/skeleton.rst
+++ b/doc/guides/sample_app_ug/skeleton.rst
@@ -149,7 +149,9 @@ Forwarding application is shown below:
             return retval;
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+            return retval;
 
         return 0;
     }
@@ -177,7 +179,7 @@ Finally the RX port is set in promiscuous mode:
 
 .. code-block:: c
 
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
 
 
 The Lcores Main
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 30b0c7803..b97dd8aa8 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1381,24 +1381,41 @@ rte_eth_dev_mac_restore(struct rte_eth_dev *dev,
 	}
 }
 
-static void
+static int
 rte_eth_dev_config_restore(struct rte_eth_dev *dev,
 			   struct rte_eth_dev_info *dev_info, uint16_t port_id)
 {
+	int ret;
+
 	if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR))
 		rte_eth_dev_mac_restore(dev, dev_info);
 
 	/* replay promiscuous configuration */
-	if (rte_eth_promiscuous_get(port_id) == 1)
-		rte_eth_promiscuous_enable(port_id);
-	else if (rte_eth_promiscuous_get(port_id) == 0)
-		rte_eth_promiscuous_disable(port_id);
+	if (rte_eth_promiscuous_get(port_id) == 1) {
+		ret = rte_eth_promiscuous_enable(port_id);
+		if (ret != 0 && ret != -ENOTSUP) {
+			RTE_ETHDEV_LOG(ERR,
+				"Failed to enable promiscuous mode for device (port %u): %s\n",
+				port_id, rte_strerror(-ret));
+			return ret;
+		}
+	} else if (rte_eth_promiscuous_get(port_id) == 0) {
+		ret = rte_eth_promiscuous_disable(port_id);
+		if (ret != 0 && ret != -ENOTSUP) {
+			RTE_ETHDEV_LOG(ERR,
+				"Failed to disable promiscuous mode for device (port %u): %s\n",
+				port_id, rte_strerror(-ret));
+			return ret;
+		}
+	}
 
 	/* replay all multicast configuration */
 	if (rte_eth_allmulticast_get(port_id) == 1)
 		rte_eth_allmulticast_enable(port_id);
 	else if (rte_eth_allmulticast_get(port_id) == 0)
 		rte_eth_allmulticast_disable(port_id);
+
+	return 0;
 }
 
 int
@@ -1436,7 +1453,14 @@ rte_eth_dev_start(uint16_t port_id)
 	else
 		return eth_err(port_id, diag);
 
-	rte_eth_dev_config_restore(dev, &dev_info, port_id);
+	ret = rte_eth_dev_config_restore(dev, &dev_info, port_id);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Error during restoring configuration for device (port %u): %s\n",
+			port_id, rte_strerror(-ret));
+		rte_eth_dev_stop(port_id);
+		return ret;
+	}
 
 	if (dev->data->dev_conf.intr_conf.lsc == 0) {
 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
@@ -1864,30 +1888,34 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
 	return eth_err(port_id, ret);
 }
 
-void
+int
 rte_eth_promiscuous_enable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_enable);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP);
 	(*dev->dev_ops->promiscuous_enable)(dev);
 	dev->data->promiscuous = 1;
+
+	return 0;
 }
 
-void
+int
 rte_eth_promiscuous_disable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_disable);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP);
 	dev->data->promiscuous = 0;
 	(*dev->dev_ops->promiscuous_disable)(dev);
+
+	return 0;
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 475dbdae1..f07a829b2 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2022,16 +2022,26 @@ int rte_eth_dev_reset(uint16_t port_id);
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for promiscuous_enable() does not exist
+ *     for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_promiscuous_enable(uint16_t port_id);
+int rte_eth_promiscuous_enable(uint16_t port_id);
 
 /**
  * Disable receipt in promiscuous mode for an Ethernet device.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for promiscuous_disable() does not exist
+ *     for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_promiscuous_disable(uint16_t port_id);
+int rte_eth_promiscuous_disable(uint16_t port_id);
 
 /**
  * Return the value of promiscuous mode for an Ethernet device.
-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] The type string in the malloc library is unused
       [not found]     ` <CAOaVG17_bhBOfJdvHZOzoVO3t7CXCZCa7f=_Q=_Pi5jgnY3GzA@mail.gmail.com>
@ 2019-09-14  8:29  3%   ` Morten Brørup
  0 siblings, 0 replies; 200+ results
From: Morten Brørup @ 2019-09-14  8:29 UTC (permalink / raw)
  To: Stephen Hemminger, Anatoly Burakov; +Cc: Olivier Matz, Andrew Rybchenko, dev

I tend to agree with Stephen here, although it will break the API/ABI.

 

Another argument supporting its removal is the fact that it has remained non-implemented for many years, so a function for dumping information about rte_malloc'ed memory using the "type" string for debugging purposes has apparently not been in very high demand.

 

Med venlig hilsen / kind regards

- Morten Brørup

 

From: Stephen Hemminger [mailto:stephen@networkplumber.org] 
Sent: Saturday, September 14, 2019 8:24 AM
To: Morten Brørup
Subject: Re: [dpdk-dev] The type string in the malloc library is unused

 

I would vote for removing it.

It is too late to implement it without breaking existing code.

 

 

On Fri, Sep 13, 2019, 3:32 PM Morten Brørup <mb@smartsharesystems.com> wrote:

	Hi Anatoly,
	
	
	
	The functions in the DPDK malloc library takes a "type" parameter (a string, supposedly for debug purposes), but the underlying malloc_heap functions (which take the same string parameter) don't store or use this string for anything.
	
	
	
	Is the intention to implement this sometime in the future, or should it be considered for removal?
	
	
	


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v4 02/54] ethdev: change rte_eth_dev_info_get() return value to int
  2019-09-12 16:42  3%   ` [dpdk-dev] [PATCH v4 02/54] " Andrew Rybchenko
@ 2019-09-13 10:18  0%     ` Iremonger, Bernard
  0 siblings, 0 replies; 200+ results
From: Iremonger, Bernard @ 2019-09-13 10:18 UTC (permalink / raw)
  To: Andrew Rybchenko, Neil Horman, Mcnamara, John, Kovacevic, Marko,
	Thomas Monjalon, Yigit, Ferruh
  Cc: dev, Ivan Ilchenko

Hi Ivan,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Andrew Rybchenko
> Sent: Thursday, September 12, 2019 5:42 PM
> To: Neil Horman <nhorman@tuxdriver.com>; Mcnamara, John
> <john.mcnamara@intel.com>; Kovacevic, Marko
> <marko.kovacevic@intel.com>; Thomas Monjalon <thomas@monjalon.net>;
> Yigit, Ferruh <ferruh.yigit@intel.com>
> Cc: dev@dpdk.org; Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>
> Subject: [dpdk-dev] [PATCH v4 02/54] ethdev: change
> rte_eth_dev_info_get() return value to int
> 
> From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>
> 
> Change rte_eth_dev_info_get() return value from void to int and return
> negative errno values in case of error conditions.
> Modify rte_eth_dev_info_get() usage across the ethdev according to new
> return type.
> 
> Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>
> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

./check-git-log.sh -1
Wrong headline format:
        ethdev: change rte_eth_dev_info_get() return value to int

> ---
>  doc/guides/rel_notes/deprecation.rst   |  1 -
>  doc/guides/rel_notes/release_19_11.rst |  5 +-
>  lib/librte_ethdev/rte_ethdev.c         | 69 ++++++++++++++++++--------
>  lib/librte_ethdev/rte_ethdev.h         |  6 ++-
>  4 files changed, 57 insertions(+), 24 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/deprecation.rst
> b/doc/guides/rel_notes/deprecation.rst
> index 0ee8533b1..cbb4c34ef 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -88,7 +88,6 @@ Deprecation Notices
>    negative errno values to indicate various error conditions (e.g.
>    invalid port ID, unsupported operation, failed operation):
> 
> -  - ``rte_eth_dev_info_get``
>    - ``rte_eth_promiscuous_enable`` and ``rte_eth_promiscuous_disable``
>    - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
>    - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait`` diff --git
> a/doc/guides/rel_notes/release_19_11.rst
> b/doc/guides/rel_notes/release_19_11.rst
> index 66297d8f3..c8d97f16e 100644
> --- a/doc/guides/rel_notes/release_19_11.rst
> +++ b/doc/guides/rel_notes/release_19_11.rst
> @@ -94,6 +94,9 @@ API Changes
>     Also, make sure to start the actual text at the margin.
>     =========================================================
> 
> +* ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void``
> +to
> +  ``int`` to provide a way to report various error conditions.
> +
> 
>  ABI Changes
>  -----------
> @@ -145,7 +148,7 @@ The libraries prepended with a plus sign were
> incremented in this version.
>       librte_distributor.so.1
>       librte_eal.so.11
>       librte_efd.so.1
> -     librte_ethdev.so.12
> +   + librte_ethdev.so.13
>       librte_eventdev.so.7
>       librte_flow_classify.so.1
>       librte_gro.so.1
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index 17d183e1f..42b1d6e30 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -1125,7 +1125,6 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t
> nb_rx_q, uint16_t nb_tx_q,
> 
>  	dev = &rte_eth_devices[port_id];
> 
> -	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -
> ENOTSUP);
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -
> ENOTSUP);
> 
>  	if (dev->data->dev_started) {
> @@ -1144,7 +1143,9 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t
> nb_rx_q, uint16_t nb_tx_q,
>  	 */
>  	memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data-
> >dev_conf));
> 
> -	rte_eth_dev_info_get(port_id, &dev_info);
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		goto rollback;
> 
>  	/* If number of queues specified by application for both Rx and Tx is
>  	 * zero, use driver preferred values. This cannot be done individually
> @@ -1406,6 +1407,7 @@ rte_eth_dev_start(uint16_t port_id)
>  	struct rte_eth_dev *dev;
>  	struct rte_eth_dev_info dev_info;
>  	int diag;
> +	int ret;
> 
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
> 
> @@ -1420,7 +1422,9 @@ rte_eth_dev_start(uint16_t port_id)
>  		return 0;
>  	}
> 
> -	rte_eth_dev_info_get(port_id, &dev_info);
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		return ret;
> 
>  	/* Lets restore MAC now if device does not support live change */
>  	if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR) @@ -
> 1584,7 +1588,6 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t
> rx_queue_id,
>  		return -EINVAL;
>  	}
> 
> -	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -
> ENOTSUP);
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -
> ENOTSUP);
> 
>  	/*
> @@ -1592,7 +1595,10 @@ rte_eth_rx_queue_setup(uint16_t port_id,
> uint16_t rx_queue_id,
>  	 * This value must be provided in the private data of the memory
> pool.
>  	 * First check that the memory pool has a valid private data.
>  	 */
> -	rte_eth_dev_info_get(port_id, &dev_info);
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		return ret;
> +
>  	if (mp->private_data_size < sizeof(struct
> rte_pktmbuf_pool_private)) {
>  		RTE_ETHDEV_LOG(ERR, "%s private_data_size %d < %d\n",
>  			mp->name, (int)mp->private_data_size, @@ -1703,6
> +1709,7 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t
> tx_queue_id,
>  	struct rte_eth_dev_info dev_info;
>  	struct rte_eth_txconf local_conf;
>  	void **txq;
> +	int ret;
> 
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
> 
> @@ -1712,10 +1719,11 @@ rte_eth_tx_queue_setup(uint16_t port_id,
> uint16_t tx_queue_id,
>  		return -EINVAL;
>  	}
> 
> -	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -
> ENOTSUP);
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -
> ENOTSUP);
> 
> -	rte_eth_dev_info_get(port_id, &dev_info);
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		return ret;
> 
>  	/* Use default specified by driver, if nb_tx_desc is zero */
>  	if (nb_tx_desc == 0) {
> @@ -2540,7 +2548,7 @@ rte_eth_dev_fw_version_get(uint16_t port_id,
> char *fw_version, size_t fw_size)
>  							fw_version,
> fw_size));
>  }
> 
> -void
> +int
>  rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info
> *dev_info)  {
>  	struct rte_eth_dev *dev;
> @@ -2558,7 +2566,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct
> rte_eth_dev_info *dev_info)
>  	 */
>  	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
> 
> -	RTE_ETH_VALID_PORTID_OR_RET(port_id);
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	dev = &rte_eth_devices[port_id];
> 
>  	dev_info->rx_desc_lim = lim;
> @@ -2567,13 +2575,15 @@ rte_eth_dev_info_get(uint16_t port_id, struct
> rte_eth_dev_info *dev_info)
>  	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
>  	dev_info->max_mtu = UINT16_MAX;
> 
> -	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -
> ENOTSUP);
>  	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
>  	dev_info->driver_name = dev->device->driver->name;
>  	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
>  	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
> 
>  	dev_info->dev_flags = &dev->data->dev_flags;
> +
> +	return 0;
>  }
> 
>  int
> @@ -2643,7 +2653,10 @@ rte_eth_dev_set_mtu(uint16_t port_id, uint16_t
> mtu)
>  	 * which relies on dev->dev_ops->dev_infos_get.
>  	 */
>  	if (*dev->dev_ops->dev_infos_get != NULL) {
> -		rte_eth_dev_info_get(port_id, &dev_info);
> +		ret = rte_eth_dev_info_get(port_id, &dev_info);
> +		if (ret != 0)
> +			return ret;
> +
>  		if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
>  			return -EINVAL;
>  	}
> @@ -2991,10 +3004,15 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
> {
>  	struct rte_eth_dev *dev;
>  	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
> +	int ret;
> 
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		return ret;
> +
>  	dev = &rte_eth_devices[port_id];
> -	rte_eth_dev_info_get(port_id, &dev_info);
>  	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
>  	    dev_info.flow_type_rss_offloads) {
>  		RTE_ETHDEV_LOG(ERR,
> @@ -3100,9 +3118,11 @@ get_mac_addr_index(uint16_t port_id, const
> struct rte_ether_addr *addr)
>  	struct rte_eth_dev_info dev_info;
>  	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
>  	unsigned i;
> +	int ret;
> 
> -	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> -	rte_eth_dev_info_get(port_id, &dev_info);
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		return -1;
> 
>  	for (i = 0; i < dev_info.max_mac_addrs; i++)
>  		if (memcmp(addr, &dev->data->mac_addrs[i], @@ -3233,8
> +3253,12 @@ get_hash_mac_addr_index(uint16_t port_id, const struct
> rte_ether_addr *addr)
>  	struct rte_eth_dev_info dev_info;
>  	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
>  	unsigned i;
> +	int ret;
> +
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		return -1;
> 
> -	rte_eth_dev_info_get(port_id, &dev_info);
>  	if (!dev->data->hash_mac_addrs)
>  		return -1;
> 
> @@ -3319,11 +3343,15 @@ int rte_eth_set_queue_rate_limit(uint16_t
> port_id, uint16_t queue_idx,
>  	struct rte_eth_dev *dev;
>  	struct rte_eth_dev_info dev_info;
>  	struct rte_eth_link link;
> +	int ret;
> 
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> 
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		return ret;
> +
>  	dev = &rte_eth_devices[port_id];
> -	rte_eth_dev_info_get(port_id, &dev_info);
>  	link = dev->data->dev_link;
> 
>  	if (queue_idx > dev_info.max_tx_queues) { @@ -4363,15 +4391,14
> @@ rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
>  				 uint16_t *nb_rx_desc,
>  				 uint16_t *nb_tx_desc)
>  {
> -	struct rte_eth_dev *dev;
>  	struct rte_eth_dev_info dev_info;
> +	int ret;
> 
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> 
> -	dev = &rte_eth_devices[port_id];
> -	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -
> ENOTSUP);
> -
> -	rte_eth_dev_info_get(port_id, &dev_info);
> +	ret = rte_eth_dev_info_get(port_id, &dev_info);
> +	if (ret != 0)
> +		return ret;
> 
>  	if (nb_rx_desc != NULL)
>  		rte_eth_dev_adjust_nb_desc(nb_rx_desc,
> &dev_info.rx_desc_lim); diff --git a/lib/librte_ethdev/rte_ethdev.h
> b/lib/librte_ethdev/rte_ethdev.h index d9871782e..475dbdae1 100644
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -2366,8 +2366,12 @@ void rte_eth_macaddr_get(uint16_t port_id,
> struct rte_ether_addr *mac_addr);
>   * @param dev_info
>   *   A pointer to a structure of type *rte_eth_dev_info* to be filled with
>   *   the contextual information of the Ethernet device.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the
> device.
> + *   - (-ENODEV) if *port_id* invalid.
>   */
> -void rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info
> *dev_info);
> +int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info
> +*dev_info);
> 
>  /**
>   * Retrieve the firmware version of a device.
> --
> 2.17.1

Regards,

Bernard.


^ permalink raw reply	[relevance 0%]

* [dpdk-dev] DPDK techboard minutes of September 11
@ 2019-09-12 16:46  5% Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-09-12 16:46 UTC (permalink / raw)
  To: dev; +Cc: techboard

Meeting notes for the DPDK technical board meeting held on 2019-05-08

Attendees: 9/9
	- Bruce Richardson
	- Ferruh Yigit
	- Hemant Agrawal
	- Jerin Jacob
	- Konstantin Ananyev
	- Maxime Coquelin
	- Olivier Matz
	- Stephen Hemminger
	- Thomas Monjalon


1/ Review of last meeting minutes

Starting now the meeting minutes should be drafted
in the next 24 hours after the meeting.
It has been decided that meeting minutes are agreed
if no objection one week after the draft is shared.


2/ Examples removal

Bruce and Hemant will start removing few useless examples
during 19.11 release cycle.


3/ ABI compatibility

The new ABI policy has been discussed for months
and will be a topic for a panel discussion in Bordeaux event.
The final version and agreement of the guidelines are expected soon.

The first step should start after 19.11 release,
and will forbid any change which is not ABI-compatible with 19.11.
This first period must be used to prepare a longer freeze.
Then it will be allowed to break ABI compatibility in release 20.11,
and a longer compatibility period (2 years) could start from 20.11.
Note that experimental functions can change at any time.


4/ Build systems

Meson support is almost complete.
Bruce will present the status in Bordeaux event.
Makefile system will be deprecated in the release 19.11,
and there will be a blocking warning in the default configuration
of the release 20.02. The date for Makefile removal has not been decided.
The configurability of current Meson integration needs to be discussed.


5/ Next techboard meeting will be face to face
in Bordeaux, on September 19 Thursday, at 9pm.




^ permalink raw reply	[relevance 5%]

* [dpdk-dev] [PATCH v4 02/54] ethdev: change rte_eth_dev_info_get() return value to int
  @ 2019-09-12 16:42  3%   ` Andrew Rybchenko
  2019-09-13 10:18  0%     ` Iremonger, Bernard
  0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-09-12 16:42 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Thomas Monjalon,
	Ferruh Yigit
  Cc: dev, Ivan Ilchenko

From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>

Change rte_eth_dev_info_get() return value from void to int and return
negative errno values in case of error conditions.
Modify rte_eth_dev_info_get() usage across the ethdev according
to new return type.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   |  1 -
 doc/guides/rel_notes/release_19_11.rst |  5 +-
 lib/librte_ethdev/rte_ethdev.c         | 69 ++++++++++++++++++--------
 lib/librte_ethdev/rte_ethdev.h         |  6 ++-
 4 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 0ee8533b1..cbb4c34ef 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_dev_info_get``
   - ``rte_eth_promiscuous_enable`` and ``rte_eth_promiscuous_disable``
   - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 66297d8f3..c8d97f16e 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -94,6 +94,9 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void`` to
+  ``int`` to provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
@@ -145,7 +148,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_distributor.so.1
      librte_eal.so.11
      librte_efd.so.1
-     librte_ethdev.so.12
+   + librte_ethdev.so.13
      librte_eventdev.so.7
      librte_flow_classify.so.1
      librte_gro.so.1
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e1f..42b1d6e30 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1125,7 +1125,6 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -1144,7 +1143,9 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	 */
 	memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf));
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		goto rollback;
 
 	/* If number of queues specified by application for both Rx and Tx is
 	 * zero, use driver preferred values. This cannot be done individually
@@ -1406,6 +1407,7 @@ rte_eth_dev_start(uint16_t port_id)
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
 	int diag;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1420,7 +1422,9 @@ rte_eth_dev_start(uint16_t port_id)
 		return 0;
 	}
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* Lets restore MAC now if device does not support live change */
 	if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)
@@ -1584,7 +1588,6 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 		return -EINVAL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP);
 
 	/*
@@ -1592,7 +1595,10 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	 * This value must be provided in the private data of the memory pool.
 	 * First check that the memory pool has a valid private data.
 	 */
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
 		RTE_ETHDEV_LOG(ERR, "%s private_data_size %d < %d\n",
 			mp->name, (int)mp->private_data_size,
@@ -1703,6 +1709,7 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_txconf local_conf;
 	void **txq;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1712,10 +1719,11 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 		return -EINVAL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP);
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* Use default specified by driver, if nb_tx_desc is zero */
 	if (nb_tx_desc == 0) {
@@ -2540,7 +2548,7 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 							fw_version, fw_size));
 }
 
-void
+int
 rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 {
 	struct rte_eth_dev *dev;
@@ -2558,7 +2566,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	 */
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	dev_info->rx_desc_lim = lim;
@@ -2567,13 +2575,15 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
 	dev_info->max_mtu = UINT16_MAX;
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
 
 	dev_info->dev_flags = &dev->data->dev_flags;
+
+	return 0;
 }
 
 int
@@ -2643,7 +2653,10 @@ rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
 	 * which relies on dev->dev_ops->dev_infos_get.
 	 */
 	if (*dev->dev_ops->dev_infos_get != NULL) {
-		rte_eth_dev_info_get(port_id, &dev_info);
+		ret = rte_eth_dev_info_get(port_id, &dev_info);
+		if (ret != 0)
+			return ret;
+
 		if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
 			return -EINVAL;
 	}
@@ -2991,10 +3004,15 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	dev = &rte_eth_devices[port_id];
-	rte_eth_dev_info_get(port_id, &dev_info);
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3100,9 +3118,11 @@ get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	unsigned i;
+	int ret;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return -1;
 
 	for (i = 0; i < dev_info.max_mac_addrs; i++)
 		if (memcmp(addr, &dev->data->mac_addrs[i],
@@ -3233,8 +3253,12 @@ get_hash_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	unsigned i;
+	int ret;
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return -1;
 
-	rte_eth_dev_info_get(port_id, &dev_info);
 	if (!dev->data->hash_mac_addrs)
 		return -1;
 
@@ -3319,11 +3343,15 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_link link;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	dev = &rte_eth_devices[port_id];
-	rte_eth_dev_info_get(port_id, &dev_info);
 	link = dev->data->dev_link;
 
 	if (queue_idx > dev_info.max_tx_queues) {
@@ -4363,15 +4391,14 @@ rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
 				 uint16_t *nb_rx_desc,
 				 uint16_t *nb_tx_desc)
 {
-	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
-	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
-
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	if (nb_rx_desc != NULL)
 		rte_eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim);
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index d9871782e..475dbdae1 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2366,8 +2366,12 @@ void rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  * @param dev_info
  *   A pointer to a structure of type *rte_eth_dev_info* to be filled with
  *   the contextual information of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
+int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
  * Retrieve the firmware version of a device.
-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
  2019-09-11 12:29  4%             ` Ananyev, Konstantin
@ 2019-09-12 14:12  5%               ` Akhil Goyal
  2019-09-16 14:53  3%                 ` Ananyev, Konstantin
  0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2019-09-12 14:12 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev, De Lara Guarch, Pablo, Thomas Monjalon
  Cc: Zhang, Roy Fan, Doherty, Declan, Anoob Joseph

Hi Konstantin,

> Hi Akhil,
> > >
> > > > > This action type allows the burst of symmetric crypto workload using the
> > > same
> > > > > algorithm, key, and direction being processed by CPU cycles
> synchronously.
> > > > > This flexible action type does not require external hardware involvement,
> > > > > having the crypto workload processed synchronously, and is more
> > > performant
> > > > > than Cryptodev SW PMD due to the saved cycles on removed "async
> mode
> > > > > simulation" as well as 3 cacheline access of the crypto ops.
> > > >
> > > > Does that mean application will not call the cryptodev_enqueue_burst and
> > > corresponding dequeue burst.
> > >
> > > Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> > >
> > > > It would be a new API something like process_packets and it will have the
> > > crypto processed packets while returning from the API?
> > >
> > > Yes, though the plan is that API will operate on raw data buffers, not mbufs.
> > >
> > > >
> > > > I still do not understand why we cannot do with the conventional crypto lib
> > > only.
> > > > As far as I can understand, you are not doing any protocol processing or
> any
> > > value add
> > > > To the crypto processing. IMO, you just need a synchronous crypto
> processing
> > > API which
> > > > Can be defined in cryptodev, you don't need to re-create a crypto session
> in
> > > the name of
> > > > Security session in the driver just to do a synchronous processing.
> > >
> > > I suppose your question is why not to have
> > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > The main reason is that would require disruptive changes in existing
> cryptodev
> > > API
> > > (would cause ABI/API breakage).
> > > Session for  RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need some extra
> > > information
> > > that normal crypto_sym_xform doesn't contain
> > > (cipher offset from the start of the buffer, might be something extra in
> future).
> >
> > Cipher offset will be part of rte_crypto_op.
> 
> fill/read (+ alloc/free) is one of the main things that slowdown current crypto-op
> approach.
> That's why the general idea - have all data that wouldn't change from packet to
> packet
> included into the session and setup it once at session_init().

I agree that you cannot use crypto-op.
You can have the new API in crypto.
As per the current patch, you only need cipher_offset which you can have it as a parameter until
You get it approved in the crypto xform. I believe it will be beneficial in case of other crypto cases as well.
We can have cipher offset at both places(crypto-op and cipher_xform). It will give flexibility to the user to
override it.


> 
> > If you intend not to use rte_crypto_op
> > You can pass this as an argument in the new cryptodev API.
> 
> You mean extra parameter in rte_security_process_cpu_crypto_bulk()?
> It can be in theory, but that solution looks a bit ugly:
> 	why to pass for each call something that would be constant per session?
> 	Again having that value constant per session might allow some extra
> optimisations
> 	That would be hard to achieve for dynamic case.
> and not extendable:
> Suppose tomorrow will need to add something extra (some new algorithm
> support or so).
> With what you proposing will need to new parameter to the function,
> which means API breakage.
> 
> > Something extra will also cause ABI breakage in security as well.
> > So it will be same.
> 
> I don't think it would.
> AFAIK, right now this patch doesn't introduce any API/ABI breakage.
> Iinside struct rte_security_session_conf we have a union of xforms
> depending on session type.
> So as long as cpu_crypto_xform wouldn't exceed sizes of other xform -
> I believe no ABI breakage will appear.
Agreed, it will not break ABI in case of security till we do not exceed current size.

Saving an ABI/API breakage is more important or placing the code at the correct place.
We need to find a tradeoff. Others can comment on this.
@Thomas Monjalon, @De Lara Guarch, Pablo Any comments?

> 
> 
> >
> > > Also right now there is no way to add new type of crypto_sym_session
> without
> > > either breaking existing crypto-dev ABI/API or introducing new structure
> > > (rte_crypto_sym_cpu_session or so) for that.
> >
> > What extra info is required in rte_cryptodev_sym_session to get the
> rte_crypto_sym_cpu_session.
> 
> Right now - just cipher_offset (see above).
> What else in future (if any) - don't know.
> 
> > I don't think there is any.
> > I believe the same crypto session will be able to work synchronously as well.
> 
> Exactly the same - problematically, see above.
> 
> > We would only need  a new API to perform synchronous actions.
> > That will reduce the duplication code significantly
> > in the driver to support 2 different kind of APIs with similar code inside.
> > Please correct me in case I am missing something.
> 
> To add new API into crypto-dev would also require changes in the PMD,
> it wouldn't come totally free and I believe would require roughly the same
> amount of changes.

It will be required only in the PMDs which support it and would be minimal.
You would need a feature flag, support  for that synchronous API. Session information will
already be there in the session. The changes wrt cipher_offset need to be added
but with some default value to identify override will be done or not.

> 
> >
> >
> > > While rte_security is designed in a way that we can add new session types
> and
> > > related parameters without causing API/ABI breakage.
> >
> > Yes the intent is to add new sessions based on various protocols that can be
> supported by the driver.
> 
> Various protocols and different types of sessions (and devices they belong to).
> Let say right now we have INLINE_CRYPTO, INLINE_PROTO, LOOKASIDE_PROTO,
> etc.
> Here we introduce new type of session.

What is the new value add to the existing sessions. The changes that we are doing
here is just to avoid an API/ABI breakage. The synchronous processing can happen on both
crypto and security session. This would mean, only the processing API should be defined,
rest all should be already there in the sessions.
In All other cases, INLINE - eth device was not having any format to perform crypto op
LOOKASIDE - PROTO - add protocol specific sessions which is not available in crypto.

> 
> > It is not that we should find it as an alternative to cryptodev and using it just
> because it will not cause
> > ABI/API breakage.
> 
> I am considering this new API as an alternative to existing ones, but as an
> extension.
> Existing crypto-op API has its own advantages (generic), and I think we should
> keep it supported by all crypto-devs.
> From other side rte_security is an extendable framework that suits the purpose:
> allows easily (and yes without ABI breakage) introduce new API for special type
> of crypto-dev (SW based).
> 
> 

Adding a synchronous processing API is understandable and can be added in both
Crypto as well as Security, but a new action type for it is not required.
Now whether to support that, we have ABI/API breakage, that is a different issue.
And we may have to deal with it if no other option is there.

> 
> 
> 
> > IMO the code should be placed where its intent is.
> >
> > >
> > > BTW, what is your concern with proposed approach (via rte_security)?
> > > From my perspective it is a lightweight change and it is totally optional
> > > for the crypto PMDs to support it or not.
> > > Konstantin
> > >
> > > > >
> > > > > AESNI-GCM and AESNI-MB PMDs are updated with this support. There is
> a
> > > small
> > > > > performance test app under app/test/security_aesni_gcm(mb)_perftest
> to
> > > > > prove.
> > > > >
> > > > > For the new API
> > > > > The packet is sent to the crypto device for symmetric crypto
> > > > > processing. The device will encrypt or decrypt the buffer based on the
> > > session
> > > > > data specified and preprocessed in the security session. Different
> > > > > than the inline or lookaside modes, when the function exits, the user will
> > > > > expect the buffers are either processed successfully, or having the error
> > > number
> > > > > assigned to the appropriate index of the status array.
> > > > >
> > > > > Will update the program's guide in the v1 patch.
> > > > >
> > > > > Regards,
> > > > > Fan
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > > > > > Sent: Wednesday, September 4, 2019 11:33 AM
> > > > > > To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> > > > > > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Doherty,
> > > Declan
> > > > > > <declan.doherty@intel.com>; De Lara Guarch, Pablo
> > > > > > <pablo.de.lara.guarch@intel.com>
> > > > > > Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action
> type
> > > and
> > > > > > API
> > > > > >
> > > > > > Hi Fan,
> > > > > >
> > > > > > >
> > > > > > > This patch introduce new
> RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > > > > action
> > > > > > > type to security library. The type represents performing crypto
> > > > > > > operation with CPU cycles. The patch also includes a new API to
> > > > > > > process crypto operations in bulk and the function pointers for PMDs.
> > > > > > >
> > > > > > I am not able to get the flow of execution for this action type. Could
> you
> > > > > > please elaborate the flow in the documentation. If not in
> documentation
> > > > > > right now, then please elaborate the flow in cover letter.
> > > > > > Also I see that there are new APIs for processing crypto operations in
> bulk.
> > > > > > What does that mean. How are they different from the existing APIs
> which
> > > > > > are also handling bulk crypto ops depending on the budget.
> > > > > >
> > > > > >
> > > > > > -Akhil


^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH v5 00/12] lib: add RIB and FIB liraries
  2019-09-12  7:37  0%   ` Morten Brørup
@ 2019-09-12  9:47  0%     ` Medvedkin, Vladimir
  0 siblings, 0 replies; 200+ results
From: Medvedkin, Vladimir @ 2019-09-12  9:47 UTC (permalink / raw)
  To: Morten Brørup; +Cc: bruce.richardson, dev

Hi Brørup,

On 12/09/2019 08:37, Morten Brørup wrote:
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Vladimir Medvedkin
>>
>> This is heavily reworked version of previous RIB library series:
>> https://mails.dpdk.org/archives/dev/2018-April/099492.html
>>
>> Current lpm implementation while provides really good lookup
>> performance has number of problems.
>> One of them is very low speed for control plane operations
>> such as add or delete a route.
>> Another disadvantage is fixed number of bits for userdata
>> (24 for v4 and 21 for v6)
>> Also it is hard to introduce changes in existing LPM code or add new
>> algorithms without breaking ABI.
>>
>> This patch series tries to solve this problems by:
>> Introduce two new libraries - RIB and FIB.
>> RIB that is Routing Information Base.
>> It implements a control plane struct containing routes in a tree and
>> provides fast add/del operations for routes. Also it allows to perform
>> fast subtree traversals (i.e. retrieve existing subroutes for a given
>> prefix). This structure will be used as a control plane helper
>> structure
>> for FIB implementation.
>> Also it might be used standalone in other different places such as
>> bitmaps for example.
>>
> Great!
>
>
>> Second library is FIB that is Forwarding Information Base. It
>> represents
>> dataplane related struct and algorithms for longest prefix match.
>> Internally it consists of two parts - RIB (control plane ops) and
>> implementation for the dataplane tasks.
>> Initial version provides two implementations for both ipv4 and ipv6:
>> dummy (uses RIB as a dataplane) and DIR24_8 (same as current LPM)
>> Due to proposed design it allows to extend FIB with new algorithms in
>> future
>> (for example DXR, poptrie, etc).
> The feedback following here is meant as a comment, not an objection. Feel free to ignore!
>
> This FIB library is designed for IP based forwarding only.
>
> How about forwarding based on other criteria?
> E.g. the FIB in a standard Ethernet switch is based on VLAN+MAC.
>
> Such a FIB would probably require a different library, based on a hash structure, and would also require a compare-and-set function callable from the data plane in order to provide wire speed learning.
>
> So I suggest that the documentation highlights that this FIB library is for IP based forwarding. Optionally also reconsider the name of the library and its functions, structures etc..

Thanks for the feedback.

Yes, at the moment FIB has only longest prefix match algorithms. 
However, it is possible to add different exact match algorithms for 
VLAN+MAC/MPLS/etc processing.

It is always hard to find proper name for library/function/variable, so 
if you think that fib name is not relevant feel free to suggest better :)

>
>>  From our measurements we saw 10x speedup for control plane operations
>> comparing with current LPM library (depending on prefix length
>> distribution)
>>
>> ToDo:
>>   - introduce new performance measurement app.
>>   - add documentation.
>>   - add support into existing examples (l3fwd)
>>
>
> Med venlig hilsen / kind regards
> - Morten Brørup

-- 
Regards,
Vladimir


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v5 00/12] lib: add RIB and FIB liraries
  2019-09-11 17:09  2% ` [dpdk-dev] [PATCH v5 00/12] lib: add RIB and FIB liraries Vladimir Medvedkin
@ 2019-09-12  7:37  0%   ` Morten Brørup
  2019-09-12  9:47  0%     ` Medvedkin, Vladimir
  0 siblings, 1 reply; 200+ results
From: Morten Brørup @ 2019-09-12  7:37 UTC (permalink / raw)
  To: Vladimir Medvedkin; +Cc: bruce.richardson, dev

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Vladimir Medvedkin
> 
> This is heavily reworked version of previous RIB library series:
> https://mails.dpdk.org/archives/dev/2018-April/099492.html
> 
> Current lpm implementation while provides really good lookup
> performance has number of problems.
> One of them is very low speed for control plane operations
> such as add or delete a route.
> Another disadvantage is fixed number of bits for userdata
> (24 for v4 and 21 for v6)
> Also it is hard to introduce changes in existing LPM code or add new
> algorithms without breaking ABI.
> 
> This patch series tries to solve this problems by:
> Introduce two new libraries - RIB and FIB.
> RIB that is Routing Information Base.
> It implements a control plane struct containing routes in a tree and
> provides fast add/del operations for routes. Also it allows to perform
> fast subtree traversals (i.e. retrieve existing subroutes for a given
> prefix). This structure will be used as a control plane helper
> structure
> for FIB implementation.
> Also it might be used standalone in other different places such as
> bitmaps for example.
> 

Great!


> Second library is FIB that is Forwarding Information Base. It
> represents
> dataplane related struct and algorithms for longest prefix match.
> Internally it consists of two parts - RIB (control plane ops) and
> implementation for the dataplane tasks.
> Initial version provides two implementations for both ipv4 and ipv6:
> dummy (uses RIB as a dataplane) and DIR24_8 (same as current LPM)
> Due to proposed design it allows to extend FIB with new algorithms in
> future
> (for example DXR, poptrie, etc).

The feedback following here is meant as a comment, not an objection. Feel free to ignore!

This FIB library is designed for IP based forwarding only.

How about forwarding based on other criteria?
E.g. the FIB in a standard Ethernet switch is based on VLAN+MAC.

Such a FIB would probably require a different library, based on a hash structure, and would also require a compare-and-set function callable from the data plane in order to provide wire speed learning.

So I suggest that the documentation highlights that this FIB library is for IP based forwarding. Optionally also reconsider the name of the library and its functions, structures etc..

> 
> From our measurements we saw 10x speedup for control plane operations
> comparing with current LPM library (depending on prefix length
> distribution)
> 
> ToDo:
>  - introduce new performance measurement app.
>  - add documentation.
>  - add support into existing examples (l3fwd)
> 


Med venlig hilsen / kind regards
- Morten Brørup

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v5 00/12] lib: add RIB and FIB liraries
  @ 2019-09-11 17:09  2% ` Vladimir Medvedkin
  2019-09-12  7:37  0%   ` Morten Brørup
  0 siblings, 1 reply; 200+ results
From: Vladimir Medvedkin @ 2019-09-11 17:09 UTC (permalink / raw)
  To: dev; +Cc: bruce.richardson

This is heavily reworked version of previous RIB library series:
https://mails.dpdk.org/archives/dev/2018-April/099492.html

Current lpm implementation while provides really good lookup
performance has number of problems.
One of them is very low speed for control plane operations
such as add or delete a route.
Another disadvantage is fixed number of bits for userdata
(24 for v4 and 21 for v6)
Also it is hard to introduce changes in existing LPM code or add new
algorithms without breaking ABI.

This patch series tries to solve this problems by:
Introduce two new libraries - RIB and FIB.
RIB that is Routing Information Base.
It implements a control plane struct containing routes in a tree and
provides fast add/del operations for routes. Also it allows to perform
fast subtree traversals (i.e. retrieve existing subroutes for a given
prefix). This structure will be used as a control plane helper structure
for FIB implementation.
Also it might be used standalone in other different places such as
bitmaps for example.

Second library is FIB that is Forwarding Information Base. It represents
dataplane related struct and algorithms for longest prefix match.
Internally it consists of two parts - RIB (control plane ops) and
implementation for the dataplane tasks.
Initial version provides two implementations for both ipv4 and ipv6:
dummy (uses RIB as a dataplane) and DIR24_8 (same as current LPM)
Due to proposed design it allows to extend FIB with new algorithms in future
(for example DXR, poptrie, etc).

From our measurements we saw 10x speedup for control plane operations
comparing with current LPM library (depending on prefix length distribution)

ToDo:
 - introduce new performance measurement app.
 - add documentation.
 - add support into existing examples (l3fwd)


Vladimir Medvedkin (12):
  rib: add RIB library
  test/rib: add RIB library autotests
  rib: add ipv6 support for RIB
  test/rib: add ipv6 support for RIB autotests
  fib: add FIB library
  fib: add FIB ipv6 support
  fib: add DIR24-8 dataplane algorithm
  fib: add dataplane algorithm for ipv6
  test/fib: add FIB library autotests
  test/fib: add ipv6 support for FIB autotests
  test/fib: add FIB library performance autotests
  test/fib: add FIB library ipv6 performance autotests

 app/test/Makefile                  |   7 +
 app/test/autotest_data.py          |  36 ++
 app/test/meson.build               |  14 +
 app/test/test_fib.c                | 397 +++++++++++++++++++
 app/test/test_fib6.c               | 405 ++++++++++++++++++++
 app/test/test_fib6_perf.c          | 157 ++++++++
 app/test/test_fib_perf.c           | 411 ++++++++++++++++++++
 app/test/test_rib.c                | 351 +++++++++++++++++
 app/test/test_rib6.c               | 357 +++++++++++++++++
 config/common_base                 |  11 +
 doc/api/doxy-api.conf.in           |   2 +
 lib/Makefile                       |   4 +
 lib/librte_fib/Makefile            |  25 ++
 lib/librte_fib/dir24_8.c           | 737 +++++++++++++++++++++++++++++++++++
 lib/librte_fib/dir24_8.h           |  36 ++
 lib/librte_fib/meson.build         |   8 +
 lib/librte_fib/rte_fib.c           | 319 ++++++++++++++++
 lib/librte_fib/rte_fib.h           | 188 +++++++++
 lib/librte_fib/rte_fib6.c          | 322 ++++++++++++++++
 lib/librte_fib/rte_fib6.h          | 193 ++++++++++
 lib/librte_fib/rte_fib_version.map |  23 ++
 lib/librte_fib/trie.c              | 760 +++++++++++++++++++++++++++++++++++++
 lib/librte_fib/trie.h              |  37 ++
 lib/librte_rib/Makefile            |  25 ++
 lib/librte_rib/meson.build         |   8 +
 lib/librte_rib/rte_rib.c           | 532 ++++++++++++++++++++++++++
 lib/librte_rib/rte_rib.h           | 277 ++++++++++++++
 lib/librte_rib/rte_rib6.c          | 598 +++++++++++++++++++++++++++++
 lib/librte_rib/rte_rib6.h          | 334 ++++++++++++++++
 lib/librte_rib/rte_rib_version.map |  35 ++
 lib/meson.build                    |   4 +-
 mk/rte.app.mk                      |   2 +
 32 files changed, 6614 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_fib.c
 create mode 100644 app/test/test_fib6.c
 create mode 100644 app/test/test_fib6_perf.c
 create mode 100644 app/test/test_fib_perf.c
 create mode 100644 app/test/test_rib.c
 create mode 100644 app/test/test_rib6.c
 create mode 100644 lib/librte_fib/Makefile
 create mode 100644 lib/librte_fib/dir24_8.c
 create mode 100644 lib/librte_fib/dir24_8.h
 create mode 100644 lib/librte_fib/meson.build
 create mode 100644 lib/librte_fib/rte_fib.c
 create mode 100644 lib/librte_fib/rte_fib.h
 create mode 100644 lib/librte_fib/rte_fib6.c
 create mode 100644 lib/librte_fib/rte_fib6.h
 create mode 100644 lib/librte_fib/rte_fib_version.map
 create mode 100644 lib/librte_fib/trie.c
 create mode 100644 lib/librte_fib/trie.h
 create mode 100644 lib/librte_rib/Makefile
 create mode 100644 lib/librte_rib/meson.build
 create mode 100644 lib/librte_rib/rte_rib.c
 create mode 100644 lib/librte_rib/rte_rib.h
 create mode 100644 lib/librte_rib/rte_rib6.c
 create mode 100644 lib/librte_rib/rte_rib6.h
 create mode 100644 lib/librte_rib/rte_rib_version.map

-- 
2.7.4


^ permalink raw reply	[relevance 2%]

* [dpdk-dev] DPDK techboard minutes (2019-07-17)
@ 2019-09-11 15:05  3% Olivier Matz
  0 siblings, 0 replies; 200+ results
From: Olivier Matz @ 2019-09-11 15:05 UTC (permalink / raw)
  To: dev

Hi,

Here are the meeting notes for the DPDK technical board meeting held on
2019-07-17.

Attendees:

- Bruce Richardson
- Ferruh Yigit
- Hemant Agrawal
- Jerin Jacob
- Olivier Matz
- Thomas Monjalon

1) New next-net tree co-maintainer
==================================

Andrew Rybchenko <arybchenko@solarflare.com> is accepted as new
co-maintainer for next-net sub-tree.

2) DPDK API/ABI Stability
=========================

Good progresses and discussions.

Some points should be clarified before the userspace summit:

- Splitting DPDK into core, non-core and experimental libraries
- OS Packaging of DPDK
- UNH Testing of DPDK

3) Some examples are suggested to be removed in 19.11
=====================================================

Bruce to kick off the discussion on the ML.
(done: https://mails.dpdk.org/archives/dev/2019-July/138676.html )

4) Security process update
==========================

Request has been done to Trishan at last governing board that LF becomes
a CNA (CVE Numbering Authority).

Stephen (techboard representative at govboard) to pass the request via
email.

5) Proposal for regexdev subsystem
===================================

RFC proposal from Jerin Jacob <jerinj@marvell.com>:
https://patchwork.dpdk.org/patch/55505/

Several vendors seems interested by this feature. Concerned people
are encouraged to reply to this thread.

6) SPDX licenses
================

Hemant + Bruce to check if we can achieve SPDX compliance for 19.11.

7) Next meeting
===============

On 2019-07-31, Maxime will chair it.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] DPDK techboard minutes of July 31
@ 2019-09-11 15:04  5% Maxime Coquelin
  0 siblings, 0 replies; 200+ results
From: Maxime Coquelin @ 2019-09-11 15:04 UTC (permalink / raw)
  To: DPDK Techboard, dev

Meeting notes for the DPDK technical board meeting held on 2018-07-31

Attendees:
    - Bruce Richardson
    - Ferruh Yigit
    - Hemant Agrawal
    - Jerin Jacob
    - Maxime Coquelin
    - Stephen Hemminger
    - Thomas Monjalon

1) Security process updates
 - The governing board acknowledges the security process
 - Last governing board meeting didn't covered the technical board
   request for LF to become a CNA
 - Stephen to do the request at the next governing board meeting

2) SPDX licences
 - Still some subsystems not compliant with SPDK, target is still v19.11
 - Hemant sent a reminder on DPDK dev mailing-list
 - Hemant will give a status update at next meeting

3) DPDK community survey follow-up
 - 39% of the respondents said they do not get enough reviews
  * Situation has improved since we have more sub-trees
  * Could further be improved if maintainers asked trusted contributors
    to help reviewing patches
  * In case the contributor feels the review process does not work, he
    should e-mail the techboard
  * Thomas and Honnappa to update the contribution documentation and
    send a pointer to that doc on the dev mailing-list

4) DPDK API/ABI Stability discussions
 - Ray prepared a v2 of the policy patch, main changes:
  * Change to 1 year initial ABI stability period, with a review
    afterward to elongate the stability period
  * Changes to the handling of experimental and depreciation process

 - Open question is from where to start the major ABI version numbering.
  * Should it be the year of the declaration of stable ABI version?
  * Or start at v3.0 and continue from there?
  * Bruce mentioned that we already have libraries at version > 10, so
    using 3 would not work
  * Techboard voted to use the year of stabilization as starting point.

5) Next meeting
 - On 2019-08-14, Stephen will chair it.

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
  2019-09-10 10:44  4%           ` Akhil Goyal
@ 2019-09-11 12:29  4%             ` Ananyev, Konstantin
  2019-09-12 14:12  5%               ` Akhil Goyal
  0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-09-11 12:29 UTC (permalink / raw)
  To: Akhil Goyal, dev; +Cc: Zhang, Roy Fan, Doherty, Declan, De Lara Guarch, Pablo



Hi Akhil,
> >
> > > > This action type allows the burst of symmetric crypto workload using the
> > same
> > > > algorithm, key, and direction being processed by CPU cycles synchronously.
> > > > This flexible action type does not require external hardware involvement,
> > > > having the crypto workload processed synchronously, and is more
> > performant
> > > > than Cryptodev SW PMD due to the saved cycles on removed "async mode
> > > > simulation" as well as 3 cacheline access of the crypto ops.
> > >
> > > Does that mean application will not call the cryptodev_enqueue_burst and
> > corresponding dequeue burst.
> >
> > Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> >
> > > It would be a new API something like process_packets and it will have the
> > crypto processed packets while returning from the API?
> >
> > Yes, though the plan is that API will operate on raw data buffers, not mbufs.
> >
> > >
> > > I still do not understand why we cannot do with the conventional crypto lib
> > only.
> > > As far as I can understand, you are not doing any protocol processing or any
> > value add
> > > To the crypto processing. IMO, you just need a synchronous crypto processing
> > API which
> > > Can be defined in cryptodev, you don't need to re-create a crypto session in
> > the name of
> > > Security session in the driver just to do a synchronous processing.
> >
> > I suppose your question is why not to have
> > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > The main reason is that would require disruptive changes in existing cryptodev
> > API
> > (would cause ABI/API breakage).
> > Session for  RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need some extra
> > information
> > that normal crypto_sym_xform doesn't contain
> > (cipher offset from the start of the buffer, might be something extra in future).
> 
> Cipher offset will be part of rte_crypto_op.

fill/read (+ alloc/free) is one of the main things that slowdown current crypto-op approach.
That's why the general idea - have all data that wouldn't change from packet to packet
included into the session and setup it once at session_init().

> If you intend not to use rte_crypto_op
> You can pass this as an argument in the new cryptodev API.

You mean extra parameter in rte_security_process_cpu_crypto_bulk()?
It can be in theory, but that solution looks a bit ugly:
	why to pass for each call something that would be constant per session?
	Again having that value constant per session might allow some extra optimisations
	That would be hard to achieve for dynamic case. 
and not extendable:
Suppose tomorrow will need to add something extra (some new algorithm support or so).
With what you proposing will need to new parameter to the function,
which means API breakage. 

> Something extra will also cause ABI breakage in security as well.
> So it will be same.

I don't think it would.
AFAIK, right now this patch doesn't introduce any API/ABI breakage.
Iinside struct rte_security_session_conf we have a union of xforms
depending on session type.
So as long as cpu_crypto_xform wouldn't exceed sizes of other xform -
I believe no ABI breakage will appear.


> 
> > Also right now there is no way to add new type of crypto_sym_session without
> > either breaking existing crypto-dev ABI/API or introducing new structure
> > (rte_crypto_sym_cpu_session or so) for that.
> 
> What extra info is required in rte_cryptodev_sym_session to get the rte_crypto_sym_cpu_session.

Right now - just cipher_offset (see above).
What else in future (if any) - don't know.

> I don't think there is any.
> I believe the same crypto session will be able to work synchronously as well.

Exactly the same - problematically, see above.

> We would only need  a new API to perform synchronous actions.
> That will reduce the duplication code significantly
> in the driver to support 2 different kind of APIs with similar code inside.
> Please correct me in case I am missing something.

To add new API into crypto-dev would also require changes in the PMD,
it wouldn't come totally free and I believe would require roughly the same amount of changes. 

> 
> 
> > While rte_security is designed in a way that we can add new session types and
> > related parameters without causing API/ABI breakage.
> 
> Yes the intent is to add new sessions based on various protocols that can be supported by the driver.

Various protocols and different types of sessions (and devices they belong to).
Let say right now we have INLINE_CRYPTO, INLINE_PROTO, LOOKASIDE_PROTO, etc.
Here we introduce new type of session.

> It is not that we should find it as an alternative to cryptodev and using it just because it will not cause
> ABI/API breakage.

I am considering this new API as an alternative to existing ones, but as an extension.
Existing crypto-op API has its own advantages (generic), and I think we should keep it supported by all crypto-devs. 
From other side rte_security is an extendable framework that suits the purpose:
allows easily (and yes without ABI breakage) introduce new API for special type of crypto-dev (SW based).


 


> IMO the code should be placed where its intent is.
> 
> >
> > BTW, what is your concern with proposed approach (via rte_security)?
> > From my perspective it is a lightweight change and it is totally optional
> > for the crypto PMDs to support it or not.
> > Konstantin
> >
> > > >
> > > > AESNI-GCM and AESNI-MB PMDs are updated with this support. There is a
> > small
> > > > performance test app under app/test/security_aesni_gcm(mb)_perftest to
> > > > prove.
> > > >
> > > > For the new API
> > > > The packet is sent to the crypto device for symmetric crypto
> > > > processing. The device will encrypt or decrypt the buffer based on the
> > session
> > > > data specified and preprocessed in the security session. Different
> > > > than the inline or lookaside modes, when the function exits, the user will
> > > > expect the buffers are either processed successfully, or having the error
> > number
> > > > assigned to the appropriate index of the status array.
> > > >
> > > > Will update the program's guide in the v1 patch.
> > > >
> > > > Regards,
> > > > Fan
> > > >
> > > > > -----Original Message-----
> > > > > From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > > > > Sent: Wednesday, September 4, 2019 11:33 AM
> > > > > To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> > > > > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Doherty,
> > Declan
> > > > > <declan.doherty@intel.com>; De Lara Guarch, Pablo
> > > > > <pablo.de.lara.guarch@intel.com>
> > > > > Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action type
> > and
> > > > > API
> > > > >
> > > > > Hi Fan,
> > > > >
> > > > > >
> > > > > > This patch introduce new RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > > > action
> > > > > > type to security library. The type represents performing crypto
> > > > > > operation with CPU cycles. The patch also includes a new API to
> > > > > > process crypto operations in bulk and the function pointers for PMDs.
> > > > > >
> > > > > I am not able to get the flow of execution for this action type. Could you
> > > > > please elaborate the flow in the documentation. If not in documentation
> > > > > right now, then please elaborate the flow in cover letter.
> > > > > Also I see that there are new APIs for processing crypto operations in bulk.
> > > > > What does that mean. How are they different from the existing APIs which
> > > > > are also handling bulk crypto ops depending on the budget.
> > > > >
> > > > >
> > > > > -Akhil


^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] mbuf: add bulk free function
  @ 2019-09-11 11:39  3%     ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-09-11 11:39 UTC (permalink / raw)
  To: Olivier Matz; +Cc: Morten Brørup, dev

On Wed, 11 Sep 2019 13:33:13 +0200
Olivier Matz <olivier.matz@6wind.com> wrote:

> Hi,
> 
> On Wed, Sep 11, 2019 at 12:18:34PM +0100, Stephen Hemminger wrote:
> > On Wed, 11 Sep 2019 09:19:08 +0000
> > Morten Brørup <mb@smartsharesystems.com> wrote:
> >   
> > > Add function for freeing a bulk of mbufs.
> > > 
> > > Signed-off-by: Morten Brørup <mb@smartsharesystems.com>
> > > ---
> > >  lib/librte_mbuf/rte_mbuf.h | 17 +++++++++++++++++
> > >  1 file changed, 17 insertions(+)
> > > 
> > > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> > > index 98225ec80..f2e174da1 100644
> > > --- a/lib/librte_mbuf/rte_mbuf.h
> > > +++ b/lib/librte_mbuf/rte_mbuf.h
> > > @@ -1907,6 +1907,23 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m)
> > >  	}
> > >  }
> > >  
> > > +/**
> > > + * Free a bulk of mbufs back into their original mempool.
> > > + *
> > > + *  @param mbufs
> > > + *    Array of pointers to mbufs
> > > + *  @param count
> > > + *    Array size
> > > + */
> > > +static inline void
> > > +rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned count)
> > > +{
> > > +	unsigned idx = 0;
> > > +
> > > +	for (idx = 0; idx < count; idx++)
> > > +		rte_pktmbuf_free(mbufs[idx]);
> > > +}
> > > +  
> > 
> > You can optimize this to use mempool bulk put operation.  
> 
> A bulk free for mbuf is not as simple as a bulk mempool put, because
> of indirect mbufs, and because mbufs may return in different mempools.
> 
> Morten, do you have more details about why do you need such a function?
> 
> Thanks,
> Olivier

I was thinking of a function that looked at the list and if they were all
the same pool and safe to bulk put, then use that as a fast path. This would
be the most common case.

Also, less inline functions please. When it is an inline it adds more API/ABI
dependencies.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [RFC v3 0/4] get Rx/Tx packet burst mode information
@ 2019-09-10 16:33  3% Haiyue Wang
  0 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2019-09-10 16:33 UTC (permalink / raw)
  To: dev, ferruh.yigit, mdr, chenmin.sun; +Cc: Haiyue Wang

v1 -> v2: 
Avoid ABI breaking, add a simple trace API to export string type
information.

v2 -> v3:
Use bit fields to present the burst mode setting, and rename the
APIs.

Haiyue Wang (4):
  ethdev: add the API for getting burst mode information
  net/i40e: support to get the Rx/Tx burst mode
  net/ice: support to get the Rx/Tx burst mode
  app/testpmd: show the Rx/Tx burst mode description

 app/test-pmd/config.c                    | 25 ++++++++
 doc/guides/rel_notes/release_19_11.rst   |  8 +++
 drivers/net/i40e/i40e_ethdev.c           |  2 +
 drivers/net/i40e/i40e_ethdev.h           |  4 ++
 drivers/net/i40e/i40e_rxtx.c             | 72 +++++++++++++++++++++
 drivers/net/ice/ice_ethdev.c             |  2 +
 drivers/net/ice/ice_rxtx.c               | 54 ++++++++++++++++
 drivers/net/ice/ice_rxtx.h               |  4 ++
 lib/librte_ethdev/rte_ethdev.c           | 75 ++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h           | 82 ++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev_core.h      |  5 ++
 lib/librte_ethdev/rte_ethdev_version.map |  5 ++
 12 files changed, 338 insertions(+)

-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
  2019-09-06 13:27  4%         ` Ananyev, Konstantin
@ 2019-09-10 10:44  4%           ` Akhil Goyal
  2019-09-11 12:29  4%             ` Ananyev, Konstantin
  0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2019-09-10 10:44 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev
  Cc: Zhang, Roy Fan, Doherty, Declan, De Lara Guarch, Pablo


Hi Konstantin,
> 
> Hi Akhil,
> 
> > > This action type allows the burst of symmetric crypto workload using the
> same
> > > algorithm, key, and direction being processed by CPU cycles synchronously.
> > > This flexible action type does not require external hardware involvement,
> > > having the crypto workload processed synchronously, and is more
> performant
> > > than Cryptodev SW PMD due to the saved cycles on removed "async mode
> > > simulation" as well as 3 cacheline access of the crypto ops.
> >
> > Does that mean application will not call the cryptodev_enqueue_burst and
> corresponding dequeue burst.
> 
> Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> 
> > It would be a new API something like process_packets and it will have the
> crypto processed packets while returning from the API?
> 
> Yes, though the plan is that API will operate on raw data buffers, not mbufs.
> 
> >
> > I still do not understand why we cannot do with the conventional crypto lib
> only.
> > As far as I can understand, you are not doing any protocol processing or any
> value add
> > To the crypto processing. IMO, you just need a synchronous crypto processing
> API which
> > Can be defined in cryptodev, you don't need to re-create a crypto session in
> the name of
> > Security session in the driver just to do a synchronous processing.
> 
> I suppose your question is why not to have
> rte_crypot_process_cpu_crypto_bulk(...) instead?
> The main reason is that would require disruptive changes in existing cryptodev
> API
> (would cause ABI/API breakage).
> Session for  RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need some extra
> information
> that normal crypto_sym_xform doesn't contain
> (cipher offset from the start of the buffer, might be something extra in future).

Cipher offset will be part of rte_crypto_op. If you intend not to use rte_crypto_op
You can pass this as an argument in the new cryptodev API.
Something extra will also cause ABI breakage in security as well.
So it will be same.

> Also right now there is no way to add new type of crypto_sym_session without
> either breaking existing crypto-dev ABI/API or introducing new structure
> (rte_crypto_sym_cpu_session or so) for that.

What extra info is required in rte_cryptodev_sym_session to get the rte_crypto_sym_cpu_session.
I don't think there is any.
I believe the same crypto session will be able to work synchronously as well. We would only need
a new API to perform synchronous actions. That will reduce the duplication code significantly
in the driver to support 2 different kind of APIs with similar code inside. 
Please correct me in case I am missing something.


> While rte_security is designed in a way that we can add new session types and
> related parameters without causing API/ABI breakage.

Yes the intent is to add new sessions based on various protocols that can be supported by the driver.
It is not that we should find it as an alternative to cryptodev and using it just because it will not cause
ABI/API breakage. IMO the code should be placed where its intent is.

> 
> BTW, what is your concern with proposed approach (via rte_security)?
> From my perspective it is a lightweight change and it is totally optional
> for the crypto PMDs to support it or not.
> Konstantin
> 
> > >
> > > AESNI-GCM and AESNI-MB PMDs are updated with this support. There is a
> small
> > > performance test app under app/test/security_aesni_gcm(mb)_perftest to
> > > prove.
> > >
> > > For the new API
> > > The packet is sent to the crypto device for symmetric crypto
> > > processing. The device will encrypt or decrypt the buffer based on the
> session
> > > data specified and preprocessed in the security session. Different
> > > than the inline or lookaside modes, when the function exits, the user will
> > > expect the buffers are either processed successfully, or having the error
> number
> > > assigned to the appropriate index of the status array.
> > >
> > > Will update the program's guide in the v1 patch.
> > >
> > > Regards,
> > > Fan
> > >
> > > > -----Original Message-----
> > > > From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > > > Sent: Wednesday, September 4, 2019 11:33 AM
> > > > To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> > > > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Doherty,
> Declan
> > > > <declan.doherty@intel.com>; De Lara Guarch, Pablo
> > > > <pablo.de.lara.guarch@intel.com>
> > > > Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action type
> and
> > > > API
> > > >
> > > > Hi Fan,
> > > >
> > > > >
> > > > > This patch introduce new RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > > action
> > > > > type to security library. The type represents performing crypto
> > > > > operation with CPU cycles. The patch also includes a new API to
> > > > > process crypto operations in bulk and the function pointers for PMDs.
> > > > >
> > > > I am not able to get the flow of execution for this action type. Could you
> > > > please elaborate the flow in the documentation. If not in documentation
> > > > right now, then please elaborate the flow in cover letter.
> > > > Also I see that there are new APIs for processing crypto operations in bulk.
> > > > What does that mean. How are they different from the existing APIs which
> > > > are also handling bulk crypto ops depending on the budget.
> > > >
> > > >
> > > > -Akhil


^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH 1/1] ethdev: change owner delete function return value to int
  @ 2019-09-10  9:02  4% ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-10  9:02 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Stephen Hemminger,
	K. Y. Srinivasan, Haiyang Zhang, Thomas Monjalon, Ferruh Yigit
  Cc: dev, Igor Romanov

From: Igor Romanov <igor.romanov@oktetlabs.ru>

Change rte_eth_dev_owner_delete() return value from void to int
and return negative errno values in case of error conditions.

Right now there is only one error case for rte_eth_dev_owner_delete() -
invalid owner, but it still makes sense to return error to catch bugs
in the code which uses the function.

Also update the usage of the function in drivers/netvsc
according to the new return type.

Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst   | 1 -
 doc/guides/rel_notes/release_19_11.rst | 3 +++
 drivers/net/netvsc/hn_ethdev.c         | 5 ++++-
 lib/librte_ethdev/rte_ethdev.c         | 6 +++++-
 lib/librte_ethdev/rte_ethdev.h         | 4 +++-
 5 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 61ba2e0bc..237813b64 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -90,7 +90,6 @@ Deprecation Notices
 
   - ``rte_eth_dev_stop``
   - ``rte_eth_dev_close``
-  - ``rte_eth_dev_owner_delete``
 
 * ethdev: New offload flags ``DEV_RX_OFFLOAD_RSS_HASH`` and
   ``DEV_RX_OFFLOAD_FLOW_MARK`` will be added in 19.11.
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 033ed54f4..54950277b 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -115,6 +115,9 @@ API Changes
 * ethdev: changed ``rte_eth_macaddr_get`` return value from ``void`` to
   ``int`` to provide a way to report various error conditions.
 
+* ethdev: changed ``rte_eth_dev_owner_delete`` return value from ``void`` to
+  ``int`` to provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index ca96e80a4..eed8dece9 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -1004,6 +1004,7 @@ static int
 eth_hn_dev_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct hn_data *hv = eth_dev->data->dev_private;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1021,7 +1022,9 @@ eth_hn_dev_uninit(struct rte_eth_dev *eth_dev)
 	hn_tx_pool_uninit(eth_dev);
 	rte_vmbus_chan_close(hv->primary->chan);
 	rte_free(hv->primary);
-	rte_eth_dev_owner_delete(hv->owner.id);
+	ret = rte_eth_dev_owner_delete(hv->owner.id);
+	if (ret != 0)
+		return ret;
 
 	return 0;
 }
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 29ecb9274..e50bac847 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -687,10 +687,11 @@ rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id)
 	return ret;
 }
 
-void
+int
 rte_eth_dev_owner_delete(const uint64_t owner_id)
 {
 	uint16_t port_id;
+	int ret = 0;
 
 	rte_eth_dev_shared_data_prepare();
 
@@ -708,9 +709,12 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 		RTE_ETHDEV_LOG(ERR,
 			       "Invalid owner id=%016"PRIx64"\n",
 			       owner_id);
+		ret = -EINVAL;
 	}
 
 	rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
+
+	return ret;
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 9c213e072..d937fb429 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -1566,9 +1566,11 @@ int rte_eth_dev_owner_unset(const uint16_t port_id,
  *
  * @param	owner_id
  *  The owner identifier.
+ * @return
+ *  0 on success, negative errno value on error.
  */
 __rte_experimental
-void rte_eth_dev_owner_delete(const uint64_t owner_id);
+int rte_eth_dev_owner_delete(const uint64_t owner_id);
 
 /**
  * @warning
-- 
2.17.1


^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH 1/7] ethdev: change MAC addr get function return value to int
  @ 2019-09-10  8:52  4% ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-10  8:52 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Bernard Iremonger,
	Thomas Monjalon, Ferruh Yigit
  Cc: dev, Igor Romanov

From: Igor Romanov <igor.romanov@oktetlabs.ru>

Change rte_eth_macaddr_get() return value from void to int
and return negative errno values in case of error conditions.

Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst       | 1 -
 doc/guides/rel_notes/release_19_11.rst     | 3 +++
 doc/guides/sample_app_ug/flow_classify.rst | 4 +++-
 lib/librte_ethdev/rte_ethdev.c             | 6 ++++--
 lib/librte_ethdev/rte_ethdev.h             | 5 ++++-
 5 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 43b15ec2f..61ba2e0bc 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -90,7 +90,6 @@ Deprecation Notices
 
   - ``rte_eth_dev_stop``
   - ``rte_eth_dev_close``
-  - ``rte_eth_macaddr_get``
   - ``rte_eth_dev_owner_delete``
 
 * ethdev: New offload flags ``DEV_RX_OFFLOAD_RSS_HASH`` and
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 3ff1296a2..033ed54f4 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -112,6 +112,9 @@ API Changes
   return value from ``void`` to ``int`` to provide a way to report various
   error conditions.
 
+* ethdev: changed ``rte_eth_macaddr_get`` return value from ``void`` to
+  ``int`` to provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
diff --git a/doc/guides/sample_app_ug/flow_classify.rst b/doc/guides/sample_app_ug/flow_classify.rst
index 7c2b6dcf8..bc234b50a 100644
--- a/doc/guides/sample_app_ug/flow_classify.rst
+++ b/doc/guides/sample_app_ug/flow_classify.rst
@@ -306,7 +306,9 @@ Forwarding application is shown below:
             return retval;
 
         /* Display the port MAC address. */
-        rte_eth_macaddr_get(port, &addr);
+        retval = rte_eth_macaddr_get(port, &addr);
+        if (retval < 0)
+            return retval;
         printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
                " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
                port,
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index b9fa5f562..29ecb9274 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2702,14 +2702,16 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 	return j;
 }
 
-void
+int
 rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
+
+	return 0;
 }
 
 
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index aba5b4c86..9c213e072 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2361,8 +2361,11 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @param mac_addr
  *   A pointer to a structure of type *ether_addr* to be filled with
  *   the Ethernet address of the Ethernet device.
+ * @return
+ *   - (0) if successful
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
+int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
 /**
  * Retrieve the contextual information of an Ethernet device.
-- 
2.17.1


^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH 02/18] ethdev: change link status get functions return value to int
  @ 2019-09-10  8:25  3% ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-10  8:25 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Ori Kam,
	Bruce Richardson, Pablo de Lara, Radu Nicolau, Akhil Goyal,
	Tomasz Kantecki, Chas Williams, Thomas Monjalon, Ferruh Yigit
  Cc: dev, Igor Romanov

From: Igor Romanov <igor.romanov@oktetlabs.ru>

Change rte_eth_link_get() and rte_eth_link_get_nowait() return value
from void to int and return negative errno values in case of error
conditions.

Return value of link_update callback is ignored since the callback
returns not errors but whether link up status has changed or not.

Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst          |  1 -
 doc/guides/rel_notes/release_19_11.rst        |  4 ++++
 doc/guides/sample_app_ug/link_status_intr.rst |  9 ++++++---
 drivers/net/bonding/rte_eth_bond_pmd.c        |  2 +-
 lib/librte_ethdev/rte_ethdev.c                | 16 ++++++++++------
 lib/librte_ethdev/rte_ethdev.h                | 12 ++++++++++--
 6 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 165d13726..43b15ec2f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
   - ``rte_eth_dev_stop``
   - ``rte_eth_dev_close``
   - ``rte_eth_macaddr_get``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index d728592c8..3ff1296a2 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -108,6 +108,10 @@ API Changes
 * ethdev: changed ``rte_eth_dev_xstats_reset`` return value from ``void`` to
   ``int`` to provide a way to report various error conditions.
 
+* ethdev: changed ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
+  return value from ``void`` to ``int`` to provide a way to report various
+  error conditions.
+
 
 ABI Changes
 -----------
diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
index cfb1bcd58..5283be8b7 100644
--- a/doc/guides/sample_app_ug/link_status_intr.rst
+++ b/doc/guides/sample_app_ug/link_status_intr.rst
@@ -164,6 +164,7 @@ An example callback function that has been written as indicated below.
     lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param)
     {
         struct rte_eth_link link;
+        int ret;
 
         RTE_SET_USED(param);
 
@@ -171,9 +172,11 @@ An example callback function that has been written as indicated below.
 
         printf("Event type: %s\n", type == RTE_ETH_EVENT_INTR_LSC ? "LSC interrupt" : "unknown event");
 
-        rte_eth_link_get_nowait(port_id, &link);
-
-        if (link.link_status) {
+        ret = rte_eth_link_get_nowait(port_id, &link);
+        if (ret < 0) {
+            printf("Failed to get port %d link status: %s\n\n",
+                   port_id, rte_strerror(-ret));
+        } else if (link.link_status) {
             printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, (unsigned)link.link_speed,
                   (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex"));
         } else
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fed71bd95..9316f93f7 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2358,7 +2358,7 @@ bond_ethdev_slave_link_status_change_monitor(void *cb_arg)
 static int
 bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 {
-	void (*link_update)(uint16_t port_id, struct rte_eth_link *eth_link);
+	int (*link_update)(uint16_t port_id, struct rte_eth_link *eth_link);
 
 	struct bond_dev_private *bond_ctx;
 	struct rte_eth_link slave_link;
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 1bd1e32b0..b9fa5f562 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2015,40 +2015,44 @@ rte_eth_allmulticast_get(uint16_t port_id)
 	return dev->data->all_multicast;
 }
 
-void
+int
 rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
 	else {
-		RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update);
+		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
 		(*dev->dev_ops->link_update)(dev, 1);
 		*eth_link = dev->data->dev_link;
 	}
+
+	return 0;
 }
 
-void
+int
 rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
 	else {
-		RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update);
+		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
 		(*dev->dev_ops->link_update)(dev, 0);
 		*eth_link = dev->data->dev_link;
 	}
+
+	return 0;
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 14420dbbe..aba5b4c86 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2103,8 +2103,12 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  * @param link
  *   A pointer to an *rte_eth_link* structure to be filled with
  *   the status, the speed and the mode of the Ethernet device link.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if the function is not supported in PMD driver.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
+int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
 /**
  * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
@@ -2116,8 +2120,12 @@ void rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  * @param link
  *   A pointer to an *rte_eth_link* structure to be filled with
  *   the status, the speed and the mode of the Ethernet device link.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if the function is not supported in PMD driver.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
+int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
 /**
  * Retrieve the general I/O statistics of an Ethernet device.
-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH 1/7] ethdev: change allmulticast mode controllers to return errors
  @ 2019-09-09 12:13  4% ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-09 12:13 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Thomas Monjalon,
	Ferruh Yigit
  Cc: dev, Ivan Ilchenko

From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>

Change rte_eth_allmulticast_enable()/rte_eth_allmulticast_disable()
return value from void to int and return negative errno values
in case of error conditions.
Modify usage of these functions across the ethdev according
to new return type.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst   |  1 -
 doc/guides/rel_notes/release_19_11.rst |  4 +++
 lib/librte_ethdev/rte_ethdev.c         | 37 +++++++++++++++++++-------
 lib/librte_ethdev/rte_ethdev.h         | 14 ++++++++--
 4 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b2e0a1fc7c..0d8e231ef5 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
   - ``rte_eth_dev_stop``
   - ``rte_eth_dev_close``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 5299157df7..a79e6a08e6 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -101,6 +101,10 @@ API Changes
   ``rte_eth_promiscuous_disable`` return value from ``void`` to ``int`` to
   provide a way to report various error conditions.
 
+* ethdev: changed ``rte_eth_allmulticast_enable`` and
+  ``rte_eth_allmulticast_disable`` return value from ``void`` to ``int`` to
+  provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 98fe533c5a..577640fdbe 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1416,10 +1416,23 @@ rte_eth_dev_config_restore(struct rte_eth_dev *dev,
 	}
 
 	/* replay all multicast configuration */
-	if (rte_eth_allmulticast_get(port_id) == 1)
-		rte_eth_allmulticast_enable(port_id);
-	else if (rte_eth_allmulticast_get(port_id) == 0)
-		rte_eth_allmulticast_disable(port_id);
+	if (rte_eth_allmulticast_get(port_id) == 1) {
+		ret = rte_eth_allmulticast_enable(port_id);
+		if (ret != 0 && ret != -ENOTSUP) {
+			RTE_ETHDEV_LOG(ERR,
+				"Failed to enable allmulticast mode for device (port %u): %s\n",
+				port_id, rte_strerror(-ret));
+			return ret;
+		}
+	} else if (rte_eth_allmulticast_get(port_id) == 0) {
+		ret = rte_eth_allmulticast_disable(port_id);
+		if (ret != 0 && ret != -ENOTSUP) {
+			RTE_ETHDEV_LOG(ERR,
+				"Failed to disable allmulticast mode for device (port %u): %s\n",
+				port_id, rte_strerror(-ret));
+			return ret;
+		}
+	}
 
 	return 0;
 }
@@ -1945,30 +1958,34 @@ rte_eth_promiscuous_get(uint16_t port_id)
 	return dev->data->promiscuous;
 }
 
-void
+int
 rte_eth_allmulticast_enable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_enable);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_enable, -ENOTSUP);
 	(*dev->dev_ops->allmulticast_enable)(dev);
 	dev->data->all_multicast = 1;
+
+	return 0;
 }
 
-void
+int
 rte_eth_allmulticast_disable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_disable);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_disable, -ENOTSUP);
 	dev->data->all_multicast = 0;
 	(*dev->dev_ops->allmulticast_disable)(dev);
+
+	return 0;
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index f07a829b29..d24e3f9a24 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2060,16 +2060,26 @@ int rte_eth_promiscuous_get(uint16_t port_id);
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for allmulticast_enable() does not exist
+ *     for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_allmulticast_enable(uint16_t port_id);
+int rte_eth_allmulticast_enable(uint16_t port_id);
 
 /**
  * Disable the receipt of all multicast frames by an Ethernet device.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for allmulticast_disable() does not exist
+ *     for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_allmulticast_disable(uint16_t port_id);
+int rte_eth_allmulticast_disable(uint16_t port_id);
 
 /**
  * Return the value of allmulticast mode for an Ethernet device.
-- 
2.17.1


^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 01/13] ethdev: change promiscuous mode controllers to return errors
  @ 2019-09-09 11:58  3%   ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-09 11:58 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Bernard Iremonger,
	Ori Kam, Bruce Richardson, Pablo de Lara, Radu Nicolau,
	Akhil Goyal, Tomasz Kantecki, Harry van Haaren, Xiaoyun Li,
	Thomas Monjalon, Ferruh Yigit
  Cc: dev, Ivan Ilchenko

From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>

Change rte_eth_promiscuous_enable()/rte_eth_promiscuous_disable()
return value from void to int and return negative errno values
in case of error conditions.
Modify usage of these functions across the ethdev according
to new return type.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst        |  1 -
 doc/guides/rel_notes/release_19_11.rst      |  4 ++
 doc/guides/sample_app_ug/flow_classify.rst  |  6 ++-
 doc/guides/sample_app_ug/flow_filtering.rst | 15 +++++-
 doc/guides/sample_app_ug/rxtx_callbacks.rst |  5 +-
 doc/guides/sample_app_ug/skeleton.rst       |  6 ++-
 lib/librte_ethdev/rte_ethdev.c              | 52 ++++++++++++++++-----
 lib/librte_ethdev/rte_ethdev.h              | 14 +++++-
 8 files changed, 80 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index cbb4c34efd..b2e0a1fc7c 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_promiscuous_enable`` and ``rte_eth_promiscuous_disable``
   - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
   - ``rte_eth_dev_stop``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 152f120197..5299157df7 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -97,6 +97,10 @@ API Changes
 * ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void`` to
   ``int`` to provide a way to report various error conditions.
 
+* ethdev: changed ``rte_eth_promiscuous_enable`` and
+  ``rte_eth_promiscuous_disable`` return value from ``void`` to ``int`` to
+  provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
diff --git a/doc/guides/sample_app_ug/flow_classify.rst b/doc/guides/sample_app_ug/flow_classify.rst
index 96a5c66d0f..7c2b6dcf83 100644
--- a/doc/guides/sample_app_ug/flow_classify.rst
+++ b/doc/guides/sample_app_ug/flow_classify.rst
@@ -315,7 +315,9 @@ Forwarding application is shown below:
                addr.addr_bytes[4], addr.addr_bytes[5]);
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+                return retval;
 
         return 0;
     }
@@ -343,7 +345,7 @@ Finally the RX port is set in promiscuous mode:
 
 .. code-block:: c
 
-    rte_eth_promiscuous_enable(port);
+    retval = rte_eth_promiscuous_enable(port);
 
 The Add Rules function
 ~~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/guides/sample_app_ug/flow_filtering.rst b/doc/guides/sample_app_ug/flow_filtering.rst
index 02fc675506..de3e4ab0b6 100644
--- a/doc/guides/sample_app_ug/flow_filtering.rst
+++ b/doc/guides/sample_app_ug/flow_filtering.rst
@@ -193,7 +193,13 @@ application is shown below:
                    }
           }
 
-           rte_eth_promiscuous_enable(port_id);
+           ret = rte_eth_promiscuous_enable(port_id);
+           if (ret != 0) {
+                   rte_exit(EXIT_FAILURE,
+                           ":: cannot enable promiscuous mode: err=%d, port=%u\n",
+                           ret, port_id);
+           }
+
            ret = rte_eth_dev_start(port_id);
            if (ret < 0) {
                    rte_exit(EXIT_FAILURE,
@@ -278,7 +284,12 @@ We are setting the RX port to promiscuous mode:
 
 .. code-block:: c
 
-   rte_eth_promiscuous_enable(port_id);
+   ret = rte_eth_promiscuous_enable(port_id);
+   if (ret != 0) {
+        rte_exit(EXIT_FAILURE,
+                 ":: cannot enable promiscuous mode: err=%d, port=%u\n",
+                 ret, port_id);
+   }
 
 The last step is to start the port.
 
diff --git a/doc/guides/sample_app_ug/rxtx_callbacks.rst b/doc/guides/sample_app_ug/rxtx_callbacks.rst
index 32c120992f..0a69ec71ab 100644
--- a/doc/guides/sample_app_ug/rxtx_callbacks.rst
+++ b/doc/guides/sample_app_ug/rxtx_callbacks.rst
@@ -117,8 +117,9 @@ comments:
             return retval;
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
-
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+            return retval;
 
         /* Add the callbacks for RX and TX.*/
         rte_eth_add_rx_callback(port, 0, add_timestamps, NULL);
diff --git a/doc/guides/sample_app_ug/skeleton.rst b/doc/guides/sample_app_ug/skeleton.rst
index 59ca511d33..1d0a2760d4 100644
--- a/doc/guides/sample_app_ug/skeleton.rst
+++ b/doc/guides/sample_app_ug/skeleton.rst
@@ -149,7 +149,9 @@ Forwarding application is shown below:
             return retval;
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+            return retval;
 
         return 0;
     }
@@ -177,7 +179,7 @@ Finally the RX port is set in promiscuous mode:
 
 .. code-block:: c
 
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
 
 
 The Lcores Main
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 30b0c7803f..b97dd8aa85 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1381,24 +1381,41 @@ rte_eth_dev_mac_restore(struct rte_eth_dev *dev,
 	}
 }
 
-static void
+static int
 rte_eth_dev_config_restore(struct rte_eth_dev *dev,
 			   struct rte_eth_dev_info *dev_info, uint16_t port_id)
 {
+	int ret;
+
 	if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR))
 		rte_eth_dev_mac_restore(dev, dev_info);
 
 	/* replay promiscuous configuration */
-	if (rte_eth_promiscuous_get(port_id) == 1)
-		rte_eth_promiscuous_enable(port_id);
-	else if (rte_eth_promiscuous_get(port_id) == 0)
-		rte_eth_promiscuous_disable(port_id);
+	if (rte_eth_promiscuous_get(port_id) == 1) {
+		ret = rte_eth_promiscuous_enable(port_id);
+		if (ret != 0 && ret != -ENOTSUP) {
+			RTE_ETHDEV_LOG(ERR,
+				"Failed to enable promiscuous mode for device (port %u): %s\n",
+				port_id, rte_strerror(-ret));
+			return ret;
+		}
+	} else if (rte_eth_promiscuous_get(port_id) == 0) {
+		ret = rte_eth_promiscuous_disable(port_id);
+		if (ret != 0 && ret != -ENOTSUP) {
+			RTE_ETHDEV_LOG(ERR,
+				"Failed to disable promiscuous mode for device (port %u): %s\n",
+				port_id, rte_strerror(-ret));
+			return ret;
+		}
+	}
 
 	/* replay all multicast configuration */
 	if (rte_eth_allmulticast_get(port_id) == 1)
 		rte_eth_allmulticast_enable(port_id);
 	else if (rte_eth_allmulticast_get(port_id) == 0)
 		rte_eth_allmulticast_disable(port_id);
+
+	return 0;
 }
 
 int
@@ -1436,7 +1453,14 @@ rte_eth_dev_start(uint16_t port_id)
 	else
 		return eth_err(port_id, diag);
 
-	rte_eth_dev_config_restore(dev, &dev_info, port_id);
+	ret = rte_eth_dev_config_restore(dev, &dev_info, port_id);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Error during restoring configuration for device (port %u): %s\n",
+			port_id, rte_strerror(-ret));
+		rte_eth_dev_stop(port_id);
+		return ret;
+	}
 
 	if (dev->data->dev_conf.intr_conf.lsc == 0) {
 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
@@ -1864,30 +1888,34 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
 	return eth_err(port_id, ret);
 }
 
-void
+int
 rte_eth_promiscuous_enable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_enable);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP);
 	(*dev->dev_ops->promiscuous_enable)(dev);
 	dev->data->promiscuous = 1;
+
+	return 0;
 }
 
-void
+int
 rte_eth_promiscuous_disable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_disable);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP);
 	dev->data->promiscuous = 0;
 	(*dev->dev_ops->promiscuous_disable)(dev);
+
+	return 0;
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 475dbdae17..f07a829b29 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2022,16 +2022,26 @@ int rte_eth_dev_reset(uint16_t port_id);
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for promiscuous_enable() does not exist
+ *     for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_promiscuous_enable(uint16_t port_id);
+int rte_eth_promiscuous_enable(uint16_t port_id);
 
 /**
  * Disable receipt in promiscuous mode for an Ethernet device.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for promiscuous_disable() does not exist
+ *     for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_promiscuous_disable(uint16_t port_id);
+int rte_eth_promiscuous_disable(uint16_t port_id);
 
 /**
  * Return the value of promiscuous mode for an Ethernet device.
-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 15/15] sched: remove redundant code
  @ 2019-09-09 10:05  4%   ` Jasvinder Singh
  0 siblings, 0 replies; 200+ results
From: Jasvinder Singh @ 2019-09-09 10:05 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Lukasz Krakowiak

Remove redundant data structure fields from port level data
structures and update release notes.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com>
---
 doc/guides/rel_notes/release_19_11.rst |  6 +++-
 lib/librte_sched/rte_sched.c           | 43 +-------------------------
 lib/librte_sched/rte_sched.h           | 22 -------------
 3 files changed, 6 insertions(+), 65 deletions(-)

diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 8490d897c..746aeb0ea 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -85,6 +85,10 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* sched: The pipe nodes configuration parameters such as number of pipes,
+  pipe queue sizes, pipe profiles, etc., are moved from port level structure
+  to subport level. This allows different subports of the same port to
+  have different configuration for the pipe nodes.
 
 ABI Changes
 -----------
@@ -172,7 +176,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_rcu.so.1
      librte_reorder.so.1
      librte_ring.so.2
-     librte_sched.so.3
+   + librte_sched.so.4
      librte_security.so.2
      librte_stack.so.1
      librte_table.so.3
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 8a7727286..ba504da1e 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -207,10 +207,8 @@ struct rte_sched_subport {
 struct rte_sched_port {
 	/* User parameters */
 	uint32_t n_subports_per_port;
-	uint32_t n_pipes_per_subport;
 	uint32_t n_max_pipes_per_subport;
 	uint32_t n_max_pipes_per_subport_log2;
-	uint32_t n_pipes_per_subport_log2;
 	uint16_t pipe_queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
 	uint8_t pipe_tc[RTE_SCHED_QUEUES_PER_PIPE];
 	uint8_t tc_queue[RTE_SCHED_QUEUES_PER_PIPE];
@@ -218,13 +216,7 @@ struct rte_sched_port {
 	uint32_t mtu;
 	uint32_t frame_overhead;
 	int socket;
-	uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
-	uint32_t n_pipe_profiles;
 	uint32_t n_max_pipe_profiles;
-	uint32_t pipe_tc_be_rate_max;
-#ifdef RTE_SCHED_RED
-	struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
-#endif
 
 	/* Timing */
 	uint64_t time_cpu_cycles;     /* Current CPU time measured in CPU cyles */
@@ -232,48 +224,15 @@ struct rte_sched_port {
 	uint64_t time;                /* Current NIC TX time measured in bytes */
 	struct rte_reciprocal inv_cycles_per_byte; /* CPU cycles per byte */
 
-	/* Scheduling loop detection */
-	uint32_t pipe_loop;
-	uint32_t pipe_exhaustion;
-
-	/* Bitmap */
-	struct rte_bitmap *bmp;
-	uint32_t grinder_base_bmp_pos[RTE_SCHED_PORT_N_GRINDERS] __rte_aligned_16;
-
 	/* Grinders */
-	struct rte_sched_grinder grinder[RTE_SCHED_PORT_N_GRINDERS];
-	uint32_t busy_grinders;
 	struct rte_mbuf **pkts_out;
 	uint32_t n_pkts_out;
 	uint32_t subport_id;
 
-	/* Queue base calculation */
-	uint32_t qsize_add[RTE_SCHED_QUEUES_PER_PIPE];
-	uint32_t qsize_sum;
-
 	/* Large data structures */
-	struct rte_sched_subport *subports[0];
-	struct rte_sched_subport *subport;
-	struct rte_sched_pipe *pipe;
-	struct rte_sched_queue *queue;
-	struct rte_sched_queue_extra *queue_extra;
-	struct rte_sched_pipe_profile *pipe_profiles;
-	uint8_t *bmp_array;
-	struct rte_mbuf **queue_array;
-	uint8_t memory[0] __rte_cache_aligned;
+	struct rte_sched_subport *subports[0] __rte_cache_aligned;
 } __rte_cache_aligned;
 
-enum rte_sched_port_array {
-	e_RTE_SCHED_PORT_ARRAY_SUBPORT = 0,
-	e_RTE_SCHED_PORT_ARRAY_PIPE,
-	e_RTE_SCHED_PORT_ARRAY_QUEUE,
-	e_RTE_SCHED_PORT_ARRAY_QUEUE_EXTRA,
-	e_RTE_SCHED_PORT_ARRAY_PIPE_PROFILES,
-	e_RTE_SCHED_PORT_ARRAY_BMP_ARRAY,
-	e_RTE_SCHED_PORT_ARRAY_QUEUE_ARRAY,
-	e_RTE_SCHED_PORT_ARRAY_TOTAL,
-};
-
 enum rte_sched_subport_array {
 	e_RTE_SCHED_SUBPORT_ARRAY_PIPE = 0,
 	e_RTE_SCHED_SUBPORT_ARRAY_QUEUE,
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index ea2b07448..db1b0232f 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -246,33 +246,11 @@ struct rte_sched_port_params {
 	/** Number of subports */
 	uint32_t n_subports_per_port;
 
-	/** Number of subport_pipes */
-	uint32_t n_pipes_per_subport;
-
 	/** Maximum number of subport_pipes */
 	uint32_t n_max_pipes_per_subport;
 
-	/** Packet queue size for each traffic class.
-	 * All the pipes within the same subport share the similar
-	 * configuration for the queues.
-	 */
-	uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
-
-	/** Pipe profile table.
-	 * Every pipe is configured using one of the profiles from this table.
-	 */
-	struct rte_sched_pipe_params *pipe_profiles;
-
-	/** Profiles in the pipe profile table */
-	uint32_t n_pipe_profiles;
-
 	/** Max profiles allowed in the pipe profile table */
 	uint32_t n_max_pipe_profiles;
-
-#ifdef RTE_SCHED_RED
-	/** RED parameters */
-	struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
-#endif
 };
 
 /*
-- 
2.21.0


^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [RFC] ethdev: support hairpin queue
  2019-09-06  3:08  0%     ` Wu, Jingjing
@ 2019-09-08  6:44  0%       ` Ori Kam
  0 siblings, 0 replies; 200+ results
From: Ori Kam @ 2019-09-08  6:44 UTC (permalink / raw)
  To: Wu, Jingjing, Thomas Monjalon, Yigit, Ferruh, arybchenko,
	Shahaf Shuler, Slava Ovsiienko, Alex Rosenbaum
  Cc: dev

Hi Jingjing,

PSB

> -----Original Message-----
> From: Wu, Jingjing <jingjing.wu@intel.com>
> Sent: Friday, September 6, 2019 6:08 AM
> To: Ori Kam <orika@mellanox.com>; Thomas Monjalon
> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> arybchenko@solarflare.com; Shahaf Shuler <shahafs@mellanox.com>; Slava
> Ovsiienko <viacheslavo@mellanox.com>; Alex Rosenbaum
> <alexr@mellanox.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [RFC] ethdev: support hairpin queue
> 
> Hi, Ori
> 
> Thanks for the explanation. I have more question below.
> 
> Thanks
> Jingjing
> 
> > -----Original Message-----
> > From: Ori Kam [mailto:orika@mellanox.com]
> > Sent: Thursday, September 5, 2019 1:45 PM
> > To: Wu, Jingjing <jingjing.wu@intel.com>; Thomas Monjalon
> <thomas@monjalon.net>;
> > Yigit, Ferruh <ferruh.yigit@intel.com>; arybchenko@solarflare.com; Shahaf
> Shuler
> > <shahafs@mellanox.com>; Slava Ovsiienko <viacheslavo@mellanox.com>;
> Alex
> > Rosenbaum <alexr@mellanox.com>
> > Cc: dev@dpdk.org
> > Subject: RE: [dpdk-dev] [RFC] ethdev: support hairpin queue
> >
> > Hi Wu,
> > Thanks for your comments PSB,
> >
> > Ori
> >
> > > -----Original Message-----
> > > From: Wu, Jingjing <jingjing.wu@intel.com>
> > > Sent: Thursday, September 5, 2019 7:01 AM
> > > To: Ori Kam <orika@mellanox.com>; Thomas Monjalon
> > > <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> > > arybchenko@solarflare.com; Shahaf Shuler <shahafs@mellanox.com>;
> Slava
> > > Ovsiienko <viacheslavo@mellanox.com>; Alex Rosenbaum
> > > <alexr@mellanox.com>
> > > Cc: dev@dpdk.org
> > > Subject: RE: [dpdk-dev] [RFC] ethdev: support hairpin queue
> > >
> > >
> > > > -----Original Message-----
> > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ori Kam
> > > > Sent: Tuesday, August 13, 2019 9:38 PM
> > > > To: thomas@monjalon.net; Yigit, Ferruh <ferruh.yigit@intel.com>;
> > > > arybchenko@solarflare.com; shahafs@mellanox.com;
> > > viacheslavo@mellanox.com;
> > > > alexr@mellanox.com
> > > > Cc: dev@dpdk.org; orika@mellanox.com
> > > > Subject: [dpdk-dev] [RFC] ethdev: support hairpin queue
> > > >
> > > > This RFC replaces RFC[1].
> > > >
> > > > The hairpin feature (different name can be forward) acts as "bump on the
> > > wire",
> > > > meaning that a packet that is received from the wire can be modified
> using
> > > > offloaded action and then sent back to the wire without application
> > > intervention
> > > > which save CPU cycles.
> > > >
> > > > The hairpin is the inverse function of loopback in which application
> > > > sends a packet then it is received again by the
> > > > application without being sent to the wire.
> > > >
> > > > The hairpin can be used by a number of different NVF, for example load
> > > > balancer, gateway and so on.
> > > >
> > > > As can be seen from the hairpin description, hairpin is basically RX queue
> > > > connected to TX queue.
> > > >
> > > > During the design phase I was thinking of two ways to implement this
> > > > feature the first one is adding a new rte flow action. and the second
> > > > one is create a special kind of queue.
> > > >
> > > > The advantages of using the queue approch:
> > > > 1. More control for the application. queue depth (the memory size that
> > > > should be used).
> > > > 2. Enable QoS. QoS is normaly a parametr of queue, so in this approch it
> > > > will be easy to integrate with such system.
> > >
> > >
> > > Which kind of QoS?
> >
> > For example latency , packet rate those kinds of makes sense in the queue
> level.
> > I know we don't have any current support but I think we will have during the
> next year.
> >
> Where would be the QoS API loading? TM API? Or propose other new?

I think it will be a new API,  The TM is more like limiting the bandwidth of a target flow, while in
QoS should influence more the priority between the queues.

> > >
> > > > 3. Native integression with the rte flow API. Just setting the target
> > > > queue/rss to hairpin queue, will result that the traffic will be routed
> > > > to the hairpin queue.
> > > > 4. Enable queue offloading.
> > > >
> > > Looks like the hairpin queue is just hardware queue, it has no relationship
> with
> > > host memory. It makes the queue concept a little bit confusing. And why do
> we
> > > need to setup queues, maybe some info in eth_conf is enough?
> >
> > Like stated above it makes sense to have queue related parameters.
> > For example I can think of application that most packets are going threw that
> hairpin
> > queue, but some control packets are
> > from the application. So the application can configure the QoS between those
> two
> > queues. In addtion this will enable the application
> > to use the queue like normal queue from rte_flow (see comment below) and
> every other
> > aspect.
> >
> Yes, it is typical use case. And rte_flow is used to classify to different queue?
> If I understand correct, your hairpin queue is using host memory/or on-card
> memory for buffering, but CPU cannot touch it, all the packet processing is
> done by NIC.
> Queue is created, where the queue ID is used? Tx queue ID may be used as
> action of rte_flow? I still don't understand where the hairpin Rx queue ID be
> used.
> In my opinion, if no rx/tx function, it should not be a true queue from host view.
> 

Yes rte_flow is used to classify the traffic between the queues, in order to use the hairpin feature in 
the basic usage, the application just insert any ingress flow that the target queue/RSS is hairpin queue.
For example assuming that queue index 4 is hairpin queue, hairpin will look something like this:
Flow create 0 ingress group 0 pattern eth / ipv4 .... / end actions decap / encap / queue index 4 / end

I understand but don't agree about your point that if there is no rx/tx function it is not a queue.
In hairpin queue we are offloading the data path. Unrelated to this RFC we are working on VDPA driver.
This is not ethdev driver but what it does is offloading the vhost and offloads the enqueue and dequeue functions[1].

> > >
> > > Not sure how your hardware make the hairpin work? Use rte_flow for
> packet
> > > modification offload? Then how does HW distribute packets to those
> hardware
> > > queue, classification? If So, why not just extend rte_flow with the hairpin
> > > action?
> > >
> >
> > You are correct, the application uses rte_flow and just points the traffic to the
> requested
> > hairpin queue/rss.
> > We could have added a new rte_flow command. The reasons we didn't:
> > 1. Like stated above some of the hairpin makes sense in queue level.
> > 2.  In the near future, we will also want to support hairpin between different
> ports. This
> > makes much more
> > sense using queues.
> >
> > > > Each hairpin Rxq can be connected Txq / number of Txqs which can
> belong to
> > > a
> > > > different ports assuming the PMD supports it. The same goes the other
> > > > way each hairpin Txq can be connected to one or more Rxqs.
> > > > This is the reason that both the Txq setup and Rxq setup are getting the
> > > > hairpin configuration structure.
> > > >
> > > > From PMD prespctive the number of Rxq/Txq is the total of standard
> > > > queues + hairpin queues.
> > > >
> > > > To configure hairpin queue the user should call
> > > > rte_eth_rx_hairpin_queue_setup / rte_eth_tx_hairpin_queue_setup
> insteed
> > > > of the normal queue setup functions.
> > >
> > > If the new API introduced to avoid ABI change, would one API
> > > rte_eth_rx_hairpin_setup be enough?
> >
> > I'm not sure I understand your comment.
> > The rx_hairpin_setup was created for two main reasons:
> > 1. Avoid API change.
> > 2. I think it is more correct to use different API since the parameters are
> different.
> >
> I mean not use queue setup concept, set hairpin feature through one hairpin
> configuration API.
> 

I'm not sure I understand.
API that will look something like this will be better?
Int hairpin_bind(uint16_t rx_port, uint16_t rx queue, struct hairpin_conf *rx_hairpin_conf, 
uint16_t tx_port, uint16_t tx_queue, struct hairpin_conf *tx_hairpin_conf)

The problem with such API, is that it will cause issue for nics that supports one to many connections.
For example assuming that some nic can support one rx queue to 4 tx queues.
Also we still need to configure the hairpin queue. So if I understand you correctly is that the hairpin queues
will not be setup and this API will set them.
 
> > The reason we have both rx and tx setup functions is that we want the user to
> have
> > control binding the two queues.
> > It is most important when we will advance to hairpin between ports.
> 
> Hairpin between ports? It looks like switch but not hairpin, right?

Switch from my understanding is between VM meaning traffic sent from one VM will be routed
directly to the target VM. This is not the case of hairpin. In hairpin traffic comes from the wire and goes
back to the wire. There are no VM in the system. Example application for hairpin is load balancers or gateways,
were we get for example one port is connected to one system and the second port connected to a second system.
It is the job of the application to check if the packet should pass and if so modify it, to match the second system.
For example moving VXLAN tunnel packet to MPLS tunnel in the other system.
  
> >
> > >
> > > Thanks
> > > Jingjing
> >
> > Thanks,
> > Ori

Thanks,
Ori

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v6 02/10] vhost: add packed ring
  @ 2019-09-06 16:42  3%     ` Maxime Coquelin
  0 siblings, 0 replies; 200+ results
From: Maxime Coquelin @ 2019-09-06 16:42 UTC (permalink / raw)
  To: JinYu, dev
  Cc: changpeng.liu, tiwei.bie, zhihong.wang, Lin Li, Xun Ni, Yu Zhang



On 8/29/19 4:12 PM, JinYu wrote:
> This patch add the packed ring in the rte_vhost_vring.
> 
> Signed-off-by: Lin Li <lilin24@baidu.com>
> Signed-off-by: Xun Ni <nixun@baidu.com>
> Signed-off-by: Yu Zhang <zhangyu31@baidu.com>
> Signed-off-by: Jin Yu <jin.yu@intel.com>
> ---
>  lib/librte_vhost/rte_vhost.h | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> index 9943575ce..7257f0965 100644
> --- a/lib/librte_vhost/rte_vhost.h
> +++ b/lib/librte_vhost/rte_vhost.h
> @@ -103,9 +103,18 @@ struct rte_vhost_memory {
>  };
>  
>  struct rte_vhost_vring {
> -	struct vring_desc	*desc;
> -	struct vring_avail	*avail;
> -	struct vring_used	*used;
> +	union {
> +		struct vring_desc *desc;
> +		struct vring_packed_desc *desc_packed;
> +	};
> +	union {
> +		struct vring_avail *avail;
> +		struct vring_packed_desc_event *driver_event;
> +	};
> +	union {
> +		struct vring_used *used;
> +		struct vring_packed_desc_event *device_event;
> +	};
>  	uint64_t		log_guest_addr;
>  
>  	/** Deprecated, use rte_vhost_vring_call() instead. */
> 

My understanding is that it does neither break the API nor ABI.

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH 1/2] ethdev: change xstats reset function return value to int
  @ 2019-09-06 14:34  4% ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-06 14:34 UTC (permalink / raw)
  To: Maryam Tahhan, Reshma Pattan, Wenzhuo Lu, Jingjing Wu,
	Bernard Iremonger, Neil Horman, John McNamara, Marko Kovacevic,
	Thomas Monjalon, Ferruh Yigit
  Cc: dev, Igor Romanov

From: Igor Romanov <igor.romanov@oktetlabs.ru>

Change rte_eth_xstats_reset() return value from void to int and
return negative errno values in case of error conditions.

Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 app/proc-info/main.c                   | 10 +++++++++-
 app/test-pmd/config.c                  |  8 +++++++-
 doc/guides/rel_notes/deprecation.rst   |  1 -
 doc/guides/rel_notes/release_19_11.rst |  3 +++
 lib/librte_ethdev/rte_ethdev.c         |  8 ++++----
 lib/librte_ethdev/rte_ethdev.h         |  7 ++++++-
 6 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index 34eb7a7cc4..94e808dc6e 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -580,8 +580,16 @@ nic_xstats_display(uint16_t port_id)
 static void
 nic_xstats_clear(uint16_t port_id)
 {
+	int ret;
+
 	printf("\n Clearing NIC xstats for port %d\n", port_id);
-	rte_eth_xstats_reset(port_id);
+	ret = rte_eth_xstats_reset(port_id);
+	if (ret != 0) {
+		printf("\n Error clearing xstats for port %d: %s\n", port_id,
+		       strerror(-ret));
+		return;
+	}
+
 	printf("\n  NIC extended statistics for port %d cleared\n", port_id);
 }
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 24158e5f7d..857b6dabc9 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -273,7 +273,13 @@ nic_xstats_display(portid_t port_id)
 void
 nic_xstats_clear(portid_t port_id)
 {
-	rte_eth_xstats_reset(port_id);
+	int ret;
+
+	ret = rte_eth_xstats_reset(port_id);
+	if (ret != 0) {
+		printf("%s: Error: failed to reset xstats (port %u): %s",
+		       __func__, port_id, strerror(ret));
+	}
 }
 
 void
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b2e0a1fc7c..beb9cc3b65 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -92,7 +92,6 @@ Deprecation Notices
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
   - ``rte_eth_dev_stop``
   - ``rte_eth_dev_close``
-  - ``rte_eth_xstats_reset``
   - ``rte_eth_macaddr_get``
   - ``rte_eth_dev_owner_delete``
 
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 5299157df7..3f492ac20d 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -101,6 +101,9 @@ API Changes
   ``rte_eth_promiscuous_disable`` return value from ``void`` to ``int`` to
   provide a way to report various error conditions.
 
+* ethdev: changed ``rte_eth_dev_xstats_reset`` return value from ``void`` to
+  ``int`` to provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 98fe533c5a..b843bbc208 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2518,22 +2518,22 @@ rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats,
 }
 
 /* reset ethdev extended statistics */
-void
+int
 rte_eth_xstats_reset(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	/* implemented by the driver */
 	if (dev->dev_ops->xstats_reset != NULL) {
 		(*dev->dev_ops->xstats_reset)(dev);
-		return;
+		return 0;
 	}
 
 	/* fallback to default */
-	rte_eth_stats_reset(port_id);
+	return rte_eth_stats_reset(port_id);
 }
 
 static int
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index f07a829b29..328503d1be 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2284,8 +2284,13 @@ int rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if device notified to reset extended stats.
+ *   - (-ENOTSUP) if pmd doesn't support both
+ *     extended stats and basic stats reset.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_xstats_reset(uint16_t port_id);
+int rte_eth_xstats_reset(uint16_t port_id);
 
 /**
  *  Set a mapping for the specified transmit queue to the specified per-queue
-- 
2.17.1


^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [RFC 19.11 v2 0/3] Hide DPDK internal struct from public API
  @ 2019-09-06 14:00  3%   ` Bruce Richardson
  0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-09-06 14:00 UTC (permalink / raw)
  To: Marcin Zapolski; +Cc: dev, jerinj

On Fri, Sep 06, 2019 at 03:18:10PM +0200, Marcin Zapolski wrote:
> Several DPDK internal structures are exposed to direct access by user
> applications. This patch removes them from public API, and makes core DPDK
> functions that use them non-inline.
> 
> v2:
> This patch set no longer makes internal DPDK functions non-inline. Instead
> it splits the rte_eth_dev structure to private and public part and modifies
> function arguments of rx and tx functions. This should bring less performance
> impact, but at the cost of needing to modify every PMD to use new rx and tx
> functions.
> For testing purposes, the ixgbe and i40e drivers are modified to acommodate for
> the changes.
> 
> Marcin Zapolski (3):
>   ethdev: hide key ethdev structures from public API
>   i40e: make driver compatible with changes in ethdev
>   ixgbe: make driver compatible with changes in ethdev
> 
Thanks for testing this out Marcin. The performance impact seems lower
alright. The amount of changes needed I still am not particularly happy
about, so I'd like to propose a third option for consideration.

How about leaving the existing inline functions as they are, but also
providing the uninline functions for backward compatibility, with a
build-time switch to select between the two? Standard builds could use the
uninline versions for API/ABI compatibility, while any builds which
absolutely need the most performance can switch to using the inline
versions at the cost of compatibility. We could even make the build-switch
generic to indicate across all components a preference for absolute
performance over compatibility.

Regards,
/Bruce

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
  @ 2019-09-06 13:27  4%         ` Ananyev, Konstantin
  2019-09-10 10:44  4%           ` Akhil Goyal
  0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-09-06 13:27 UTC (permalink / raw)
  To: Akhil Goyal, dev; +Cc: Zhang, Roy Fan, Doherty, Declan, De Lara Guarch, Pablo

Hi Akhil,

> > This action type allows the burst of symmetric crypto workload using the same
> > algorithm, key, and direction being processed by CPU cycles synchronously.
> > This flexible action type does not require external hardware involvement,
> > having the crypto workload processed synchronously, and is more performant
> > than Cryptodev SW PMD due to the saved cycles on removed "async mode
> > simulation" as well as 3 cacheline access of the crypto ops.
> 
> Does that mean application will not call the cryptodev_enqueue_burst and corresponding dequeue burst.

Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)

> It would be a new API something like process_packets and it will have the crypto processed packets while returning from the API?

Yes, though the plan is that API will operate on raw data buffers, not mbufs.

> 
> I still do not understand why we cannot do with the conventional crypto lib only.
> As far as I can understand, you are not doing any protocol processing or any value add
> To the crypto processing. IMO, you just need a synchronous crypto processing API which
> Can be defined in cryptodev, you don't need to re-create a crypto session in the name of
> Security session in the driver just to do a synchronous processing.

I suppose your question is why not to have rte_crypot_process_cpu_crypto_bulk(...) instead?
The main reason is that would require disruptive changes in existing cryptodev API
(would cause ABI/API breakage).
Session for  RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need some extra information
that normal crypto_sym_xform doesn't contain 
(cipher offset from the start of the buffer, might be something extra in future).
Also right now there is no way to add new type of crypto_sym_session without
either breaking existing crypto-dev ABI/API or introducing new structure 
(rte_crypto_sym_cpu_session or so) for that.   
While rte_security is designed in a way that we can add new session types and
related parameters without causing API/ABI breakage. 

BTW, what is your concern with proposed approach (via rte_security)?
From my perspective it is a lightweight change and it is totally optional
for the crypto PMDs to support it or not.
Konstantin 

> >
> > AESNI-GCM and AESNI-MB PMDs are updated with this support. There is a small
> > performance test app under app/test/security_aesni_gcm(mb)_perftest to
> > prove.
> >
> > For the new API
> > The packet is sent to the crypto device for symmetric crypto
> > processing. The device will encrypt or decrypt the buffer based on the session
> > data specified and preprocessed in the security session. Different
> > than the inline or lookaside modes, when the function exits, the user will
> > expect the buffers are either processed successfully, or having the error number
> > assigned to the appropriate index of the status array.
> >
> > Will update the program's guide in the v1 patch.
> >
> > Regards,
> > Fan
> >
> > > -----Original Message-----
> > > From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > > Sent: Wednesday, September 4, 2019 11:33 AM
> > > To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> > > Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Doherty, Declan
> > > <declan.doherty@intel.com>; De Lara Guarch, Pablo
> > > <pablo.de.lara.guarch@intel.com>
> > > Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action type and
> > > API
> > >
> > > Hi Fan,
> > >
> > > >
> > > > This patch introduce new RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > action
> > > > type to security library. The type represents performing crypto
> > > > operation with CPU cycles. The patch also includes a new API to
> > > > process crypto operations in bulk and the function pointers for PMDs.
> > > >
> > > I am not able to get the flow of execution for this action type. Could you
> > > please elaborate the flow in the documentation. If not in documentation
> > > right now, then please elaborate the flow in cover letter.
> > > Also I see that there are new APIs for processing crypto operations in bulk.
> > > What does that mean. How are they different from the existing APIs which
> > > are also handling bulk crypto ops depending on the budget.
> > >
> > >
> > > -Akhil


^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v3 02/54] ethdev: change rte_eth_dev_info_get() return value to int
  @ 2019-09-06  7:30  3%   ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-06  7:30 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Thomas Monjalon,
	Ferruh Yigit
  Cc: dev, Ivan Ilchenko

From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>

Change rte_eth_dev_info_get() return value from void to int and return
negative errno values in case of error conditions.
Modify rte_eth_dev_info_get() usage across the ethdev according
to new return type.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
v3:
 - return -1 from get_mac_addr_index() and get_hash_mac_addr_index()
 - rollback dev_conf in the case of rte_eth_dev_info_get() failure

 doc/guides/rel_notes/deprecation.rst   |  1 -
 doc/guides/rel_notes/release_19_11.rst |  5 +-
 lib/librte_ethdev/rte_ethdev.c         | 69 ++++++++++++++++++--------
 lib/librte_ethdev/rte_ethdev.h         |  6 ++-
 4 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 0ee8533b13..cbb4c34efd 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_dev_info_get``
   - ``rte_eth_promiscuous_enable`` and ``rte_eth_promiscuous_disable``
   - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 27cfbd9e38..152f120197 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -94,6 +94,9 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void`` to
+  ``int`` to provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
@@ -145,7 +148,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_distributor.so.1
      librte_eal.so.11
      librte_efd.so.1
-     librte_ethdev.so.12
+   + librte_ethdev.so.13
      librte_eventdev.so.7
      librte_flow_classify.so.1
      librte_gro.so.1
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e1f0..42b1d6e30a 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1125,7 +1125,6 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -1144,7 +1143,9 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	 */
 	memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf));
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		goto rollback;
 
 	/* If number of queues specified by application for both Rx and Tx is
 	 * zero, use driver preferred values. This cannot be done individually
@@ -1406,6 +1407,7 @@ rte_eth_dev_start(uint16_t port_id)
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
 	int diag;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1420,7 +1422,9 @@ rte_eth_dev_start(uint16_t port_id)
 		return 0;
 	}
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* Lets restore MAC now if device does not support live change */
 	if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)
@@ -1584,7 +1588,6 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 		return -EINVAL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP);
 
 	/*
@@ -1592,7 +1595,10 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	 * This value must be provided in the private data of the memory pool.
 	 * First check that the memory pool has a valid private data.
 	 */
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
 		RTE_ETHDEV_LOG(ERR, "%s private_data_size %d < %d\n",
 			mp->name, (int)mp->private_data_size,
@@ -1703,6 +1709,7 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_txconf local_conf;
 	void **txq;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1712,10 +1719,11 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 		return -EINVAL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP);
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* Use default specified by driver, if nb_tx_desc is zero */
 	if (nb_tx_desc == 0) {
@@ -2540,7 +2548,7 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 							fw_version, fw_size));
 }
 
-void
+int
 rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 {
 	struct rte_eth_dev *dev;
@@ -2558,7 +2566,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	 */
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	dev_info->rx_desc_lim = lim;
@@ -2567,13 +2575,15 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
 	dev_info->max_mtu = UINT16_MAX;
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
 
 	dev_info->dev_flags = &dev->data->dev_flags;
+
+	return 0;
 }
 
 int
@@ -2643,7 +2653,10 @@ rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
 	 * which relies on dev->dev_ops->dev_infos_get.
 	 */
 	if (*dev->dev_ops->dev_infos_get != NULL) {
-		rte_eth_dev_info_get(port_id, &dev_info);
+		ret = rte_eth_dev_info_get(port_id, &dev_info);
+		if (ret != 0)
+			return ret;
+
 		if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
 			return -EINVAL;
 	}
@@ -2991,10 +3004,15 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	dev = &rte_eth_devices[port_id];
-	rte_eth_dev_info_get(port_id, &dev_info);
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3100,9 +3118,11 @@ get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	unsigned i;
+	int ret;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return -1;
 
 	for (i = 0; i < dev_info.max_mac_addrs; i++)
 		if (memcmp(addr, &dev->data->mac_addrs[i],
@@ -3233,8 +3253,12 @@ get_hash_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	unsigned i;
+	int ret;
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return -1;
 
-	rte_eth_dev_info_get(port_id, &dev_info);
 	if (!dev->data->hash_mac_addrs)
 		return -1;
 
@@ -3319,11 +3343,15 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_link link;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	dev = &rte_eth_devices[port_id];
-	rte_eth_dev_info_get(port_id, &dev_info);
 	link = dev->data->dev_link;
 
 	if (queue_idx > dev_info.max_tx_queues) {
@@ -4363,15 +4391,14 @@ rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
 				 uint16_t *nb_rx_desc,
 				 uint16_t *nb_tx_desc)
 {
-	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
-	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
-
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	if (nb_rx_desc != NULL)
 		rte_eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim);
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index d9871782e3..475dbdae17 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2366,8 +2366,12 @@ void rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  * @param dev_info
  *   A pointer to a structure of type *rte_eth_dev_info* to be filled with
  *   the contextual information of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
+int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
  * Retrieve the firmware version of a device.
-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC] ethdev: support hairpin queue
  2019-09-05  5:44  0%   ` Ori Kam
@ 2019-09-06  3:08  0%     ` Wu, Jingjing
  2019-09-08  6:44  0%       ` Ori Kam
  0 siblings, 1 reply; 200+ results
From: Wu, Jingjing @ 2019-09-06  3:08 UTC (permalink / raw)
  To: Ori Kam, Thomas Monjalon, Yigit, Ferruh, arybchenko,
	Shahaf Shuler, Slava Ovsiienko, Alex Rosenbaum
  Cc: dev

Hi, Ori

Thanks for the explanation. I have more question below.

Thanks
Jingjing

> -----Original Message-----
> From: Ori Kam [mailto:orika@mellanox.com]
> Sent: Thursday, September 5, 2019 1:45 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Thomas Monjalon <thomas@monjalon.net>;
> Yigit, Ferruh <ferruh.yigit@intel.com>; arybchenko@solarflare.com; Shahaf Shuler
> <shahafs@mellanox.com>; Slava Ovsiienko <viacheslavo@mellanox.com>; Alex
> Rosenbaum <alexr@mellanox.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [RFC] ethdev: support hairpin queue
> 
> Hi Wu,
> Thanks for your comments PSB,
> 
> Ori
> 
> > -----Original Message-----
> > From: Wu, Jingjing <jingjing.wu@intel.com>
> > Sent: Thursday, September 5, 2019 7:01 AM
> > To: Ori Kam <orika@mellanox.com>; Thomas Monjalon
> > <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> > arybchenko@solarflare.com; Shahaf Shuler <shahafs@mellanox.com>; Slava
> > Ovsiienko <viacheslavo@mellanox.com>; Alex Rosenbaum
> > <alexr@mellanox.com>
> > Cc: dev@dpdk.org
> > Subject: RE: [dpdk-dev] [RFC] ethdev: support hairpin queue
> >
> >
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ori Kam
> > > Sent: Tuesday, August 13, 2019 9:38 PM
> > > To: thomas@monjalon.net; Yigit, Ferruh <ferruh.yigit@intel.com>;
> > > arybchenko@solarflare.com; shahafs@mellanox.com;
> > viacheslavo@mellanox.com;
> > > alexr@mellanox.com
> > > Cc: dev@dpdk.org; orika@mellanox.com
> > > Subject: [dpdk-dev] [RFC] ethdev: support hairpin queue
> > >
> > > This RFC replaces RFC[1].
> > >
> > > The hairpin feature (different name can be forward) acts as "bump on the
> > wire",
> > > meaning that a packet that is received from the wire can be modified using
> > > offloaded action and then sent back to the wire without application
> > intervention
> > > which save CPU cycles.
> > >
> > > The hairpin is the inverse function of loopback in which application
> > > sends a packet then it is received again by the
> > > application without being sent to the wire.
> > >
> > > The hairpin can be used by a number of different NVF, for example load
> > > balancer, gateway and so on.
> > >
> > > As can be seen from the hairpin description, hairpin is basically RX queue
> > > connected to TX queue.
> > >
> > > During the design phase I was thinking of two ways to implement this
> > > feature the first one is adding a new rte flow action. and the second
> > > one is create a special kind of queue.
> > >
> > > The advantages of using the queue approch:
> > > 1. More control for the application. queue depth (the memory size that
> > > should be used).
> > > 2. Enable QoS. QoS is normaly a parametr of queue, so in this approch it
> > > will be easy to integrate with such system.
> >
> >
> > Which kind of QoS?
> 
> For example latency , packet rate those kinds of makes sense in the queue level.
> I know we don't have any current support but I think we will have during the next year.
> 
Where would be the QoS API loading? TM API? Or propose other new?
> >
> > > 3. Native integression with the rte flow API. Just setting the target
> > > queue/rss to hairpin queue, will result that the traffic will be routed
> > > to the hairpin queue.
> > > 4. Enable queue offloading.
> > >
> > Looks like the hairpin queue is just hardware queue, it has no relationship with
> > host memory. It makes the queue concept a little bit confusing. And why do we
> > need to setup queues, maybe some info in eth_conf is enough?
> 
> Like stated above it makes sense to have queue related parameters.
> For example I can think of application that most packets are going threw that hairpin
> queue, but some control packets are
> from the application. So the application can configure the QoS between those two
> queues. In addtion this will enable the application
> to use the queue like normal queue from rte_flow (see comment below) and every other
> aspect.
> 
Yes, it is typical use case. And rte_flow is used to classify to different queue?
If I understand correct, your hairpin queue is using host memory/or on-card memory for buffering, but CPU cannot touch it, all the packet processing is done by NIC.
Queue is created, where the queue ID is used? Tx queue ID may be used as action of rte_flow? I still don't understand where the hairpin Rx queue ID be used. 
In my opinion, if no rx/tx function, it should not be a true queue from host view. 

> >
> > Not sure how your hardware make the hairpin work? Use rte_flow for packet
> > modification offload? Then how does HW distribute packets to those hardware
> > queue, classification? If So, why not just extend rte_flow with the hairpin
> > action?
> >
> 
> You are correct, the application uses rte_flow and just points the traffic to the requested
> hairpin queue/rss.
> We could have added a new rte_flow command. The reasons we didn't:
> 1. Like stated above some of the hairpin makes sense in queue level.
> 2.  In the near future, we will also want to support hairpin between different ports. This
> makes much more
> sense using queues.
> 
> > > Each hairpin Rxq can be connected Txq / number of Txqs which can belong to
> > a
> > > different ports assuming the PMD supports it. The same goes the other
> > > way each hairpin Txq can be connected to one or more Rxqs.
> > > This is the reason that both the Txq setup and Rxq setup are getting the
> > > hairpin configuration structure.
> > >
> > > From PMD prespctive the number of Rxq/Txq is the total of standard
> > > queues + hairpin queues.
> > >
> > > To configure hairpin queue the user should call
> > > rte_eth_rx_hairpin_queue_setup / rte_eth_tx_hairpin_queue_setup insteed
> > > of the normal queue setup functions.
> >
> > If the new API introduced to avoid ABI change, would one API
> > rte_eth_rx_hairpin_setup be enough?
> 
> I'm not sure I understand your comment.
> The rx_hairpin_setup was created for two main reasons:
> 1. Avoid API change.
> 2. I think it is more correct to use different API since the parameters are different.
> 
I mean not use queue setup concept, set hairpin feature through one hairpin configuration API.

> The reason we have both rx and tx setup functions is that we want the user to have
> control binding the two queues.
> It is most important when we will advance to hairpin between ports.

Hairpin between ports? It looks like switch but not hairpin, right?
> 
> >
> > Thanks
> > Jingjing
> 
> Thanks,
> Ori

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH 01/13] ethdev: change promiscuous mode controllers to return errors
  @ 2019-09-05 16:10  3% ` Andrew Rybchenko
      2 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-05 16:10 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Bernard Iremonger,
	Ori Kam, Bruce Richardson, Pablo de Lara, Radu Nicolau,
	Akhil Goyal, Tomasz Kantecki, Harry van Haaren, Xiaoyun Li,
	Thomas Monjalon, Ferruh Yigit
  Cc: dev, Ivan Ilchenko

From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>

Change rte_eth_promiscuous_enable()/rte_eth_promiscuous_disable()
return value from void to int and return negative errno values
in case of error conditions.
Modify usage of these functions across the ethdev according
to new return type.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst        |  1 -
 doc/guides/rel_notes/release_19_11.rst      |  4 ++
 doc/guides/sample_app_ug/flow_classify.rst  |  6 ++-
 doc/guides/sample_app_ug/flow_filtering.rst | 15 +++++-
 doc/guides/sample_app_ug/rxtx_callbacks.rst |  5 +-
 doc/guides/sample_app_ug/skeleton.rst       |  6 ++-
 lib/librte_ethdev/rte_ethdev.c              | 52 ++++++++++++++++-----
 lib/librte_ethdev/rte_ethdev.h              | 14 +++++-
 8 files changed, 80 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index cbb4c34efd..b2e0a1fc7c 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_promiscuous_enable`` and ``rte_eth_promiscuous_disable``
   - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
   - ``rte_eth_dev_stop``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 152f120197..5299157df7 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -97,6 +97,10 @@ API Changes
 * ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void`` to
   ``int`` to provide a way to report various error conditions.
 
+* ethdev: changed ``rte_eth_promiscuous_enable`` and
+  ``rte_eth_promiscuous_disable`` return value from ``void`` to ``int`` to
+  provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
diff --git a/doc/guides/sample_app_ug/flow_classify.rst b/doc/guides/sample_app_ug/flow_classify.rst
index 96a5c66d0f..7c2b6dcf83 100644
--- a/doc/guides/sample_app_ug/flow_classify.rst
+++ b/doc/guides/sample_app_ug/flow_classify.rst
@@ -315,7 +315,9 @@ Forwarding application is shown below:
                addr.addr_bytes[4], addr.addr_bytes[5]);
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+                return retval;
 
         return 0;
     }
@@ -343,7 +345,7 @@ Finally the RX port is set in promiscuous mode:
 
 .. code-block:: c
 
-    rte_eth_promiscuous_enable(port);
+    retval = rte_eth_promiscuous_enable(port);
 
 The Add Rules function
 ~~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/guides/sample_app_ug/flow_filtering.rst b/doc/guides/sample_app_ug/flow_filtering.rst
index 02fc675506..de3e4ab0b6 100644
--- a/doc/guides/sample_app_ug/flow_filtering.rst
+++ b/doc/guides/sample_app_ug/flow_filtering.rst
@@ -193,7 +193,13 @@ application is shown below:
                    }
           }
 
-           rte_eth_promiscuous_enable(port_id);
+           ret = rte_eth_promiscuous_enable(port_id);
+           if (ret != 0) {
+                   rte_exit(EXIT_FAILURE,
+                           ":: cannot enable promiscuous mode: err=%d, port=%u\n",
+                           ret, port_id);
+           }
+
            ret = rte_eth_dev_start(port_id);
            if (ret < 0) {
                    rte_exit(EXIT_FAILURE,
@@ -278,7 +284,12 @@ We are setting the RX port to promiscuous mode:
 
 .. code-block:: c
 
-   rte_eth_promiscuous_enable(port_id);
+   ret = rte_eth_promiscuous_enable(port_id);
+   if (ret != 0) {
+        rte_exit(EXIT_FAILURE,
+                 ":: cannot enable promiscuous mode: err=%d, port=%u\n",
+                 ret, port_id);
+   }
 
 The last step is to start the port.
 
diff --git a/doc/guides/sample_app_ug/rxtx_callbacks.rst b/doc/guides/sample_app_ug/rxtx_callbacks.rst
index 32c120992f..0a69ec71ab 100644
--- a/doc/guides/sample_app_ug/rxtx_callbacks.rst
+++ b/doc/guides/sample_app_ug/rxtx_callbacks.rst
@@ -117,8 +117,9 @@ comments:
             return retval;
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
-
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+            return retval;
 
         /* Add the callbacks for RX and TX.*/
         rte_eth_add_rx_callback(port, 0, add_timestamps, NULL);
diff --git a/doc/guides/sample_app_ug/skeleton.rst b/doc/guides/sample_app_ug/skeleton.rst
index 59ca511d33..1d0a2760d4 100644
--- a/doc/guides/sample_app_ug/skeleton.rst
+++ b/doc/guides/sample_app_ug/skeleton.rst
@@ -149,7 +149,9 @@ Forwarding application is shown below:
             return retval;
 
         /* Enable RX in promiscuous mode for the Ethernet device. */
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
+        if (retval != 0)
+            return retval;
 
         return 0;
     }
@@ -177,7 +179,7 @@ Finally the RX port is set in promiscuous mode:
 
 .. code-block:: c
 
-        rte_eth_promiscuous_enable(port);
+        retval = rte_eth_promiscuous_enable(port);
 
 
 The Lcores Main
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 4b6cbe2343..0f6dedbe23 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1381,24 +1381,41 @@ rte_eth_dev_mac_restore(struct rte_eth_dev *dev,
 	}
 }
 
-static void
+static int
 rte_eth_dev_config_restore(struct rte_eth_dev *dev,
 			   struct rte_eth_dev_info *dev_info, uint16_t port_id)
 {
+	int ret;
+
 	if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR))
 		rte_eth_dev_mac_restore(dev, dev_info);
 
 	/* replay promiscuous configuration */
-	if (rte_eth_promiscuous_get(port_id) == 1)
-		rte_eth_promiscuous_enable(port_id);
-	else if (rte_eth_promiscuous_get(port_id) == 0)
-		rte_eth_promiscuous_disable(port_id);
+	if (rte_eth_promiscuous_get(port_id) == 1) {
+		ret = rte_eth_promiscuous_enable(port_id);
+		if (ret != 0 && ret != -ENOTSUP) {
+			RTE_ETHDEV_LOG(ERR,
+				"Failed to enable promiscuous mode for device (port %u): %s\n",
+				port_id, rte_strerror(-ret));
+			return ret;
+		}
+	} else if (rte_eth_promiscuous_get(port_id) == 0) {
+		ret = rte_eth_promiscuous_disable(port_id);
+		if (ret != 0 && ret != -ENOTSUP) {
+			RTE_ETHDEV_LOG(ERR,
+				"Failed to disable promiscuous mode for device (port %u): %s\n",
+				port_id, rte_strerror(-ret));
+			return ret;
+		}
+	}
 
 	/* replay all multicast configuration */
 	if (rte_eth_allmulticast_get(port_id) == 1)
 		rte_eth_allmulticast_enable(port_id);
 	else if (rte_eth_allmulticast_get(port_id) == 0)
 		rte_eth_allmulticast_disable(port_id);
+
+	return 0;
 }
 
 int
@@ -1436,7 +1453,14 @@ rte_eth_dev_start(uint16_t port_id)
 	else
 		return eth_err(port_id, diag);
 
-	rte_eth_dev_config_restore(dev, &dev_info, port_id);
+	ret = rte_eth_dev_config_restore(dev, &dev_info, port_id);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Error during restoring configuration for device (port %u): %s\n",
+			port_id, rte_strerror(-ret));
+		rte_eth_dev_stop(port_id);
+		return ret;
+	}
 
 	if (dev->data->dev_conf.intr_conf.lsc == 0) {
 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
@@ -1864,30 +1888,34 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
 	return eth_err(port_id, ret);
 }
 
-void
+int
 rte_eth_promiscuous_enable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_enable);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP);
 	(*dev->dev_ops->promiscuous_enable)(dev);
 	dev->data->promiscuous = 1;
+
+	return 0;
 }
 
-void
+int
 rte_eth_promiscuous_disable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_disable);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP);
 	dev->data->promiscuous = 0;
 	(*dev->dev_ops->promiscuous_disable)(dev);
+
+	return 0;
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index eda9e5c628..56e47b96be 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2022,16 +2022,26 @@ int rte_eth_dev_reset(uint16_t port_id);
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for promiscuous_enable() does not exist
+ *     for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_promiscuous_enable(uint16_t port_id);
+int rte_eth_promiscuous_enable(uint16_t port_id);
 
 /**
  * Disable receipt in promiscuous mode for an Ethernet device.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for promiscuous_disable() does not exist
+ *     for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_promiscuous_disable(uint16_t port_id);
+int rte_eth_promiscuous_disable(uint16_t port_id);
 
 /**
  * Return the value of promiscuous mode for an Ethernet device.
-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH 1/2] version: 19.11-rc0
@ 2019-09-05 15:47  6% agupta3
  0 siblings, 0 replies; 200+ results
From: agupta3 @ 2019-09-05 15:47 UTC (permalink / raw)
  To: John McNamara, Marko Kovacevic; +Cc: dev, David Marchand

From: David Marchand <david.marchand@redhat.com>

Start a new release cycle with empty release notes.

Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
---
 VERSION                                |   2 +-
 doc/guides/rel_notes/index.rst         |   1 +
 doc/guides/rel_notes/release_19_11.rst | 216 +++++++++++++++++++++++++++++++++
 3 files changed, 218 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/rel_notes/release_19_11.rst

diff --git a/VERSION b/VERSION
index 909cfd6..fff18fc 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-19.08.0
+19.11.0-rc0
diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index adfaf12..26f4a97 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -8,6 +8,7 @@ Release Notes
     :maxdepth: 1
     :numbered:
 
+    release_19_11
     release_19_08
     release_19_05
     release_19_02
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
new file mode 100644
index 0000000..8490d89
--- /dev/null
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -0,0 +1,216 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2019 The DPDK contributors
+
+.. include:: <isonum.txt>
+
+DPDK Release 19.11
+==================
+
+.. **Read this first.**
+
+   The text in the sections below explains how to update the release notes.
+
+   Use proper spelling, capitalization and punctuation in all sections.
+
+   Variable and config names should be quoted as fixed width text:
+   ``LIKE_THIS``.
+
+   Build the docs and view the output file to ensure the changes are correct::
+
+      make doc-guides-html
+
+      xdg-open build/doc/html/guides/rel_notes/release_19_11.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release.
+   Sample format:
+
+   * **Add a title in the past tense with a full stop.**
+
+     Add a short 1-2 sentence description in the past tense.
+     The description should be enough to allow someone scanning
+     the release notes to understand the new feature.
+
+     If the feature adds a lot of sub-features you can use a bullet list
+     like this:
+
+     * Added feature foo to do something.
+     * Enhanced feature bar to do something else.
+
+     Refer to the previous release notes for examples.
+
+     Suggested order in release notes items:
+     * Core libs (EAL, mempool, ring, mbuf, buses)
+     * Device abstraction libs and PMDs
+       - ethdev (lib, PMDs)
+       - cryptodev (lib, PMDs)
+       - eventdev (lib, PMDs)
+       - etc
+     * Other libs
+     * Apps, Examples, Tools (if significant)
+
+     This section is a comment. Do not overwrite or remove it.
+     Also, make sure to start the actual text at the margin.
+     =========================================================
+
+
+Removed Items
+-------------
+
+.. This section should contain removed items in this release. Sample format:
+
+   * Add a short 1-2 sentence description of the removed item
+     in the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+   * sample: Add a short 1-2 sentence description of the API change
+     which was announced in the previous releases and made in this release.
+     Start with a scope label like "ethdev:".
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+   * sample: Add a short 1-2 sentence description of the ABI change
+     which was announced in the previous releases and made in this release.
+     Start with a scope label like "ethdev:".
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Shared Library Versions
+-----------------------
+
+.. Update any library version updated in this release
+   and prepend with a ``+`` sign, like this:
+
+     libfoo.so.1
+   + libupdated.so.2
+     libbar.so.1
+
+   This section is a comment. Do not overwrite or remove it.
+   =========================================================
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     librte_acl.so.2
+     librte_bbdev.so.1
+     librte_bitratestats.so.2
+     librte_bpf.so.1
+     librte_bus_dpaa.so.2
+     librte_bus_fslmc.so.2
+     librte_bus_ifpga.so.2
+     librte_bus_pci.so.2
+     librte_bus_vdev.so.2
+     librte_bus_vmbus.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.2
+     librte_compressdev.so.1
+     librte_cryptodev.so.8
+     librte_distributor.so.1
+     librte_eal.so.11
+     librte_efd.so.1
+     librte_ethdev.so.12
+     librte_eventdev.so.7
+     librte_flow_classify.so.1
+     librte_gro.so.1
+     librte_gso.so.1
+     librte_hash.so.2
+     librte_ip_frag.so.1
+     librte_ipsec.so.1
+     librte_jobstats.so.1
+     librte_kni.so.2
+     librte_kvargs.so.1
+     librte_latencystats.so.1
+     librte_lpm.so.2
+     librte_mbuf.so.5
+     librte_member.so.1
+     librte_mempool.so.5
+     librte_meter.so.3
+     librte_metrics.so.1
+     librte_net.so.1
+     librte_pci.so.1
+     librte_pdump.so.3
+     librte_pipeline.so.3
+     librte_pmd_bnxt.so.2
+     librte_pmd_bond.so.2
+     librte_pmd_i40e.so.2
+     librte_pmd_ixgbe.so.2
+     librte_pmd_dpaa2_qdma.so.1
+     librte_pmd_ring.so.2
+     librte_pmd_softnic.so.1
+     librte_pmd_vhost.so.2
+     librte_port.so.3
+     librte_power.so.1
+     librte_rawdev.so.1
+     librte_rcu.so.1
+     librte_reorder.so.1
+     librte_ring.so.2
+     librte_sched.so.3
+     librte_security.so.2
+     librte_stack.so.1
+     librte_table.so.3
+     librte_timer.so.1
+     librte_vhost.so.4
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+   * **Add title in present tense with full stop.**
+
+     Add a short 1-2 sentence description of the known issue
+     in the present tense. Add information on any known workarounds.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested
+   with this release.
+
+   The format is:
+
+   * <vendor> platform with <vendor> <type of devices> combinations
+
+     * List of CPU
+     * List of OS
+     * List of devices
+     * Other relevant details...
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
-- 
1.8.3.1


^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [RFC] ethdev: support hairpin queue
  2019-09-05  4:00  3% ` Wu, Jingjing
@ 2019-09-05  5:44  0%   ` Ori Kam
  2019-09-06  3:08  0%     ` Wu, Jingjing
  0 siblings, 1 reply; 200+ results
From: Ori Kam @ 2019-09-05  5:44 UTC (permalink / raw)
  To: Wu, Jingjing, Thomas Monjalon, Yigit, Ferruh, arybchenko,
	Shahaf Shuler, Slava Ovsiienko, Alex Rosenbaum
  Cc: dev

Hi Wu, 
Thanks for your comments PSB,

Ori

> -----Original Message-----
> From: Wu, Jingjing <jingjing.wu@intel.com>
> Sent: Thursday, September 5, 2019 7:01 AM
> To: Ori Kam <orika@mellanox.com>; Thomas Monjalon
> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> arybchenko@solarflare.com; Shahaf Shuler <shahafs@mellanox.com>; Slava
> Ovsiienko <viacheslavo@mellanox.com>; Alex Rosenbaum
> <alexr@mellanox.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [RFC] ethdev: support hairpin queue
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ori Kam
> > Sent: Tuesday, August 13, 2019 9:38 PM
> > To: thomas@monjalon.net; Yigit, Ferruh <ferruh.yigit@intel.com>;
> > arybchenko@solarflare.com; shahafs@mellanox.com;
> viacheslavo@mellanox.com;
> > alexr@mellanox.com
> > Cc: dev@dpdk.org; orika@mellanox.com
> > Subject: [dpdk-dev] [RFC] ethdev: support hairpin queue
> >
> > This RFC replaces RFC[1].
> >
> > The hairpin feature (different name can be forward) acts as "bump on the
> wire",
> > meaning that a packet that is received from the wire can be modified using
> > offloaded action and then sent back to the wire without application
> intervention
> > which save CPU cycles.
> >
> > The hairpin is the inverse function of loopback in which application
> > sends a packet then it is received again by the
> > application without being sent to the wire.
> >
> > The hairpin can be used by a number of different NVF, for example load
> > balancer, gateway and so on.
> >
> > As can be seen from the hairpin description, hairpin is basically RX queue
> > connected to TX queue.
> >
> > During the design phase I was thinking of two ways to implement this
> > feature the first one is adding a new rte flow action. and the second
> > one is create a special kind of queue.
> >
> > The advantages of using the queue approch:
> > 1. More control for the application. queue depth (the memory size that
> > should be used).
> > 2. Enable QoS. QoS is normaly a parametr of queue, so in this approch it
> > will be easy to integrate with such system.
> 
> 
> Which kind of QoS?

For example latency , packet rate those kinds of makes sense in the queue level.
I know we don't have any current support but I think we will have during the next year.

> 
> > 3. Native integression with the rte flow API. Just setting the target
> > queue/rss to hairpin queue, will result that the traffic will be routed
> > to the hairpin queue.
> > 4. Enable queue offloading.
> >
> Looks like the hairpin queue is just hardware queue, it has no relationship with
> host memory. It makes the queue concept a little bit confusing. And why do we
> need to setup queues, maybe some info in eth_conf is enough?

Like stated above it makes sense to have queue related parameters.
For example I can think of application that most packets are going threw that hairpin queue, but some control packets are
from the application. So the application can configure the QoS between those two queues. In addtion this will enable the application
to use the queue like normal queue from rte_flow (see comment below) and every other aspect.
 
> 
> Not sure how your hardware make the hairpin work? Use rte_flow for packet
> modification offload? Then how does HW distribute packets to those hardware
> queue, classification? If So, why not just extend rte_flow with the hairpin
> action?
> 

You are correct, the application uses rte_flow and just points the traffic to the requested hairpin queue/rss.
We could have added a new rte_flow command. The reasons we didn't:
1. Like stated above some of the hairpin makes sense in queue level.
2.  In the near future, we will also want to support hairpin between different ports. This makes much more
sense using queues.
  
> > Each hairpin Rxq can be connected Txq / number of Txqs which can belong to
> a
> > different ports assuming the PMD supports it. The same goes the other
> > way each hairpin Txq can be connected to one or more Rxqs.
> > This is the reason that both the Txq setup and Rxq setup are getting the
> > hairpin configuration structure.
> >
> > From PMD prespctive the number of Rxq/Txq is the total of standard
> > queues + hairpin queues.
> >
> > To configure hairpin queue the user should call
> > rte_eth_rx_hairpin_queue_setup / rte_eth_tx_hairpin_queue_setup insteed
> > of the normal queue setup functions.
> 
> If the new API introduced to avoid ABI change, would one API
> rte_eth_rx_hairpin_setup be enough?

I'm not sure I understand your comment.
The rx_hairpin_setup was created for two main reasons:
1. Avoid API change.
2. I think it is more correct to use different API since the parameters are different.

The reason we have both rx and tx setup functions is that we want the user to have control binding the two queues.
It is most important when we will advance to hairpin between ports.

> 
> Thanks
> Jingjing

Thanks,
Ori

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] ethdev: support hairpin queue
  @ 2019-09-05  4:00  3% ` Wu, Jingjing
  2019-09-05  5:44  0%   ` Ori Kam
  0 siblings, 1 reply; 200+ results
From: Wu, Jingjing @ 2019-09-05  4:00 UTC (permalink / raw)
  To: Ori Kam, thomas, Yigit, Ferruh, arybchenko, shahafs, viacheslavo, alexr
  Cc: dev


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ori Kam
> Sent: Tuesday, August 13, 2019 9:38 PM
> To: thomas@monjalon.net; Yigit, Ferruh <ferruh.yigit@intel.com>;
> arybchenko@solarflare.com; shahafs@mellanox.com; viacheslavo@mellanox.com;
> alexr@mellanox.com
> Cc: dev@dpdk.org; orika@mellanox.com
> Subject: [dpdk-dev] [RFC] ethdev: support hairpin queue
> 
> This RFC replaces RFC[1].
> 
> The hairpin feature (different name can be forward) acts as "bump on the wire",
> meaning that a packet that is received from the wire can be modified using
> offloaded action and then sent back to the wire without application intervention
> which save CPU cycles.
> 
> The hairpin is the inverse function of loopback in which application
> sends a packet then it is received again by the
> application without being sent to the wire.
> 
> The hairpin can be used by a number of different NVF, for example load
> balancer, gateway and so on.
> 
> As can be seen from the hairpin description, hairpin is basically RX queue
> connected to TX queue.
> 
> During the design phase I was thinking of two ways to implement this
> feature the first one is adding a new rte flow action. and the second
> one is create a special kind of queue.
> 
> The advantages of using the queue approch:
> 1. More control for the application. queue depth (the memory size that
> should be used).
> 2. Enable QoS. QoS is normaly a parametr of queue, so in this approch it
> will be easy to integrate with such system.


Which kind of QoS?

> 3. Native integression with the rte flow API. Just setting the target
> queue/rss to hairpin queue, will result that the traffic will be routed
> to the hairpin queue.
> 4. Enable queue offloading.
> 
Looks like the hairpin queue is just hardware queue, it has no relationship with host memory. It makes the queue concept a little bit confusing. And why do we need to setup queues, maybe some info in eth_conf is enough?

Not sure how your hardware make the hairpin work? Use rte_flow for packet modification offload? Then how does HW distribute packets to those hardware queue, classification? If So, why not just extend rte_flow with the hairpin action?

> Each hairpin Rxq can be connected Txq / number of Txqs which can belong to a
> different ports assuming the PMD supports it. The same goes the other
> way each hairpin Txq can be connected to one or more Rxqs.
> This is the reason that both the Txq setup and Rxq setup are getting the
> hairpin configuration structure.
> 
> From PMD prespctive the number of Rxq/Txq is the total of standard
> queues + hairpin queues.
> 
> To configure hairpin queue the user should call
> rte_eth_rx_hairpin_queue_setup / rte_eth_tx_hairpin_queue_setup insteed
> of the normal queue setup functions.

If the new API introduced to avoid ABI change, would one API rte_eth_rx_hairpin_setup be enough?

Thanks
Jingjing

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 02/11] log: define logtype register wrapper for drivers
  2019-09-03  8:47  3%       ` Ferruh Yigit
@ 2019-09-04 17:45  0%         ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-09-04 17:45 UTC (permalink / raw)
  To: Ferruh Yigit, David Marchand; +Cc: dev

03/09/2019 10:47, Ferruh Yigit:
> On 9/3/2019 9:06 AM, David Marchand wrote:
> > On Mon, Sep 2, 2019 at 4:29 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> >> On 8/19/2019 12:41 PM, David Marchand wrote:
> >>> The function rte_log_register_type_and_pick_level() fills a gap for
> >>> dynamically loaded code (especially drivers) who would not pick up
> >>> the log level passed at startup.
> >>>
> >>> Let's promote it to stable and export it for use by drivers via
> >>> a wrapper.
> >>>
> >>> Signed-off-by: David Marchand <david.marchand@redhat.com>
> >>> ---
[...]
> >>>  /**
> >>> - * @warning
> >>> - * @b EXPERIMENTAL: this API may change without prior notice
> >>> - *
> >>>   * Register a dynamic log type and try to pick its level from EAL options
[...]
> >>> -__rte_experimental
> >>>  int rte_log_register_type_and_pick_level(const char *name, uint32_t level_def);
> >>
> >> +1 to remove experimental from the API.

I am not sure about this function API.
Why we combined register and level setting in one function?

> >>> +#define RTE_LOG_REGISTER(token, name, level, fallback) \

You really need to document this macro with doxygen.

> >>> +{ \
> >>> +     token = rte_log_register_type_and_pick_level(name, level); \
> >>> +     if (token < 0) \
> >>
> >> The failure can be because component can try to register existing log name, or
> >> there is no enough memory, do you think does it worth to do log, or some
> >> additional work if component is trying to register existing log name?
[...]
> >>> +             token = fallback; \
> >>
> >> Does the 'fallback' needs to be provided by user, it looks like everyone will
> >> just copy/paste 'RTE_LOGTYPE_PMD' for drivers, and does it really needs to be
> >> configurable since it is fallback.
> > 
> > This series only touches drivers, but I expected other components
> > would use this macro later.
> > I can add a RTE_PMD_REGISTER_LOG macro that hides the RTE_LOGTYPE_PMD
> > fallback value.

I agree we don't need to configure the fallback log.
If there is an error during log setup,
we can log everything next (at debug level).
Let's make fallback hardcoded.

> >> Why not provide a hardcoded type for the failure case? And for that case perhaps
> >> create a more generic logtype, something like "RTE_LOGTYPE_FALLBACK" so that it
> >> can be as it is from all components?
> > 
> > I prefer to map all drivers to a logtype that means something, like
> > RTE_LOGTYPE_PMD.
> 
> In that manner it make sense agreed, but previously drivers were using
> 'RTE_LOGTYPE_PMD' instead of having their own log types, Stephen did some work
> to replace the 'RTE_LOGTYPE_PMD' so that it can be deprecated,
> 
> starting to use it again as fallback may lead drivers using it again as log type
> in their drivers, may they wouldn't but this is what I concern. Something with
> name 'RTE_LOGTYPE_FALLBACK' clear to not use as default logtype in drivers.
> 
> > Having a "fallback" could be used for all components, but this would
> > have to be a static logtype and adding one is not possible without
> > breaking the abi (static entries are < 32 and all values are used).

RTE_LOGTYPE_PMD can be renamed to RTE_LOGTYPE_FALLBACK.

> There is a gap between 'RTE_LOGTYPE_GSO' & 'RTE_LOGTYPE_USER1' ...

Yes, there is room here. But I prefer to rename and re-use
RTE_LOGTYPE_PMD which is not used anymore.
It is part of the EAL API but it is not supposed to be used externally.
For out-of-tree PMDs, we are not supposed to provide such compat.
So I would say don't care with deprecation here.



^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v2 02/54] ethdev: change rte_eth_dev_info_get() return value to int
  @ 2019-09-03 13:56  3%   ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-09-03 13:56 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Thomas Monjalon,
	Ferruh Yigit
  Cc: dev, Ivan Ilchenko

From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>

Change rte_eth_dev_info_get() return value from void to int and return
negative errno values in case of error conditions.
Modify rte_eth_dev_info_get() usage across the ethdev according
to new return type.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst   |  1 -
 doc/guides/rel_notes/release_19_11.rst |  5 ++-
 lib/librte_ethdev/rte_ethdev.c         | 71 ++++++++++++++++++++++++----------
 lib/librte_ethdev/rte_ethdev.h         |  6 ++-
 4 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 0ee8533..cbb4c34 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_dev_info_get``
   - ``rte_eth_promiscuous_enable`` and ``rte_eth_promiscuous_disable``
   - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 27cfbd9..152f120 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -94,6 +94,9 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void`` to
+  ``int`` to provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
@@ -145,7 +148,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_distributor.so.1
      librte_eal.so.11
      librte_efd.so.1
-     librte_ethdev.so.12
+   + librte_ethdev.so.13
      librte_eventdev.so.7
      librte_flow_classify.so.1
      librte_gro.so.1
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e..4b6cbe2 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1125,7 +1125,6 @@ struct rte_eth_dev *
 
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -1144,7 +1143,9 @@ struct rte_eth_dev *
 	 */
 	memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf));
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* If number of queues specified by application for both Rx and Tx is
 	 * zero, use driver preferred values. This cannot be done individually
@@ -1406,6 +1407,7 @@ struct rte_eth_dev *
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
 	int diag;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1420,7 +1422,9 @@ struct rte_eth_dev *
 		return 0;
 	}
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* Lets restore MAC now if device does not support live change */
 	if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)
@@ -1584,7 +1588,6 @@ struct rte_eth_dev *
 		return -EINVAL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP);
 
 	/*
@@ -1592,7 +1595,10 @@ struct rte_eth_dev *
 	 * This value must be provided in the private data of the memory pool.
 	 * First check that the memory pool has a valid private data.
 	 */
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
 		RTE_ETHDEV_LOG(ERR, "%s private_data_size %d < %d\n",
 			mp->name, (int)mp->private_data_size,
@@ -1703,6 +1709,7 @@ struct rte_eth_dev *
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_txconf local_conf;
 	void **txq;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1712,10 +1719,11 @@ struct rte_eth_dev *
 		return -EINVAL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP);
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* Use default specified by driver, if nb_tx_desc is zero */
 	if (nb_tx_desc == 0) {
@@ -2540,7 +2548,7 @@ struct rte_eth_dev *
 							fw_version, fw_size));
 }
 
-void
+int
 rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 {
 	struct rte_eth_dev *dev;
@@ -2558,7 +2566,7 @@ struct rte_eth_dev *
 	 */
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	dev_info->rx_desc_lim = lim;
@@ -2567,13 +2575,15 @@ struct rte_eth_dev *
 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
 	dev_info->max_mtu = UINT16_MAX;
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
 
 	dev_info->dev_flags = &dev->data->dev_flags;
+
+	return 0;
 }
 
 int
@@ -2643,7 +2653,10 @@ struct rte_eth_dev *
 	 * which relies on dev->dev_ops->dev_infos_get.
 	 */
 	if (*dev->dev_ops->dev_infos_get != NULL) {
-		rte_eth_dev_info_get(port_id, &dev_info);
+		ret = rte_eth_dev_info_get(port_id, &dev_info);
+		if (ret != 0)
+			return ret;
+
 		if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
 			return -EINVAL;
 	}
@@ -2991,10 +3004,15 @@ struct rte_eth_dev *
 {
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	dev = &rte_eth_devices[port_id];
-	rte_eth_dev_info_get(port_id, &dev_info);
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3100,9 +3118,13 @@ struct rte_eth_dev *
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	unsigned i;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	rte_eth_dev_info_get(port_id, &dev_info);
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	for (i = 0; i < dev_info.max_mac_addrs; i++)
 		if (memcmp(addr, &dev->data->mac_addrs[i],
@@ -3233,8 +3255,14 @@ struct rte_eth_dev *
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	unsigned i;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
-	rte_eth_dev_info_get(port_id, &dev_info);
 	if (!dev->data->hash_mac_addrs)
 		return -1;
 
@@ -3319,11 +3347,15 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_link link;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	dev = &rte_eth_devices[port_id];
-	rte_eth_dev_info_get(port_id, &dev_info);
 	link = dev->data->dev_link;
 
 	if (queue_idx > dev_info.max_tx_queues) {
@@ -4363,15 +4395,14 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
 				 uint16_t *nb_rx_desc,
 				 uint16_t *nb_tx_desc)
 {
-	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
-	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
-
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	if (nb_rx_desc != NULL)
 		rte_eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim);
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 8fa89bf..eda9e5c 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2366,8 +2366,12 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @param dev_info
  *   A pointer to a structure of type *rte_eth_dev_info* to be filled with
  *   the contextual information of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
+int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
  * Retrieve the firmware version of a device.
-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 02/11] log: define logtype register wrapper for drivers
  2019-09-03  8:06  4%     ` David Marchand
@ 2019-09-03  8:47  3%       ` Ferruh Yigit
  2019-09-04 17:45  0%         ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-09-03  8:47 UTC (permalink / raw)
  To: David Marchand; +Cc: dev

On 9/3/2019 9:06 AM, David Marchand wrote:
> On Mon, Sep 2, 2019 at 4:29 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>> On 8/19/2019 12:41 PM, David Marchand wrote:
>>> The function rte_log_register_type_and_pick_level() fills a gap for
>>> dynamically loaded code (especially drivers) who would not pick up
>>> the log level passed at startup.
>>>
>>> Let's promote it to stable and export it for use by drivers via
>>> a wrapper.
>>>
>>> Signed-off-by: David Marchand <david.marchand@redhat.com>
>>> ---
>>>  lib/librte_eal/common/include/rte_log.h | 12 ++++++++----
>>>  lib/librte_eal/rte_eal_version.map      |  8 +++++++-
>>>  2 files changed, 15 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
>>> index cbb4184..c3aff00 100644
>>> --- a/lib/librte_eal/common/include/rte_log.h
>>> +++ b/lib/librte_eal/common/include/rte_log.h
>>> @@ -209,9 +209,6 @@ int rte_log_cur_msg_logtype(void);
>>>  int rte_log_register(const char *name);
>>>
>>>  /**
>>> - * @warning
>>> - * @b EXPERIMENTAL: this API may change without prior notice
>>> - *
>>>   * Register a dynamic log type and try to pick its level from EAL options
>>>   *
>>>   * rte_log_register() is called inside. If successful, the function tries
>>> @@ -227,9 +224,16 @@ int rte_log_register(const char *name);
>>>   *    - >=0: the newly registered log type
>>>   *    - <0: rte_log_register() error value
>>>   */
>>> -__rte_experimental
>>>  int rte_log_register_type_and_pick_level(const char *name, uint32_t level_def);
>>
>> +1 to remove experimental from the API.
>>
>>>
>>> +#define RTE_LOG_REGISTER(token, name, level, fallback) \
>>> +RTE_INIT(token##_init) \
>>
>> Does it still need to be an init time call?
>> Since it is dynamic now it can be during probe, even log name can be a paramter
>> to the "struct rte_driver" and log can be registered automatically during probe,
>> not sure how complex it becomes.
> 
> This would not work with non driver components built as shared
> libraries (unless they have an explicit init symbol in the dpdk init
> flow).

Right.

> 
> The drivers can register multiple log types so this would have to be handled.
> We would touch the struct rte_driver which is embedded in other
> objects like rte_pci_driver, breaking the abi.

Yes they may require multiple logs, +abi break, so forget about it.

> 
> 
>>
>>> +{ \
>>> +     token = rte_log_register_type_and_pick_level(name, level); \
>>> +     if (token < 0) \
>>
>> The failure can be because component can try to register existing log name, or
>> there is no enough memory, do you think does it worth to do log, or some
>> additional work if component is trying to register existing log name?
> 
> Yes, I can raise a warning log (using RTE_LOGTYPE_EAL type), since
> duplicates are not supposed to happen.

I was checking if we can detect the error from duplication, there can be a
defect it that logic:

Call trace is:

rte_log_register_type_and_pick_level
    type = rte_log_register(name);
        id = rte_log_lookup(name);
        if (id >= 0)
            return id
    if (type < 0)
        return type

"type > 0" for the duplication case but error check only checks if "type < 0"


> 
> 
>>
>>> +             token = fallback; \
>>
>> Does the 'fallback' needs to be provided by user, it looks like everyone will
>> just copy/paste 'RTE_LOGTYPE_PMD' for drivers, and does it really needs to be
>> configurable since it is fallback.
> 
> This series only touches drivers, but I expected other components
> would use this macro later.
> I can add a RTE_PMD_REGISTER_LOG macro that hides the RTE_LOGTYPE_PMD
> fallback value.
> 
> 
>>
>> Why not provide a hardcoded type for the failure case? And for that case perhaps
>> create a more generic logtype, something like "RTE_LOGTYPE_FALLBACK" so that it
>> can be as it is from all components?
>>
> 
> I prefer to map all drivers to a logtype that means something, like
> RTE_LOGTYPE_PMD.

In that manner it make sense agreed, but previously drivers were using
'RTE_LOGTYPE_PMD' instead of having their own log types, Stephen did some work
to replace the 'RTE_LOGTYPE_PMD' so that it can be deprecated,

starting to use it again as fallback may lead drivers using it again as log type
in their drivers, may they wouldn't but this is what I concern. Something with
name 'RTE_LOGTYPE_FALLBACK' clear to not use as default logtype in drivers.

> 
> Having a "fallback" could be used for all components, but this would
> have to be a static logtype and adding one is not possible without
> breaking the abi (static entries are < 32 and all values are used).

There is a gap between 'RTE_LOGTYPE_GSO' & 'RTE_LOGTYPE_USER1' ...

> 
> 
> --
> David Marchand
> 


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 02/11] log: define logtype register wrapper for drivers
  @ 2019-09-03  8:06  4%     ` David Marchand
  2019-09-03  8:47  3%       ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2019-09-03  8:06 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev

On Mon, Sep 2, 2019 at 4:29 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
> On 8/19/2019 12:41 PM, David Marchand wrote:
> > The function rte_log_register_type_and_pick_level() fills a gap for
> > dynamically loaded code (especially drivers) who would not pick up
> > the log level passed at startup.
> >
> > Let's promote it to stable and export it for use by drivers via
> > a wrapper.
> >
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
> > ---
> >  lib/librte_eal/common/include/rte_log.h | 12 ++++++++----
> >  lib/librte_eal/rte_eal_version.map      |  8 +++++++-
> >  2 files changed, 15 insertions(+), 5 deletions(-)
> >
> > diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
> > index cbb4184..c3aff00 100644
> > --- a/lib/librte_eal/common/include/rte_log.h
> > +++ b/lib/librte_eal/common/include/rte_log.h
> > @@ -209,9 +209,6 @@ int rte_log_cur_msg_logtype(void);
> >  int rte_log_register(const char *name);
> >
> >  /**
> > - * @warning
> > - * @b EXPERIMENTAL: this API may change without prior notice
> > - *
> >   * Register a dynamic log type and try to pick its level from EAL options
> >   *
> >   * rte_log_register() is called inside. If successful, the function tries
> > @@ -227,9 +224,16 @@ int rte_log_register(const char *name);
> >   *    - >=0: the newly registered log type
> >   *    - <0: rte_log_register() error value
> >   */
> > -__rte_experimental
> >  int rte_log_register_type_and_pick_level(const char *name, uint32_t level_def);
>
> +1 to remove experimental from the API.
>
> >
> > +#define RTE_LOG_REGISTER(token, name, level, fallback) \
> > +RTE_INIT(token##_init) \
>
> Does it still need to be an init time call?
> Since it is dynamic now it can be during probe, even log name can be a paramter
> to the "struct rte_driver" and log can be registered automatically during probe,
> not sure how complex it becomes.

This would not work with non driver components built as shared
libraries (unless they have an explicit init symbol in the dpdk init
flow).

The drivers can register multiple log types so this would have to be handled.
We would touch the struct rte_driver which is embedded in other
objects like rte_pci_driver, breaking the abi.


>
> > +{ \
> > +     token = rte_log_register_type_and_pick_level(name, level); \
> > +     if (token < 0) \
>
> The failure can be because component can try to register existing log name, or
> there is no enough memory, do you think does it worth to do log, or some
> additional work if component is trying to register existing log name?

Yes, I can raise a warning log (using RTE_LOGTYPE_EAL type), since
duplicates are not supposed to happen.


>
> > +             token = fallback; \
>
> Does the 'fallback' needs to be provided by user, it looks like everyone will
> just copy/paste 'RTE_LOGTYPE_PMD' for drivers, and does it really needs to be
> configurable since it is fallback.

This series only touches drivers, but I expected other components
would use this macro later.
I can add a RTE_PMD_REGISTER_LOG macro that hides the RTE_LOGTYPE_PMD
fallback value.


>
> Why not provide a hardcoded type for the failure case? And for that case perhaps
> create a more generic logtype, something like "RTE_LOGTYPE_FALLBACK" so that it
> can be as it is from all components?
>

I prefer to map all drivers to a logtype that means something, like
RTE_LOGTYPE_PMD.

Having a "fallback" could be used for all components, but this would
have to be a static logtype and adding one is not possible without
breaking the abi (static entries are < 32 and all values are used).


--
David Marchand

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH 04/15] net/virtio: add virtio PCI subsystem device ID declaration
  2019-09-02  6:14  0%   ` Tiwei Bie
@ 2019-09-03  7:25  0%     ` Maxime Coquelin
  0 siblings, 0 replies; 200+ results
From: Maxime Coquelin @ 2019-09-03  7:25 UTC (permalink / raw)
  To: Tiwei Bie; +Cc: zhihong.wang, amorenoz, xiao.w.wang, dev, jfreimann, stable



On 9/2/19 8:14 AM, Tiwei Bie wrote:
> On Thu, Aug 29, 2019 at 09:59:49AM +0200, Maxime Coquelin wrote:
>> The Virtio PCI susbsytem IDs need to be specified to
>> prevent it to probe IFC vDPA VFs.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_pci.h | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
>> index a38cb45ad..56f89a454 100644
>> --- a/drivers/net/virtio/virtio_pci.h
>> +++ b/drivers/net/virtio/virtio_pci.h
>> @@ -19,6 +19,7 @@ struct virtnet_ctl;
>>  #define VIRTIO_PCI_VENDORID     0x1AF4
>>  #define VIRTIO_PCI_LEGACY_DEVICEID_NET 0x1000
>>  #define VIRTIO_PCI_MODERN_DEVICEID_NET 0x1041
>> +#define VIRTIO_PCI_SUBSY_DEVICEID_NET 0x1100
> 
> 0x1100 is the subsystem device ID used by QEMU.
> Maybe naming it VIRTIO_PCI_SUBSYS_DEVICEID_QEMU is better?

Indeed, will do.

Thanks,
Maxime

> Regards,
> Tiwei
> 
>>  
>>  /* VirtIO ABI version, this must match exactly. */
>>  #define VIRTIO_PCI_ABI_VERSION 0
>> -- 
>> 2.21.0
>>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 04/15] net/virtio: add virtio PCI subsystem device ID declaration
  2019-08-29  7:59  4% ` [dpdk-dev] [PATCH 04/15] net/virtio: add virtio PCI subsystem device ID declaration Maxime Coquelin
@ 2019-09-02  6:14  0%   ` Tiwei Bie
  2019-09-03  7:25  0%     ` Maxime Coquelin
  0 siblings, 1 reply; 200+ results
From: Tiwei Bie @ 2019-09-02  6:14 UTC (permalink / raw)
  To: Maxime Coquelin
  Cc: zhihong.wang, amorenoz, xiao.w.wang, dev, jfreimann, stable

On Thu, Aug 29, 2019 at 09:59:49AM +0200, Maxime Coquelin wrote:
> The Virtio PCI susbsytem IDs need to be specified to
> prevent it to probe IFC vDPA VFs.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_pci.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
> index a38cb45ad..56f89a454 100644
> --- a/drivers/net/virtio/virtio_pci.h
> +++ b/drivers/net/virtio/virtio_pci.h
> @@ -19,6 +19,7 @@ struct virtnet_ctl;
>  #define VIRTIO_PCI_VENDORID     0x1AF4
>  #define VIRTIO_PCI_LEGACY_DEVICEID_NET 0x1000
>  #define VIRTIO_PCI_MODERN_DEVICEID_NET 0x1041
> +#define VIRTIO_PCI_SUBSY_DEVICEID_NET 0x1100

0x1100 is the subsystem device ID used by QEMU.
Maybe naming it VIRTIO_PCI_SUBSYS_DEVICEID_QEMU is better?

Regards,
Tiwei

>  
>  /* VirtIO ABI version, this must match exactly. */
>  #define VIRTIO_PCI_ABI_VERSION 0
> -- 
> 2.21.0
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3 2/4] doc: changes to abi policy introducing major abi versions
  2019-08-15 10:23 31% ` [dpdk-dev] [PATCH v3 2/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
@ 2019-08-30 16:20 10%   ` Kevin Traynor
  0 siblings, 0 replies; 200+ results
From: Kevin Traynor @ 2019-08-30 16:20 UTC (permalink / raw)
  To: Ray Kinsella, dev
  Cc: thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, john.mcnamara, marko.kovacevic, hemant.agrawal,
	Luca Boccassi, David Marchand

Hi Ray,

On 15/08/2019 11:23, Ray Kinsella wrote:
> This policy change introduces major ABI versions, these are
> declared every year, typically aligned with the LTS release
> and are supported by subsequent releases in the following year.
> This change is intended to improve ABI stabilty for those projects
> consuming DPDK.
> 
> Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
> ---
>  doc/guides/contributing/abi_policy.rst | 308 ++++++++++++++++++++++++---------
>  doc/guides/contributing/stable.rst     |  38 ++--
>  2 files changed, 245 insertions(+), 101 deletions(-)
> 
> diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
> index 55bacb4..6190bdc 100644
> --- a/doc/guides/contributing/abi_policy.rst
> +++ b/doc/guides/contributing/abi_policy.rst
> @@ -1,33 +1,46 @@
>  ..  SPDX-License-Identifier: BSD-3-Clause
> -    Copyright 2018 The DPDK contributors
> +    Copyright 2019 The DPDK contributors
>  
> -.. abi_api_policy:
> +.. _abi_policy:
>  
> -DPDK ABI/API policy
> -===================
> +ABI Policy
> +==========
>  
>  Description
>  -----------
>  
> -This document details some methods for handling ABI management in the DPDK.
> +This document details the management policy that ensures the long-term stability
> +of the DPDK ABI and API.
>  
>  General Guidelines
>  ------------------
>  
> -#. Whenever possible, ABI should be preserved
> -#. ABI/API may be changed with a deprecation process
> -#. The modification of symbols can generally be managed with versioning
> -#. Libraries or APIs marked in ``experimental`` state may change without constraint
> -#. New APIs will be marked as ``experimental`` for at least one release to allow
> -   any issues found by users of the new API to be fixed quickly
> -#. The addition of symbols is generally not problematic
> -#. The removal of symbols generally is an ABI break and requires bumping of the
> -   LIBABIVER macro
> -#. Updates to the minimum hardware requirements, which drop support for hardware which
> -   was previously supported, should be treated as an ABI change.
> -
> -What is an ABI
> -~~~~~~~~~~~~~~
> +#. Major ABI versions are declared every **year** and are then supported for one
> +   year, typically aligned with the :ref:`LTS release <stable_lts_releases>`.
> +#. The ABI version is managed at a project level in DPDK, with the ABI version
> +   reflected in all :ref:`library's soname <what_is_soname>`.
> +#. The ABI should be preserved and not changed lightly. ABI changes must follow
> +   the outlined :ref:`deprecation process <abi_changes>`.
> +#. The addition of symbols is generally not problematic. The modification of
> +   symbols is managed with :ref:`ABI Versioning <abi_versioning>`.
> +#. The removal of symbols is considered an :ref:`ABI breakage <abi_breakages>`,
> +   once approved these will form part of the next ABI version.
> +#. Libraries or APIs marked as :ref:`Experimental <experimental_apis>` are not
> +   considered part of an ABI version and may change without constraint.
> +#. Updates to the :ref:`minimum hardware requirements <hw_rqmts>`, which drop
> +   support for hardware which was previously supported, should be treated as an
> +   ABI change.
> +
> +.. note::
> +
> +   In 2019, the DPDK community stated it's intention to move to ABI stable
> +   releases, over a number of release cycles. Beginning with maintaining ABI
> +   stability through one year of DPDK releases starting from DPDK 19.11. This
> +   policy will be reviewed in 2020, with intention of lengthening the stability
> +   period.
> +
> +What is an ABI?
> +~~~~~~~~~~~~~~~
>  
>  An ABI (Application Binary Interface) is the set of runtime interfaces exposed
>  by a library. It is similar to an API (Application Programming Interface) but
> @@ -39,30 +52,67 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
>  preserved, or (when modified), done in such a way that the application is unable
>  to behave improperly or in an unexpected fashion.
>  
> +What is an ABI version?
> +~~~~~~~~~~~~~~~~~~~~~~~
>  
> -ABI/API Deprecation
> --------------------
> +An ABI version is an instance of a library's ABI at a specific release. Certain
> +releases are considered by the community to be milestone releases, the yearly
> +LTS for example. Supporting those milestone release's ABI for some number of
> +subsequent releases is desirable to facilitate application upgrade. Those ABI
> +version's aligned with milestones release are therefore called 'ABI major
> +versions' and are supported for some number of releases.
> +
> +More details on major ABI version can be found in the :ref:`ABI versioning
> +<major_abi_versions>` guide.
>  
>  The DPDK ABI policy
> -~~~~~~~~~~~~~~~~~~~
> +-------------------
> +
> +A major ABI version is declared every year, aligned with that year's LTS
> +release, e.g. v19.11. This ABI version is then supported for one year by all
> +subsequent releases within that time period, until the next LTS release, e.g.
> +v20.11.
> +
> +At the declaration of a major ABI version, major version numbers encoded in
> +libraries soname's are bumped to indicate the new version, with the minor
> +version reset to ``0``. An example would be ``librte_eal.so.20.3`` would become
> +``librte_eal.so.21.0``.
> +
> +The ABI may then change multiple times, without warning, between the last major
> +ABI version increment and the HEAD label of the git tree, with the condition
> +that ABI compatibility with the major ABI version is preserved and therefore
> +soname's do not change.
> +
> +Minor versions are incremented to indicate the release of a new ABI compatible
> +DPDK release, typically the DPDK quarterly releases. An example of this, might
> +be that ``librte_eal.so.20.1`` would indicate the first ABI compatible DPDK
> +release, following the declaration of the new major ABI version ``20``.
> +
> +ABI versions, are supported by each release until such time as the next major
> +ABI version is declared. At that time, the deprecation of the previous major ABI
> +version will be noted in the Release Notes with guidance on individual symbol
> +depreciation and upgrade notes provided.
>  
> -ABI versions are set at the time of major release labeling, and the ABI may
> -change multiple times, without warning, between the last release label and the
> -HEAD label of the git tree.
> +.. _abi_changes:
>  
> -ABI versions, once released, are available until such time as their
> -deprecation has been noted in the Release Notes for at least one major release
> -cycle. For example consider the case where the ABI for DPDK 2.0 has been
> -shipped and then a decision is made to modify it during the development of
> -DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
> -release and the modification will be made available in the DPDK 2.2 release.
> +ABI Changes
> +~~~~~~~~~~~
>  
> -ABI versions may be deprecated in whole or in part as needed by a given
> -update.
> +The ABI may still change after the declaration of a major ABI version, that is
> +new APIs may be still added or existing APIs may be modified.
>  
> -Some ABI changes may be too significant to reasonably maintain multiple
> -versions. In those cases ABI's may be updated without backward compatibility
> -being provided. The requirements for doing so are:
> +.. Warning::
> +
> +   Note that, the process for ABI deprecation should not be undertaken lightly.
> +   ABI stability is extremely important for downstream consumers of the DPDK,

> +   especially when distributed in shared object form. Every effort should be
> +   made to preserve the ABI whenever possible. The ABI should only be changed
> +   for significant reasons, such as performance enhancements. ABI breakage due
> +   to changes such as reorganizing public structure fields for aesthetic or
> +   readability purposes should be avoided.
> +

This text is not changed and it reads like *any* performance enhancement
is a good enough reason for an ABI break. Can't obviously quantify it,
but maybe "major performance enhancement" is closer to the intended
tone? Sorry for nit-picking over one word!

> +
> +The requirements for changing the ABI are:
>  
>  #. At least 3 acknowledgments of the need to do so must be made on the
>     dpdk.org mailing list.
> @@ -71,34 +121,119 @@ being provided. The requirements for doing so are:
>       no maintainer is available for the component, the tree/sub-tree maintainer
>       for that component must acknowledge the ABI change instead.
>  
> +   - The acknowledgment of a member of the technical board, as a delegate of the
> +     `technical board <https://core.dpdk.org/techboard/>`_ acknowledging the
> +     need for the ABI change, is also mandatory.
> +
>     - It is also recommended that acknowledgments from different "areas of
>       interest" be sought for each deprecation, for example: from NIC vendors,
>       CPU vendors, end-users, etc.
>  
> -#. The changes (including an alternative map file) can be included with
> -   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
> -   to provide more details about oncoming changes.
> -   ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
> -   More preferred way to provide this information is sending the feature
> -   as a separate patch and reference it in deprecation notice.
> +#. Backward compatibly with the major ABI version must be maintained through

s/compatibly/compatibility/

> +   :ref:`abi_versioning`, with :ref:`forward-only <forward-only>` compatibility
> +   offered for any ABI changes that are indicated to be part of the next ABI
> +   version.
>  
> -#. A full deprecation cycle, as explained above, must be made to offer
> -   downstream consumers sufficient warning of the change.
> +   - In situations were backward compatibility is not possible, read the

s/were/where/

> +     section on :ref:`abi_breakages`.
>  
> -Note that the above process for ABI deprecation should not be undertaken
> -lightly. ABI stability is extremely important for downstream consumers of the
> -DPDK, especially when distributed in shared object form. Every effort should
> -be made to preserve the ABI whenever possible. The ABI should only be changed
> -for significant reasons, such as performance enhancements. ABI breakage due to
> -changes such as reorganizing public structure fields for aesthetic or
> -readability purposes should be avoided.
> +   - No backward or forward compatibility is offered for API changes marked as
> +     ``experimental``, as described in the section on :ref:`Experimental APIs
> +     and Libraries <experimental_apis>`.
>  
> -.. note::
> +#. If a newly proposed API functionally replaces an existing one, when the new
> +   API becomes non-experimental, then the old one is marked with
> +   ``__rte_deprecated``.
> +
> +    - The depreciated API should follow the notification process to be removed,
> +      see  :ref:`deprecation_notices`.
> +
> +    - At the declaration of the next major ABI version, those ABI changes then
> +      become a formal part of the new ABI and the requirement to preserve ABI
> +      compatibility with the last major ABI version is then dropped.
> +
> +    - The responsibility for removing redundant ABI compatibility code rests
> +      with the original contributor of the ABI changes, failing that, then with
> +      the contributor's company and then finally with the maintainer.
> +
> +.. _forward-only:
> +
> +.. Note::
> +
> +   Note that forward-only compatibility is offered for those changes made
> +   between major ABI versions. As a library's soname can only describe
> +   compatibility with the last major ABI version, until the next major ABI
> +   version is declared, these changes therefore cannot be resolved as a runtime
> +   dependency through the soname. Therefore any application wishing to make use
> +   of these ABI changes can only ensure that it's runtime dependencies are met
> +   through Operating System package versioning.
> +
> +.. _hw_rqmts:
> +
> +.. Note::
>  
>     Updates to the minimum hardware requirements, which drop support for hardware
>     which was previously supported, should be treated as an ABI change, and
> -   follow the relevant deprecation policy procedures as above: 3 acks and
> -   announcement at least one release in advance.
> +   follow the relevant deprecation policy procedures as above: 3 acks, technical
> +   board approval and announcement at least one release in advance.
> +
> +.. _abi_breakages:
> +
> +ABI Breakages
> +~~~~~~~~~~~~~
> +
> +For those ABI changes that are too significant to reasonably maintain multiple
> +symbol versions, there is an amended process. In these cases, ABIs may be
> +updated without the requirement of backward compatibility being provided. These
> +changes must follow the `same process :ref:`described above <abi_changes>` as non-breaking
> +changes, however with the following additional requirements:
> +
> +#. ABI breaking changes (including an alternative map file) can be included with
> +   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option, to provide
> +   more details about oncoming changes. ``RTE_NEXT_ABI`` wrapper will be removed
> +   at the declaration of the next major ABI version.
> +
> +#. Once approved, and after the depreciation notice has been observed these
> +   changes will form part of the next declared major ABI version.
> +
> +Examples of ABI Changes
> +~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The following are examples of allowable ABI changes occurring between
> +declarations of major ABI versions.
> +
> +* DPDK 19.11 release, defines the function ``rte_foo()``, and ``rte_foo()``
> +  as part of the major ABI version ``20``.
> +
> +* DPDK 20.02 release defines a new function ``rte_foo(uint8_t bar)``, and
> +  this is not a problem as long as the symbol ``rte_foo@DPDK20`` is
> +  preserved through :ref:`abi_versioning`.
> +
> +  - The new function may be marked with the ``__rte_experimental`` tag for a
> +    number of releases, as described in the section :ref:`experimental_apis`.
> +
> +  - Once ``rte_foo(uint8_t bar)`` becomes non-experimental ``rte_foo()`` is then
> +    declared as ``__rte_depreciated``, with an associated deprecation notice
> +    provided.
> +
> +* DPDK 19.11 is not re-released to include ``rte_foo(uint8_t bar)``, the new
> +  version of ``rte_foo`` only exists from DPDK 20.02 onwards as described in the
> +  :ref:`note on forward-only compatibility<forward-only>`.
> +
> +* DPDK 20.02 release defines the experimental function ``__rte_experimental
> +  rte_baz()``. This function may or may not exist in the DPDK 20.05 release.
> +
> +* An application ``dPacket`` wishes to use ``rte_foo(uint8_t bar)``, before the
> +  declaration of the DPDK ``21`` major API version. The application can only
> +  ensure it's runtime dependencies are met by specifying ``DPDK (>= 20.2)`` as
> +  an explicit package dependency, as the soname only may only indicate the
> +  supported major ABI version.
> +
> +* At the release of DPDK 20.11, the function ``rte_foo(uint8_t bar)`` becomes
> +  formally part of then new major ABI version DPDK 21.0 and ``rte_foo()`` may be
> +  removed.
> +
> +.. _deprecation_notices:
>  
>  Examples of Deprecation Notices
>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> @@ -106,46 +241,42 @@ Examples of Deprecation Notices
>  The following are some examples of ABI deprecation notices which would be
>  added to the Release Notes:
>  
> -* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
> -  to be replaced with the inline function ``rte_foo()``.
> +* The Macro ``#RTE_FOO`` is deprecated and will be removed with ABI version
> +  21, to be replaced with the inline function ``rte_foo()``.
>  
>  * The function ``rte_mbuf_grok()`` has been updated to include a new parameter
> -  in version 2.0. Backwards compatibility will be maintained for this function
> -  until the release of version 2.1
> +  in version 20.2. Backwards compatibility will be maintained for this function
> +  until the release of the new DPDK major ABI version 21, in DPDK version
> +  20.11.
>  
> -* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
> +* The members of ``struct rte_foo`` have been reorganized in DPDK 20.02 for
>    performance reasons. Existing binary applications will have backwards
> -  compatibility in release 2.0, while newly built binaries will need to
> -  reference the new structure variant ``struct rte_foo2``. Compatibility will
> -  be removed in release 2.2, and all applications will require updating and
> +  compatibility in release 20.02, while newly built binaries will need to
> +  reference the new structure variant ``struct rte_foo2``. Compatibility will be
> +  removed in release 20.11, and all applications will require updating and
>    rebuilding to the new structure at that time, which will be renamed to the
>    original ``struct rte_foo``.
>  
>  * Significant ABI changes are planned for the ``librte_dostuff`` library. The
> -  upcoming release 2.0 will not contain these changes, but release 2.1 will,
> +  upcoming release 20.02 will not contain these changes, but release 20.11 will,
>    and no backwards compatibility is planned due to the extensive nature of
> -  these changes. Binaries using this library built prior to version 2.1 will
> +  these changes. Binaries using this library built prior to ABI version 21 will
>    require updating and recompilation.
>  
> -New API replacing previous one
> -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> -
> -If a new API proposed functionally replaces an existing one, when the new API
> -becomes non-experimental then the old one is marked with ``__rte_deprecated``.
> -Deprecated APIs are removed completely just after the next LTS.
> -
> -Reminder that old API should follow deprecation process to be removed.
> +.. _experimental_apis:
>  
> +Experimental
> +------------
>  
> -Experimental APIs
> ------------------
> +APIs
> +~~~~
>  
> -APIs marked as ``experimental`` are not considered part of the ABI and may
> -change without warning at any time.  Since changes to APIs are most likely
> -immediately after their introduction, as users begin to take advantage of
> -those new APIs and start finding issues with them, new DPDK APIs will be
> -automatically marked as ``experimental`` to allow for a period of stabilization
> -before they become part of a tracked ABI.
> +APIs marked as ``experimental`` are not considered part of an ABI version and
> +may change without warning at any time. Since changes to APIs are most likely
> +immediately after their introduction, as users begin to take advantage of those
> +new APIs and start finding issues with them, new DPDK APIs will be automatically
> +marked as ``experimental`` to allow for a period of stabilization before they
> +become part of a tracked ABI version.
>  
>  Note that marking an API as experimental is a multi step process.
>  To mark an API as experimental, the symbols which are desired to be exported
> @@ -163,7 +294,16 @@ In addition to tagging the code with ``__rte_experimental``,
>  the doxygen markup must also contain the EXPERIMENTAL string,
>  and the MAINTAINERS file should note the EXPERIMENTAL libraries.
>  
> -For removing the experimental tag associated with an API, deprecation notice
> -is not required. Though, an API should remain in experimental state for at least
> -one release. Thereafter, normal process of posting patch for review to mailing
> -list can be followed.
> +For removing the experimental tag associated with an API, deprecation notice is
> +not required. Though, an API should remain in experimental state for at least
> +one release. Thereafter, the normal process of posting patch for review to
> +mailing list can be followed.
> +
> +Libraries
> +~~~~~~~~~
> +
> +Libraries marked as ``experimental`` are entirely not considered part of an ABI
> +version, and may change without warning at any time. Experimental libraries
> +always have a major version of ``0`` to indicate they exist outside of
> +:ref:`abi_versioning` , with the minor version incremented with each ABI change
> +to library.
> diff --git a/doc/guides/contributing/stable.rst b/doc/guides/contributing/stable.rst
> index 6a5eee9..d95c200 100644
> --- a/doc/guides/contributing/stable.rst
> +++ b/doc/guides/contributing/stable.rst
> @@ -1,7 +1,7 @@
>  ..  SPDX-License-Identifier: BSD-3-Clause
>      Copyright 2018 The DPDK contributors
>  
> -.. stable_lts_releases:
> +.. _stable_lts_releases:
>  
>  DPDK Stable Releases and Long Term Support
>  ==========================================
> @@ -53,6 +53,9 @@ year's November (X.11) release will be maintained as an LTS for 2 years.
>  After the X.11 release, an LTS branch will be created for it at
>  http://git.dpdk.org/dpdk-stable where bugfixes will be backported to.
>  
> +A LTS release may align with the declaration of a new major ABI version,
> +please read the :ref:`abi_policy` for more information.
> +

Above is worth to mention, but as discussed on call earlier today, the
changes below should be dropped from this patchset. At present each LTS
minor release (e.g. 18.11.2) maintains the API/ABI of the original LTS
release (e.g. 18.11) and that is not changing.

What type of non-ABI breaking things are backported to LTS branches can
be discussed during the LTS presentation in DPDK userspace.

thanks,
Kevin.

>  It is anticipated that there will be at least 4 releases per year of the LTS
>  or approximately 1 every 3 months. However, the cadence can be shorter or
>  longer depending on the number and criticality of the backported
> @@ -68,10 +71,13 @@ point the LTS branch will no longer be maintained with no further releases.
>  What changes should be backported
>  ---------------------------------
>  
> -Backporting should be limited to bug fixes. All patches accepted on the master
> -branch with a Fixes: tag should be backported to the relevant stable/LTS
> -branches, unless the submitter indicates otherwise. If there are exceptions,
> -they will be discussed on the mailing lists.
> +Backporting is a naturally conservative activity, and therefore should only
> +include bug fixes and support for new hardware, were adding support does not
> +necessitate DPDK ABI/API changes.
> +
> +All patches accepted on the master branch with a Fixes: tag should be backported
> +to the relevant stable/LTS branches, unless the submitter indicates otherwise.
> +If there are exceptions, they will be discussed on the mailing lists.
>  
>  Fixes suitable for backport should have a ``Cc: stable@dpdk.org`` tag in the
>  commit message body as follows::
> @@ -86,13 +92,18 @@ commit message body as follows::
>       Signed-off-by: Alex Smith <alex.smith@example.com>
>  
>  
> -Fixes not suitable for backport should not include the ``Cc: stable@dpdk.org`` tag.
> +Fixes not suitable for backport should not include the ``Cc: stable@dpdk.org``
> +tag.
>  
> -Features should not be backported to stable releases. It may be acceptable, in
> -limited cases, to back port features for the LTS release where:
> +New features, with the exception of new hardware support, should not be
> +backported to stable releases. In the case of new hardware support or any other
> +exceptional circumstances limited backporting maybe permitted to the LTS release
> +where:
>  
> -* There is a justifiable use case (for example a new PMD).
> -* The change is non-invasive.
> +* There is a justifiable use case, for example the change is required to support
> +  a new platform or device (for example a new PMD).
> +* The change is ABI/API preserving, it does not present an obvious "new feature"
> +  to end consumer.
>  * The work of preparing the backport is done by the proposer.
>  * There is support within the community.
>  
> @@ -119,10 +130,3 @@ A Stable Release will be released by:
>    list.
>  
>  Stable releases are available on the `dpdk.org download page <http://core.dpdk.org/download/>`_.
> -
> -
> -ABI
> ----
> -
> -The Stable Release should not be seen as a way of breaking or circumventing
> -the DPDK ABI policy.
> 

^ permalink raw reply	[relevance 10%]

* [dpdk-dev] [PATCH 04/15] net/virtio: add virtio PCI subsystem device ID declaration
  @ 2019-08-29  7:59  4% ` Maxime Coquelin
  2019-09-02  6:14  0%   ` Tiwei Bie
  0 siblings, 1 reply; 200+ results
From: Maxime Coquelin @ 2019-08-29  7:59 UTC (permalink / raw)
  To: tiwei.bie, zhihong.wang, amorenoz, xiao.w.wang, dev, jfreimann
  Cc: stable, Maxime Coquelin

The Virtio PCI susbsytem IDs need to be specified to
prevent it to probe IFC vDPA VFs.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_pci.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index a38cb45ad..56f89a454 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -19,6 +19,7 @@ struct virtnet_ctl;
 #define VIRTIO_PCI_VENDORID     0x1AF4
 #define VIRTIO_PCI_LEGACY_DEVICEID_NET 0x1000
 #define VIRTIO_PCI_MODERN_DEVICEID_NET 0x1041
+#define VIRTIO_PCI_SUBSY_DEVICEID_NET 0x1100
 
 /* VirtIO ABI version, this must match exactly. */
 #define VIRTIO_PCI_ABI_VERSION 0
-- 
2.21.0


^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [RFC] rte_hash: introduce hash list into hash lib
  @ 2019-08-28 11:53  3%   ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-08-28 11:53 UTC (permalink / raw)
  To: Bing Zhao
  Cc: yipeng1.wang, sameh.gobriel, bruce.richardson, pablo.de.lara.guarch, dev

On Wed, 28 Aug 2019 14:51:49 +0800
Bing Zhao <bingz@mellanox.com> wrote:

> +
> +/** Node element structure on the LIST of the link */
> +struct rte_hlist_node_entry {
> +	LIST_ENTRY(rte_hlist_node_entry) next;	/**< Next element pointer. */
> +	/**< Data element inside this noed. */
> +	struct rte_hlist_data_element d;
> +	char key[];				/**< Copied and stored key. */
> +};
> +
> +/** Head of all the nodes with the same hash value */
> +struct rte_hlist_head_entry {
> +	LIST_HEAD(, rte_hlist_node_entry) head;	/**< Head for each hash list. */
> +	/**< Current items in the list. */
> +	uint16_t entries_in_bucket;
> +	/**< Shift number for extension */
> +	uint16_t bucket_shift;
> +};
> +
> +/** The hlist table structure. */
> +struct rte_hlist_table {
> +	char name[RTE_HLIST_NAMESIZE];	/**< Name of the hash. */
> +	uint32_t entries;		/**< Total number of entries. */
> +	uint32_t entries_per_bucket;	/**< Number of entries in a list. */
> +	/**< Number of entries with data from customer. */
> +	uint32_t custom_entries;
> +	uint16_t key_len;		/**< Length of the key. */
> +	/**< Shift number of the whole table. */
> +	uint16_t bucket_shift;
> +	/**< To find which list the key is in. */
> +	uint32_t bucket_mask;
> +	rte_hlist_calc_fn hash_func;	/**< The hash function to calcuate. */
> +	/**< The function to free the custom data. */
> +	rte_hlist_free_fn free_func;
> +	uint32_t init_val;		/**< For initializing hash function. */
> +	/**< Reserved for fast shrinking of the table. */
> +	char *map;

You probably should use void * for that.

> +	/**< A flat and extendible table of all lists. */
> +	struct rte_hlist_head_entry *t;
> +};
> +

Since API/ABI considerations are important.
You will save yourself a lot of pain if these structures can be made
private and only part of rte_hlist.c.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v6] eal: add tsc_hz to rte_mem_config
  @ 2019-08-27 16:16  3% ` Jim Harris
  0 siblings, 0 replies; 200+ results
From: Jim Harris @ 2019-08-27 16:16 UTC (permalink / raw)
  To: dev, bruce.richardson, anatoly.burakov

This ensures secondary processes never have to
calculate the TSC rate themselves, which can be
noticeable in VMs that don't have access to
arch-specific detection mechanism (such as
CPUID leaf 0x15 or MSR 0xCE on x86).

Since rte_mem_config is now internal to the rte_eal
library, we can add tsc_hz without ABI breakage
concerns.

Reduces rte_eal_init() execution time in a secondary
process from 165ms to 66ms on my test system.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
---
 lib/librte_eal/common/eal_common_timer.c |   15 +++++++++++++++
 lib/librte_eal/common/eal_memcfg.h       |    3 +++
 2 files changed, 18 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c
index 145543de7..fa9ee1b22 100644
--- a/lib/librte_eal/common/eal_common_timer.c
+++ b/lib/librte_eal/common/eal_common_timer.c
@@ -15,8 +15,10 @@
 #include <rte_log.h>
 #include <rte_cycles.h>
 #include <rte_pause.h>
+#include <rte_eal.h>
 
 #include "eal_private.h"
+#include "eal_memcfg.h"
 
 /* The frequency of the RDTSC timer resolution */
 static uint64_t eal_tsc_resolution_hz;
@@ -77,8 +79,20 @@ estimate_tsc_freq(void)
 void
 set_tsc_freq(void)
 {
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
 	uint64_t freq;
 
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		/*
+		 * Just use the primary process calculated TSC rate in any
+		 * secondary process.  It avoids any unnecessary overhead on
+		 * systems where arch-specific frequency detection is not
+		 * available.
+		 */
+		eal_tsc_resolution_hz = mcfg->tsc_hz;
+		return;
+	}
+
 	freq = get_tsc_freq_arch();
 	if (!freq)
 		freq = get_tsc_freq();
@@ -87,6 +101,7 @@ set_tsc_freq(void)
 
 	RTE_LOG(DEBUG, EAL, "TSC frequency is ~%" PRIu64 " KHz\n", freq / 1000);
 	eal_tsc_resolution_hz = freq;
+	mcfg->tsc_hz = freq;
 }
 
 void rte_delay_us_callback_register(void (*userfunc)(unsigned int))
diff --git a/lib/librte_eal/common/eal_memcfg.h b/lib/librte_eal/common/eal_memcfg.h
index 359beb216..73be6fbae 100644
--- a/lib/librte_eal/common/eal_memcfg.h
+++ b/lib/librte_eal/common/eal_memcfg.h
@@ -70,6 +70,9 @@ struct rte_mem_config {
 	uint32_t single_file_segments;
 	/**< stored single file segments parameter. */
 
+	uint64_t tsc_hz;
+	/**< TSC rate */
+
 	uint8_t dma_maskbits; /**< Keeps the more restricted dma mask. */
 };
 


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH 01/51] ethdev: change rte_eth_dev_info_get() return value to int
  @ 2019-08-27 14:25  3% ` Andrew Rybchenko
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-08-27 14:25 UTC (permalink / raw)
  To: Neil Horman, John McNamara, Marko Kovacevic, Thomas Monjalon,
	Ferruh Yigit
  Cc: dev, Ivan Ilchenko

From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>

Change rte_eth_dev_info_get() return value from void to int and return
negative errno values in case of error conditions.
Modify rte_eth_dev_info_get() usage across the ethdev according
to new return type.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/rel_notes/deprecation.rst   |  1 -
 doc/guides/rel_notes/release_19_11.rst |  5 ++-
 lib/librte_ethdev/rte_ethdev.c         | 71 ++++++++++++++++++++++++----------
 lib/librte_ethdev/rte_ethdev.h         |  6 ++-
 4 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 0ee8533..cbb4c34 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,7 +88,6 @@ Deprecation Notices
   negative errno values to indicate various error conditions (e.g.
   invalid port ID, unsupported operation, failed operation):
 
-  - ``rte_eth_dev_info_get``
   - ``rte_eth_promiscuous_enable`` and ``rte_eth_promiscuous_disable``
   - ``rte_eth_allmulticast_enable`` and ``rte_eth_allmulticast_disable``
   - ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 8490d89..5424b6a 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -85,6 +85,9 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void`` to
+  ``int`` to provide a way to report various error conditions.
+
 
 ABI Changes
 -----------
@@ -136,7 +139,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_distributor.so.1
      librte_eal.so.11
      librte_efd.so.1
-     librte_ethdev.so.12
+   + librte_ethdev.so.13
      librte_eventdev.so.7
      librte_flow_classify.so.1
      librte_gro.so.1
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e..4b6cbe2 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1125,7 +1125,6 @@ struct rte_eth_dev *
 
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -1144,7 +1143,9 @@ struct rte_eth_dev *
 	 */
 	memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf));
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* If number of queues specified by application for both Rx and Tx is
 	 * zero, use driver preferred values. This cannot be done individually
@@ -1406,6 +1407,7 @@ struct rte_eth_dev *
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
 	int diag;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1420,7 +1422,9 @@ struct rte_eth_dev *
 		return 0;
 	}
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* Lets restore MAC now if device does not support live change */
 	if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)
@@ -1584,7 +1588,6 @@ struct rte_eth_dev *
 		return -EINVAL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP);
 
 	/*
@@ -1592,7 +1595,10 @@ struct rte_eth_dev *
 	 * This value must be provided in the private data of the memory pool.
 	 * First check that the memory pool has a valid private data.
 	 */
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
 		RTE_ETHDEV_LOG(ERR, "%s private_data_size %d < %d\n",
 			mp->name, (int)mp->private_data_size,
@@ -1703,6 +1709,7 @@ struct rte_eth_dev *
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_txconf local_conf;
 	void **txq;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1712,10 +1719,11 @@ struct rte_eth_dev *
 		return -EINVAL;
 	}
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP);
 
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	/* Use default specified by driver, if nb_tx_desc is zero */
 	if (nb_tx_desc == 0) {
@@ -2540,7 +2548,7 @@ struct rte_eth_dev *
 							fw_version, fw_size));
 }
 
-void
+int
 rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 {
 	struct rte_eth_dev *dev;
@@ -2558,7 +2566,7 @@ struct rte_eth_dev *
 	 */
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 
-	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	dev_info->rx_desc_lim = lim;
@@ -2567,13 +2575,15 @@ struct rte_eth_dev *
 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
 	dev_info->max_mtu = UINT16_MAX;
 
-	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
 
 	dev_info->dev_flags = &dev->data->dev_flags;
+
+	return 0;
 }
 
 int
@@ -2643,7 +2653,10 @@ struct rte_eth_dev *
 	 * which relies on dev->dev_ops->dev_infos_get.
 	 */
 	if (*dev->dev_ops->dev_infos_get != NULL) {
-		rte_eth_dev_info_get(port_id, &dev_info);
+		ret = rte_eth_dev_info_get(port_id, &dev_info);
+		if (ret != 0)
+			return ret;
+
 		if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
 			return -EINVAL;
 	}
@@ -2991,10 +3004,15 @@ struct rte_eth_dev *
 {
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	dev = &rte_eth_devices[port_id];
-	rte_eth_dev_info_get(port_id, &dev_info);
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3100,9 +3118,13 @@ struct rte_eth_dev *
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	unsigned i;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	rte_eth_dev_info_get(port_id, &dev_info);
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	for (i = 0; i < dev_info.max_mac_addrs; i++)
 		if (memcmp(addr, &dev->data->mac_addrs[i],
@@ -3233,8 +3255,14 @@ struct rte_eth_dev *
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	unsigned i;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
-	rte_eth_dev_info_get(port_id, &dev_info);
 	if (!dev->data->hash_mac_addrs)
 		return -1;
 
@@ -3319,11 +3347,15 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
 	struct rte_eth_link link;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
+
 	dev = &rte_eth_devices[port_id];
-	rte_eth_dev_info_get(port_id, &dev_info);
 	link = dev->data->dev_link;
 
 	if (queue_idx > dev_info.max_tx_queues) {
@@ -4363,15 +4395,14 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
 				 uint16_t *nb_rx_desc,
 				 uint16_t *nb_tx_desc)
 {
-	struct rte_eth_dev *dev;
 	struct rte_eth_dev_info dev_info;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
-	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
-
-	rte_eth_dev_info_get(port_id, &dev_info);
+	ret = rte_eth_dev_info_get(port_id, &dev_info);
+	if (ret != 0)
+		return ret;
 
 	if (nb_rx_desc != NULL)
 		rte_eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim);
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index dc6596b..09c278d 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2366,8 +2366,12 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @param dev_info
  *   A pointer to a structure of type *rte_eth_dev_info* to be filled with
  *   the contextual information of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
+ *   - (-ENODEV) if *port_id* invalid.
  */
-void rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
+int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
  * Retrieve the firmware version of a device.
-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test
  2019-08-27  8:28  8%       ` Ray Kinsella
@ 2019-08-27 14:19  7%         ` Ray Kinsella
  0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-27 14:19 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Aaron Conole, dev, vladimir.medvedkin, john.mcnamara, marko.kovacevic



On 27/08/2019 09:28, Ray Kinsella wrote:
> 
> 
> On 27/08/2019 09:17, Bruce Richardson wrote:
>> On Mon, Aug 26, 2019 at 05:45:55PM +0100, Ray Kinsella wrote:
>>>
>>>
>>> On 23/08/2019 16:49, Aaron Conole wrote:
>>>> Ray Kinsella <mdr@ashroe.eu> writes:
>>>>
>>>>> This patchset adds ABI version testing to the app/test unit test framework,
>>>>> addressing two issues previously raised during ML conversations on ABI
>>>>> stability;
>>>>>
>>>>> 1. How do we unit test still supported previous ABI versions?
>>>>> 2. How to we unit test inline functions from still supported previous ABI
>>>>> versions?
>>>>>
>>>>> Starting with rte_lpm, I did the following:-
>>>>>
>>>>> * I reproduced mostly unmodified unit tests for the v2.0 ABI, taken from DPDK
>>>>>   2.2 and 17.02.
>>>>> * I reproduced the rte_lpm interface header from v2.0, including the inline
>>>>>   functions and remapping symbols to their appropriate versions.
>>>>> * I added support for multiple abi versions to the app/test unit test framework
>>>>>   to allow users to switch between abi versions (set_abi_version), without
>>>>>   further polluting the already long list of unit tests available in app/test.
>>>>>
>>>>> The intention here is that in future as developers need to deprecate APIs, the
>>>>> associated unit tests may move into the ABI version testing mechanism of the
>>>>> app/test instead of being replaced by the latest set of unit tests as would be
>>>>> the case today.
>>>>>
>>>>> v2:
>>>>>
>>>>> * Added LPM IPv6 test cases for the v2.0 ABI.
>>>>> * Fixed a number of checkpatch errors, stop short of substantially reworking
>>>>>   the test code from the v2.0 ABI. 
>>>>> * Removed duplicating test cases published in the original v1 patch.
>>>>
>>>> Thanks for this work.  I think it's useful.
>>>>
>>>> I see an error under aarch64 builds because there are some x86_64
>>>> specific types being used in the testing.
>>>
>>> So the problem is that LPM didn't fully support ARM until DPDK v16.04.
>>> The ABI versioning code in the LPM library is there to support the 2.0 ABI.
>>>
>>> The intention of this unit test is to test backward's compatibility with
>>> an inline LPM function from DPDK v2.2.0, which was essentially x86 only
>>> at that time.
>>>
>>> Unless we want to get into the business of backporting ARM support to
>>> DPDK 2.2.0 (from where this test cases came from) - we should probably
>>> restrict these ABI versioning test cases to CONFIG_RTE_ARCH_X86_64 only.
>>>
>>> The other option is forget about testing this the LPM ABI versioning
>>> support, which then asks the question should be perhaps excise that code
>>> altogether.
>>>
>>
>> I think function versioning is great and should be widely used.
>> Unfortunately, though, in our case since we break the ABI so consistently,
>> this old code is pretty useless. Therefore, I think we should remove all
>> old versionned code from e.g. pre-18.11, since no app is realistically
>> going to work from that far back anyway.
>>
>> /Bruce 
>>
> 
> I had come to a similar conclusion, that we likely need to deprecate
> much or all of the existing ABI Compatibility code, it needs a wider
> review.
> 
> BIND_VERSION_SYMBOL and friends, are still needed to unit test ABI
> Versioning, the general idea is sound. And I liked LPM as an example,
> because it is well understood and contained, but I will look for
> something more recent we could use instead.
> 

Only recent example I can find of ABI versioning is the Timer Library,
changed in April 2019. After that are the distributor and the lpm
library both changes in 2017, does this seem right?

Ray K

root@xxx:/build/dpdk# find lib -name *.map | xargs -I{} -- git log -1
--format="%ai {}" {} | sort -k 1,2 | tail -n 10
2019-04-03 18:20:13 -0500 lib/librte_stack/rte_stack_version.map
2019-04-15 16:41:28 -0500 lib/librte_timer/rte_timer_version.map
2019-04-30 22:54:16 -0500 lib/librte_rcu/rte_rcu_version.map
2019-06-25 04:46:02 +0530 lib/librte_eventdev/rte_eventdev_version.map
2019-07-05 10:16:17 -0700 lib/librte_net/rte_net_version.map
2019-07-11 09:26:05 +0000 lib/librte_metrics/rte_metrics_version.map
2019-07-17 03:23:55 +0800 lib/librte_ring/rte_ring_version.map
2019-07-26 15:10:19 +0100 lib/librte_security/rte_security_version.map
2019-07-27 09:21:33 +0200 lib/librte_eal/rte_eal_version.map
2019-07-31 14:27:16 +0200 lib/librte_ethdev/rte_ethdev_version.map


root@xxx:/build/dpdk# find lib -name *.map | xargs -I{} -- git log -1
--format="%ai {}" {} | sort -k 1,2 | tail -n 50 | awk '{print $4}' |
xargs sort | uniq -c | sort -k 1


...
      2         rte_distributor_clear_returns;
      2         rte_distributor_create;
      2         rte_distributor_flush;
      2         rte_distributor_get_pkt;
      2         rte_distributor_poll_pkt;
      2         rte_distributor_process;
      2         rte_distributor_request_pkt;
      2         rte_distributor_returned_pkts;
      2         rte_distributor_return_pkt;
      2         rte_lpm6_add;
      2         rte_lpm6_is_rule_present;
      2         rte_lpm6_lookup;
      2         rte_lpm6_lookup_bulk_func;
      2         rte_lpm_add;
      2         rte_lpm_create;
      2         rte_lpm_delete;
      2         rte_lpm_delete_all;
      2         rte_lpm_find_existing;
      2         rte_lpm_free;
      2         rte_lpm_is_rule_present;
      2         rte_timer_dump_stats;
      2         rte_timer_manage;
      2         rte_timer_reset;
      2         rte_timer_stop;
      2         rte_timer_subsystem_init;
...






^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test
  2019-08-27  8:17  7%     ` Bruce Richardson
@ 2019-08-27  8:28  8%       ` Ray Kinsella
  2019-08-27 14:19  7%         ` Ray Kinsella
  0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2019-08-27  8:28 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Aaron Conole, dev, vladimir.medvedkin, john.mcnamara, marko.kovacevic



On 27/08/2019 09:17, Bruce Richardson wrote:
> On Mon, Aug 26, 2019 at 05:45:55PM +0100, Ray Kinsella wrote:
>>
>>
>> On 23/08/2019 16:49, Aaron Conole wrote:
>>> Ray Kinsella <mdr@ashroe.eu> writes:
>>>
>>>> This patchset adds ABI version testing to the app/test unit test framework,
>>>> addressing two issues previously raised during ML conversations on ABI
>>>> stability;
>>>>
>>>> 1. How do we unit test still supported previous ABI versions?
>>>> 2. How to we unit test inline functions from still supported previous ABI
>>>> versions?
>>>>
>>>> Starting with rte_lpm, I did the following:-
>>>>
>>>> * I reproduced mostly unmodified unit tests for the v2.0 ABI, taken from DPDK
>>>>   2.2 and 17.02.
>>>> * I reproduced the rte_lpm interface header from v2.0, including the inline
>>>>   functions and remapping symbols to their appropriate versions.
>>>> * I added support for multiple abi versions to the app/test unit test framework
>>>>   to allow users to switch between abi versions (set_abi_version), without
>>>>   further polluting the already long list of unit tests available in app/test.
>>>>
>>>> The intention here is that in future as developers need to deprecate APIs, the
>>>> associated unit tests may move into the ABI version testing mechanism of the
>>>> app/test instead of being replaced by the latest set of unit tests as would be
>>>> the case today.
>>>>
>>>> v2:
>>>>
>>>> * Added LPM IPv6 test cases for the v2.0 ABI.
>>>> * Fixed a number of checkpatch errors, stop short of substantially reworking
>>>>   the test code from the v2.0 ABI. 
>>>> * Removed duplicating test cases published in the original v1 patch.
>>>
>>> Thanks for this work.  I think it's useful.
>>>
>>> I see an error under aarch64 builds because there are some x86_64
>>> specific types being used in the testing.
>>
>> So the problem is that LPM didn't fully support ARM until DPDK v16.04.
>> The ABI versioning code in the LPM library is there to support the 2.0 ABI.
>>
>> The intention of this unit test is to test backward's compatibility with
>> an inline LPM function from DPDK v2.2.0, which was essentially x86 only
>> at that time.
>>
>> Unless we want to get into the business of backporting ARM support to
>> DPDK 2.2.0 (from where this test cases came from) - we should probably
>> restrict these ABI versioning test cases to CONFIG_RTE_ARCH_X86_64 only.
>>
>> The other option is forget about testing this the LPM ABI versioning
>> support, which then asks the question should be perhaps excise that code
>> altogether.
>>
> 
> I think function versioning is great and should be widely used.
> Unfortunately, though, in our case since we break the ABI so consistently,
> this old code is pretty useless. Therefore, I think we should remove all
> old versionned code from e.g. pre-18.11, since no app is realistically
> going to work from that far back anyway.
> 
> /Bruce 
> 

I had come to a similar conclusion, that we likely need to deprecate
much or all of the existing ABI Compatibility code, it needs a wider
review.

BIND_VERSION_SYMBOL and friends, are still needed to unit test ABI
Versioning, the general idea is sound. And I liked LPM as an example,
because it is well understood and contained, but I will look for
something more recent we could use instead.

^ permalink raw reply	[relevance 8%]

* Re: [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test
  2019-08-26 16:45  9%   ` Ray Kinsella
@ 2019-08-27  8:17  7%     ` Bruce Richardson
  2019-08-27  8:28  8%       ` Ray Kinsella
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2019-08-27  8:17 UTC (permalink / raw)
  To: Ray Kinsella
  Cc: Aaron Conole, dev, vladimir.medvedkin, john.mcnamara, marko.kovacevic

On Mon, Aug 26, 2019 at 05:45:55PM +0100, Ray Kinsella wrote:
> 
> 
> On 23/08/2019 16:49, Aaron Conole wrote:
> > Ray Kinsella <mdr@ashroe.eu> writes:
> > 
> >> This patchset adds ABI version testing to the app/test unit test framework,
> >> addressing two issues previously raised during ML conversations on ABI
> >> stability;
> >>
> >> 1. How do we unit test still supported previous ABI versions?
> >> 2. How to we unit test inline functions from still supported previous ABI
> >> versions?
> >>
> >> Starting with rte_lpm, I did the following:-
> >>
> >> * I reproduced mostly unmodified unit tests for the v2.0 ABI, taken from DPDK
> >>   2.2 and 17.02.
> >> * I reproduced the rte_lpm interface header from v2.0, including the inline
> >>   functions and remapping symbols to their appropriate versions.
> >> * I added support for multiple abi versions to the app/test unit test framework
> >>   to allow users to switch between abi versions (set_abi_version), without
> >>   further polluting the already long list of unit tests available in app/test.
> >>
> >> The intention here is that in future as developers need to deprecate APIs, the
> >> associated unit tests may move into the ABI version testing mechanism of the
> >> app/test instead of being replaced by the latest set of unit tests as would be
> >> the case today.
> >>
> >> v2:
> >>
> >> * Added LPM IPv6 test cases for the v2.0 ABI.
> >> * Fixed a number of checkpatch errors, stop short of substantially reworking
> >>   the test code from the v2.0 ABI. 
> >> * Removed duplicating test cases published in the original v1 patch.
> > 
> > Thanks for this work.  I think it's useful.
> > 
> > I see an error under aarch64 builds because there are some x86_64
> > specific types being used in the testing.
> 
> So the problem is that LPM didn't fully support ARM until DPDK v16.04.
> The ABI versioning code in the LPM library is there to support the 2.0 ABI.
> 
> The intention of this unit test is to test backward's compatibility with
> an inline LPM function from DPDK v2.2.0, which was essentially x86 only
> at that time.
> 
> Unless we want to get into the business of backporting ARM support to
> DPDK 2.2.0 (from where this test cases came from) - we should probably
> restrict these ABI versioning test cases to CONFIG_RTE_ARCH_X86_64 only.
> 
> The other option is forget about testing this the LPM ABI versioning
> support, which then asks the question should be perhaps excise that code
> altogether.
>

I think function versioning is great and should be widely used.
Unfortunately, though, in our case since we break the ABI so consistently,
this old code is pretty useless. Therefore, I think we should remove all
old versionned code from e.g. pre-18.11, since no app is realistically
going to work from that far back anyway.

/Bruce 

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test
  2019-08-23 15:49  4% ` [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test Aaron Conole
@ 2019-08-26 16:45  9%   ` Ray Kinsella
  2019-08-27  8:17  7%     ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2019-08-26 16:45 UTC (permalink / raw)
  To: Aaron Conole
  Cc: dev, bruce.richardson, vladimir.medvedkin, john.mcnamara,
	marko.kovacevic



On 23/08/2019 16:49, Aaron Conole wrote:
> Ray Kinsella <mdr@ashroe.eu> writes:
> 
>> This patchset adds ABI version testing to the app/test unit test framework,
>> addressing two issues previously raised during ML conversations on ABI
>> stability;
>>
>> 1. How do we unit test still supported previous ABI versions?
>> 2. How to we unit test inline functions from still supported previous ABI
>> versions?
>>
>> Starting with rte_lpm, I did the following:-
>>
>> * I reproduced mostly unmodified unit tests for the v2.0 ABI, taken from DPDK
>>   2.2 and 17.02.
>> * I reproduced the rte_lpm interface header from v2.0, including the inline
>>   functions and remapping symbols to their appropriate versions.
>> * I added support for multiple abi versions to the app/test unit test framework
>>   to allow users to switch between abi versions (set_abi_version), without
>>   further polluting the already long list of unit tests available in app/test.
>>
>> The intention here is that in future as developers need to deprecate APIs, the
>> associated unit tests may move into the ABI version testing mechanism of the
>> app/test instead of being replaced by the latest set of unit tests as would be
>> the case today.
>>
>> v2:
>>
>> * Added LPM IPv6 test cases for the v2.0 ABI.
>> * Fixed a number of checkpatch errors, stop short of substantially reworking
>>   the test code from the v2.0 ABI. 
>> * Removed duplicating test cases published in the original v1 patch.
> 
> Thanks for this work.  I think it's useful.
> 
> I see an error under aarch64 builds because there are some x86_64
> specific types being used in the testing.

So the problem is that LPM didn't fully support ARM until DPDK v16.04.
The ABI versioning code in the LPM library is there to support the 2.0 ABI.

The intention of this unit test is to test backward's compatibility with
an inline LPM function from DPDK v2.2.0, which was essentially x86 only
at that time.

Unless we want to get into the business of backporting ARM support to
DPDK 2.2.0 (from where this test cases came from) - we should probably
restrict these ABI versioning test cases to CONFIG_RTE_ARCH_X86_64 only.

The other option is forget about testing this the LPM ABI versioning
support, which then asks the question should be perhaps excise that code
altogether.

Make sense?

Ray K



^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] [PATCH 0/2] IXGBE vPMD changes for aarch64
  2019-08-26 10:39  3%     ` Ferruh Yigit
@ 2019-08-26 10:53  0%       ` Ruifeng Wang (Arm Technology China)
  0 siblings, 0 replies; 200+ results
From: Ruifeng Wang (Arm Technology China) @ 2019-08-26 10:53 UTC (permalink / raw)
  To: Ferruh Yigit, Ye Xiaolong
  Cc: jerinj, Gavin Hu (Arm Technology China),
	dev, Honnappa Nagarahalli, nd, Kevin Traynor, Luca Boccassi, nd


> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@intel.com>
> Sent: Monday, August 26, 2019 18:40
> To: Ruifeng Wang (Arm Technology China) <Ruifeng.Wang@arm.com>; Ye
> Xiaolong <xiaolong.ye@intel.com>
> Cc: jerinj@marvell.com; Gavin Hu (Arm Technology China)
> <Gavin.Hu@arm.com>; dev@dpdk.org; Honnappa Nagarahalli
> <Honnappa.Nagarahalli@arm.com>; nd <nd@arm.com>; Kevin Traynor
> <ktraynor@redhat.com>; Luca Boccassi <bluca@debian.org>
> Subject: Re: [dpdk-dev] [PATCH 0/2] IXGBE vPMD changes for aarch64
> 
> On 8/26/2019 3:52 AM, Ruifeng Wang (Arm Technology China) wrote:
> > Hi Xiaolong,
> >
> >> -----Original Message-----
> >> From: Ye Xiaolong <xiaolong.ye@intel.com>
> >> Sent: Sunday, August 25, 2019 09:34
> >> To: Ruifeng Wang (Arm Technology China) <Ruifeng.Wang@arm.com>
> >> Cc: jerinj@marvell.com; Gavin Hu (Arm Technology China)
> >> <Gavin.Hu@arm.com>; dev@dpdk.org; Honnappa Nagarahalli
> >> <Honnappa.Nagarahalli@arm.com>; nd <nd@arm.com>
> >> Subject: Re: [dpdk-dev] [PATCH 0/2] IXGBE vPMD changes for aarch64
> >>
> >> Hi,
> >>
> >> Thanks for the patches, could you also provide the Fixes tag and cc stable?
> >> The patchset looks good to me.
> >
> > Code changes in both patches are not for bug fixing.
> > Patch 1/2 includes fix for code comments. I don't think it deserves a Fixes
> tag or backporting. Can we skip the Fixes tag?
> 
> In 1/2 a memory barrier is removed, it means it was wrong to add it at first
> place and you are fixing it, no?
> 
> 
> Performance improvements are in gray are, but if there is no ABI/API break
> why not take is performance fix and backport and have the performance
> improvement in LTS?
> Also I think taking as much as possible may help to maintain LTS, since it
> reduces the chance of conflict in later commits, LTS is two years and these
> small things can accumulate and make getting important fixes hard by time.
> 
> Is there any specific reason not to backport these patches to LTS releases?
> 
Thanks for your explanation.
Understand that. No objection to backporting.
I'll send out new version.

> 
> >
> >>
> >> Thanks,
> >> Xiaolong
> >>
> >> On 08/13, Ruifeng Wang wrote:
> >>> Couple of changes to IXGBE vector PMD on aarch64 platform.
> >>> An unnecessary memory barrier was identified and removed.
> >>> Also part of processing was replaced with NEON intrinsics.
> >>> Both of the changes will help to improve performance.
> >>>
> >>> Ruifeng Wang (2):
> >>>  net/ixgbe: remove barrier in vPMD for aarch64
> >>>  net/ixgbe: use neon intrinsics to count packet for aarch64
> >>>
> >>> drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c | 32
> >>> ++++++++++++-------------
> >>> 1 file changed, 16 insertions(+), 16 deletions(-)
> >>>
> >>> --
> >>> 2.17.1
> >>>


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH 0/2] IXGBE vPMD changes for aarch64
  @ 2019-08-26 10:39  3%     ` Ferruh Yigit
  2019-08-26 10:53  0%       ` Ruifeng Wang (Arm Technology China)
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-08-26 10:39 UTC (permalink / raw)
  To: Ruifeng Wang (Arm Technology China), Ye Xiaolong
  Cc: jerinj, Gavin Hu (Arm Technology China),
	dev, Honnappa Nagarahalli, nd, Kevin Traynor, Luca Boccassi

On 8/26/2019 3:52 AM, Ruifeng Wang (Arm Technology China) wrote:
> Hi Xiaolong,
> 
>> -----Original Message-----
>> From: Ye Xiaolong <xiaolong.ye@intel.com>
>> Sent: Sunday, August 25, 2019 09:34
>> To: Ruifeng Wang (Arm Technology China) <Ruifeng.Wang@arm.com>
>> Cc: jerinj@marvell.com; Gavin Hu (Arm Technology China)
>> <Gavin.Hu@arm.com>; dev@dpdk.org; Honnappa Nagarahalli
>> <Honnappa.Nagarahalli@arm.com>; nd <nd@arm.com>
>> Subject: Re: [dpdk-dev] [PATCH 0/2] IXGBE vPMD changes for aarch64
>>
>> Hi,
>>
>> Thanks for the patches, could you also provide the Fixes tag and cc stable?
>> The patchset looks good to me.
> 
> Code changes in both patches are not for bug fixing.
> Patch 1/2 includes fix for code comments. I don't think it deserves a Fixes tag or backporting. Can we skip the Fixes tag?

In 1/2 a memory barrier is removed, it means it was wrong to add it at first
place and you are fixing it, no?


Performance improvements are in gray are, but if there is no ABI/API break why
not take is performance fix and backport and have the performance improvement in
LTS?
Also I think taking as much as possible may help to maintain LTS, since it
reduces the chance of conflict in later commits, LTS is two years and these
small things can accumulate and make getting important fixes hard by time.

Is there any specific reason not to backport these patches to LTS releases?


> 
>>
>> Thanks,
>> Xiaolong
>>
>> On 08/13, Ruifeng Wang wrote:
>>> Couple of changes to IXGBE vector PMD on aarch64 platform.
>>> An unnecessary memory barrier was identified and removed.
>>> Also part of processing was replaced with NEON intrinsics.
>>> Both of the changes will help to improve performance.
>>>
>>> Ruifeng Wang (2):
>>>  net/ixgbe: remove barrier in vPMD for aarch64
>>>  net/ixgbe: use neon intrinsics to count packet for aarch64
>>>
>>> drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c | 32 ++++++++++++-------------
>>> 1 file changed, 16 insertions(+), 16 deletions(-)
>>>
>>> --
>>> 2.17.1
>>>


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test
  2019-08-22 16:07  9% [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test Ray Kinsella
  2019-08-22 16:07 14% ` [dpdk-dev] [PATCH v2 1/2] app/test: add abi version testing functionality Ray Kinsella
  2019-08-22 16:07  4% ` [dpdk-dev] [PATCH v2 2/2] app/test: lpm abi version testing Ray Kinsella
@ 2019-08-23 15:49  4% ` Aaron Conole
  2019-08-26 16:45  9%   ` Ray Kinsella
  2 siblings, 1 reply; 200+ results
From: Aaron Conole @ 2019-08-23 15:49 UTC (permalink / raw)
  To: Ray Kinsella
  Cc: dev, bruce.richardson, vladimir.medvedkin, john.mcnamara,
	marko.kovacevic

Ray Kinsella <mdr@ashroe.eu> writes:

> This patchset adds ABI version testing to the app/test unit test framework,
> addressing two issues previously raised during ML conversations on ABI
> stability;
>
> 1. How do we unit test still supported previous ABI versions?
> 2. How to we unit test inline functions from still supported previous ABI
> versions?
>
> Starting with rte_lpm, I did the following:-
>
> * I reproduced mostly unmodified unit tests for the v2.0 ABI, taken from DPDK
>   2.2 and 17.02.
> * I reproduced the rte_lpm interface header from v2.0, including the inline
>   functions and remapping symbols to their appropriate versions.
> * I added support for multiple abi versions to the app/test unit test framework
>   to allow users to switch between abi versions (set_abi_version), without
>   further polluting the already long list of unit tests available in app/test.
>
> The intention here is that in future as developers need to deprecate APIs, the
> associated unit tests may move into the ABI version testing mechanism of the
> app/test instead of being replaced by the latest set of unit tests as would be
> the case today.
>
> v2:
>
> * Added LPM IPv6 test cases for the v2.0 ABI.
> * Fixed a number of checkpatch errors, stop short of substantially reworking
>   the test code from the v2.0 ABI. 
> * Removed duplicating test cases published in the original v1 patch.

Thanks for this work.  I think it's useful.

I see an error under aarch64 builds because there are some x86_64
specific types being used in the testing.

See:

  https://travis-ci.com/ovsrobot/dpdk/builds/124254699

> Ray Kinsella (2):
>   app/test: add abi version testing functionality
>   app/test: lpm abi version testing
>
>  app/test/Makefile                          |   12 +-
>  app/test/commands.c                        |  131 +-
>  app/test/meson.build                       |    6 +
>  app/test/test.c                            |    2 +
>  app/test/test.h                            |   48 +-
>  app/test/test_lpm.c                        |    3 +-
>  app/test/test_lpm6.c                       |    2 +-
>  app/test/test_lpm_perf.c                   |  293 +---
>  app/test/test_lpm_routes.c                 |  287 ++++
>  app/test/test_lpm_routes.h                 |   25 +
>  app/test/v2.0/dcompat.h                    |   30 +
>  app/test/v2.0/rte_lpm.h                    |  451 +++++
>  app/test/v2.0/rte_lpm6.h                   |  198 +++
>  app/test/v2.0/test_lpm.c                   | 1139 +++++++++++++
>  app/test/v2.0/test_lpm6.c                  | 1748 ++++++++++++++++++++
>  app/test/v2.0/test_lpm6_perf.c             |  179 ++
>  app/test/v2.0/test_lpm_perf.c              |  212 +++
>  app/test/v2.0/test_v20.c                   |   14 +
>  doc/guides/contributing/versioning.rst     |    4 +
>  lib/librte_eal/common/include/rte_compat.h |    7 +
>  20 files changed, 4471 insertions(+), 320 deletions(-)
>  create mode 100644 app/test/test_lpm_routes.c
>  create mode 100644 app/test/test_lpm_routes.h
>  create mode 100644 app/test/v2.0/dcompat.h
>  create mode 100644 app/test/v2.0/rte_lpm.h
>  create mode 100644 app/test/v2.0/rte_lpm6.h
>  create mode 100644 app/test/v2.0/test_lpm.c
>  create mode 100644 app/test/v2.0/test_lpm6.c
>  create mode 100644 app/test/v2.0/test_lpm6_perf.c
>  create mode 100644 app/test/v2.0/test_lpm_perf.c
>  create mode 100644 app/test/v2.0/test_v20.c

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH 15/15] sched: remove redundant code
  @ 2019-08-23 14:46  4% ` Jasvinder Singh
    1 sibling, 0 replies; 200+ results
From: Jasvinder Singh @ 2019-08-23 14:46 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Remove redundant data structure fields from port level data
structures and update release notes.
---
 doc/guides/rel_notes/release_19_11.rst |  6 +++-
 lib/librte_sched/rte_sched.c           | 43 +-------------------------
 lib/librte_sched/rte_sched.h           | 22 -------------
 3 files changed, 6 insertions(+), 65 deletions(-)

diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 8490d897c..746aeb0ea 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -85,6 +85,10 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* sched: The pipe nodes configuration parameters such as number of pipes,
+  pipe queue sizes, pipe profiles, etc., are moved from port level structure
+  to subport level. This allows different subports of the same port to
+  have different configuration for the pipe nodes.
 
 ABI Changes
 -----------
@@ -172,7 +176,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_rcu.so.1
      librte_reorder.so.1
      librte_ring.so.2
-     librte_sched.so.3
+   + librte_sched.so.4
      librte_security.so.2
      librte_stack.so.1
      librte_table.so.3
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 8a7727286..ba504da1e 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -207,10 +207,8 @@ struct rte_sched_subport {
 struct rte_sched_port {
 	/* User parameters */
 	uint32_t n_subports_per_port;
-	uint32_t n_pipes_per_subport;
 	uint32_t n_max_pipes_per_subport;
 	uint32_t n_max_pipes_per_subport_log2;
-	uint32_t n_pipes_per_subport_log2;
 	uint16_t pipe_queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
 	uint8_t pipe_tc[RTE_SCHED_QUEUES_PER_PIPE];
 	uint8_t tc_queue[RTE_SCHED_QUEUES_PER_PIPE];
@@ -218,13 +216,7 @@ struct rte_sched_port {
 	uint32_t mtu;
 	uint32_t frame_overhead;
 	int socket;
-	uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
-	uint32_t n_pipe_profiles;
 	uint32_t n_max_pipe_profiles;
-	uint32_t pipe_tc_be_rate_max;
-#ifdef RTE_SCHED_RED
-	struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
-#endif
 
 	/* Timing */
 	uint64_t time_cpu_cycles;     /* Current CPU time measured in CPU cyles */
@@ -232,48 +224,15 @@ struct rte_sched_port {
 	uint64_t time;                /* Current NIC TX time measured in bytes */
 	struct rte_reciprocal inv_cycles_per_byte; /* CPU cycles per byte */
 
-	/* Scheduling loop detection */
-	uint32_t pipe_loop;
-	uint32_t pipe_exhaustion;
-
-	/* Bitmap */
-	struct rte_bitmap *bmp;
-	uint32_t grinder_base_bmp_pos[RTE_SCHED_PORT_N_GRINDERS] __rte_aligned_16;
-
 	/* Grinders */
-	struct rte_sched_grinder grinder[RTE_SCHED_PORT_N_GRINDERS];
-	uint32_t busy_grinders;
 	struct rte_mbuf **pkts_out;
 	uint32_t n_pkts_out;
 	uint32_t subport_id;
 
-	/* Queue base calculation */
-	uint32_t qsize_add[RTE_SCHED_QUEUES_PER_PIPE];
-	uint32_t qsize_sum;
-
 	/* Large data structures */
-	struct rte_sched_subport *subports[0];
-	struct rte_sched_subport *subport;
-	struct rte_sched_pipe *pipe;
-	struct rte_sched_queue *queue;
-	struct rte_sched_queue_extra *queue_extra;
-	struct rte_sched_pipe_profile *pipe_profiles;
-	uint8_t *bmp_array;
-	struct rte_mbuf **queue_array;
-	uint8_t memory[0] __rte_cache_aligned;
+	struct rte_sched_subport *subports[0] __rte_cache_aligned;
 } __rte_cache_aligned;
 
-enum rte_sched_port_array {
-	e_RTE_SCHED_PORT_ARRAY_SUBPORT = 0,
-	e_RTE_SCHED_PORT_ARRAY_PIPE,
-	e_RTE_SCHED_PORT_ARRAY_QUEUE,
-	e_RTE_SCHED_PORT_ARRAY_QUEUE_EXTRA,
-	e_RTE_SCHED_PORT_ARRAY_PIPE_PROFILES,
-	e_RTE_SCHED_PORT_ARRAY_BMP_ARRAY,
-	e_RTE_SCHED_PORT_ARRAY_QUEUE_ARRAY,
-	e_RTE_SCHED_PORT_ARRAY_TOTAL,
-};
-
 enum rte_sched_subport_array {
 	e_RTE_SCHED_SUBPORT_ARRAY_PIPE = 0,
 	e_RTE_SCHED_SUBPORT_ARRAY_QUEUE,
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index ea2b07448..db1b0232f 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -246,33 +246,11 @@ struct rte_sched_port_params {
 	/** Number of subports */
 	uint32_t n_subports_per_port;
 
-	/** Number of subport_pipes */
-	uint32_t n_pipes_per_subport;
-
 	/** Maximum number of subport_pipes */
 	uint32_t n_max_pipes_per_subport;
 
-	/** Packet queue size for each traffic class.
-	 * All the pipes within the same subport share the similar
-	 * configuration for the queues.
-	 */
-	uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
-
-	/** Pipe profile table.
-	 * Every pipe is configured using one of the profiles from this table.
-	 */
-	struct rte_sched_pipe_params *pipe_profiles;
-
-	/** Profiles in the pipe profile table */
-	uint32_t n_pipe_profiles;
-
 	/** Max profiles allowed in the pipe profile table */
 	uint32_t n_max_pipe_profiles;
-
-#ifdef RTE_SCHED_RED
-	/** RED parameters */
-	struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
-#endif
 };
 
 /*
-- 
2.21.0


^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 2/2] app/test: lpm abi version testing
  2019-08-22 16:07  9% [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test Ray Kinsella
  2019-08-22 16:07 14% ` [dpdk-dev] [PATCH v2 1/2] app/test: add abi version testing functionality Ray Kinsella
@ 2019-08-22 16:07  4% ` Ray Kinsella
  2019-08-23 15:49  4% ` [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test Aaron Conole
  2 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-22 16:07 UTC (permalink / raw)
  To: dev
  Cc: mdr, bruce.richardson, vladimir.medvedkin, john.mcnamara,
	marko.kovacevic

This second patch adds the LPM ABI version Unit Tests, comprised of

1. Registering DPDK v2.0 ABI versions with the infrastructure.
2. Forward Porting the DPDK v2.0 LPM Unit Test cases, remapping the LPM
   Library symbols to the appropriate versions. The unit tests are forward
   ported more or less on an as-it-was basis.
3. Refactoring the lpm perf routes table to make this functionality
   available to the v2.0 unit tests, forwarding porting this code also from
   v2.0 would have increased the DPDK codebase several MLoC.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 app/test/Makefile              |   12 +-
 app/test/meson.build           |    6 +
 app/test/test.h                |    4 -
 app/test/test_lpm.c            |    3 +-
 app/test/test_lpm6.c           |    2 +-
 app/test/test_lpm_perf.c       |  293 +-----
 app/test/test_lpm_routes.c     |  287 ++++++
 app/test/test_lpm_routes.h     |   25 +
 app/test/v2.0/dcompat.h        |   30 +
 app/test/v2.0/rte_lpm.h        |  451 ++++++++
 app/test/v2.0/rte_lpm6.h       |  198 ++++
 app/test/v2.0/test_lpm.c       | 1139 +++++++++++++++++++++
 app/test/v2.0/test_lpm6.c      | 1748 ++++++++++++++++++++++++++++++++
 app/test/v2.0/test_lpm6_perf.c |  179 ++++
 app/test/v2.0/test_lpm_perf.c  |  212 ++++
 app/test/v2.0/test_v20.c       |   14 +
 16 files changed, 4305 insertions(+), 298 deletions(-)
 create mode 100644 app/test/test_lpm_routes.c
 create mode 100644 app/test/test_lpm_routes.h
 create mode 100644 app/test/v2.0/dcompat.h
 create mode 100644 app/test/v2.0/rte_lpm.h
 create mode 100644 app/test/v2.0/rte_lpm6.h
 create mode 100644 app/test/v2.0/test_lpm.c
 create mode 100644 app/test/v2.0/test_lpm6.c
 create mode 100644 app/test/v2.0/test_lpm6_perf.c
 create mode 100644 app/test/v2.0/test_lpm_perf.c
 create mode 100644 app/test/v2.0/test_v20.c

diff --git a/app/test/Makefile b/app/test/Makefile
index 26ba6fe2b..8b2e0ca61 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -80,6 +80,8 @@ SRCS-y += test_ring.c
 SRCS-y += test_ring_perf.c
 SRCS-y += test_pmd_perf.c
 
+#ABI Version Testing
+SRCS-$(CONFIG_RTE_BUILD_SHARED_LIB) += v2.0/test_v20.c
 ifeq ($(CONFIG_RTE_LIBRTE_TABLE),y)
 SRCS-y += test_table.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += test_table_pipeline.c
@@ -109,7 +111,6 @@ SRCS-y += test_logs.c
 SRCS-y += test_memcpy.c
 SRCS-y += test_memcpy_perf.c
 
-
 SRCS-$(CONFIG_RTE_LIBRTE_MEMBER) += test_member.c
 SRCS-$(CONFIG_RTE_LIBRTE_MEMBER) += test_member_perf.c
 
@@ -124,11 +125,20 @@ SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_multiwriter.c
 SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_readwrite.c
 SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_readwrite_lf.c
 
+SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm_routes.c
 SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm.c
 SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm6.c
 SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm6_perf.c
 
+#LPM ABI Testing
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+SRCS-$(CONFIG_RTE_LIBRTE_LPM) += v2.0/test_lpm.c
+SRCS-$(CONFIG_RTE_LIBRTE_LPM) += v2.0/test_lpm_perf.c
+SRCS-$(CONFIG_RTE_LIBRTE_LPM) += v2.0/test_lpm6.c
+SRCS-$(CONFIG_RTE_LIBRTE_LPM) += v2.0/test_lpm6_perf.c
+endif
+
 SRCS-y += test_debug.c
 SRCS-y += test_errno.c
 SRCS-y += test_tailq.c
diff --git a/app/test/meson.build b/app/test/meson.build
index ec40943bd..a0c8d4611 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -8,6 +8,7 @@ endif
 test_sources = files('commands.c',
 	'packet_burst_generator.c',
 	'sample_packet_forward.c',
+	'v2.0/test_v20.c',
 	'test.c',
 	'test_acl.c',
 	'test_alarm.c',
@@ -68,6 +69,11 @@ test_sources = files('commands.c',
 	'test_lpm6.c',
 	'test_lpm6_perf.c',
 	'test_lpm_perf.c',
+	'test_lpm_routes.c',
+	'v2.0/test_lpm.c',
+	'v2.0/test_lpm_perf.c',
+	'v2.0/test_lpm6.c',
+	'v2.0/test_lpm6_perf.c',
 	'test_malloc.c',
 	'test_mbuf.c',
 	'test_member.c',
diff --git a/app/test/test.h b/app/test/test.h
index 5ec3728d0..dc95c4059 100644
--- a/app/test/test.h
+++ b/app/test/test.h
@@ -162,11 +162,7 @@ int test_set_rxtx_conf(cmdline_fixed_string_t mode);
 int test_set_rxtx_anchor(cmdline_fixed_string_t type);
 int test_set_rxtx_sc(cmdline_fixed_string_t type);
 
-#define MAP_ABI_SYMBOL_VERSION(name, abi_version)                             \
-	__asm(".symver "RTE_STR(name)","RTE_STR(name)"@"RTE_STR(abi_version))
-
 #define TEST_DPDK_ABI_VERSION_DEFAULT 0
-#define TEST_DPDK_ABI_VERSION_V1604   1
 #define TEST_DPDK_ABI_VERSION_V20     2
 #define TEST_DPDK_ABI_VERSION_MAX     3
 
diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c
index e969fe051..0a3233220 100644
--- a/app/test/test_lpm.c
+++ b/app/test/test_lpm.c
@@ -41,7 +41,7 @@ static int32_t test16(void);
 static int32_t test17(void);
 static int32_t test18(void);
 
-rte_lpm_test tests[] = {
+static rte_lpm_test tests[] = {
 /* Test Cases */
 	test0,
 	test1,
@@ -1277,6 +1277,7 @@ test_lpm(void)
 	int status, global_status = 0;
 
 	for (i = 0; i < NUM_LPM_TESTS; i++) {
+		printf("# test %02d\n", i);
 		status = tests[i]();
 		if (status < 0) {
 			printf("ERROR: LPM Test %u: FAIL\n", i);
diff --git a/app/test/test_lpm6.c b/app/test/test_lpm6.c
index 670aadb40..474e4014c 100644
--- a/app/test/test_lpm6.c
+++ b/app/test/test_lpm6.c
@@ -52,7 +52,7 @@ static int32_t test26(void);
 static int32_t test27(void);
 static int32_t test28(void);
 
-rte_lpm6_test tests6[] = {
+static rte_lpm6_test tests6[] = {
 /* Test Cases */
 	test0,
 	test1,
diff --git a/app/test/test_lpm_perf.c b/app/test/test_lpm_perf.c
index 77eea66ad..a6b8b35c2 100644
--- a/app/test/test_lpm_perf.c
+++ b/app/test/test_lpm_perf.c
@@ -5,7 +5,6 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
-#include <math.h>
 
 #include <rte_cycles.h>
 #include <rte_random.h>
@@ -13,6 +12,7 @@
 #include <rte_ip.h>
 #include <rte_lpm.h>
 
+#include "test_lpm_routes.h"
 #include "test.h"
 #include "test_xmmt_ops.h"
 
@@ -27,295 +27,6 @@
 #define BATCH_SIZE (1 << 12)
 #define BULK_SIZE 32
 
-#define MAX_RULE_NUM (1200000)
-
-struct route_rule {
-	uint32_t ip;
-	uint8_t depth;
-};
-
-struct route_rule large_route_table[MAX_RULE_NUM];
-
-static uint32_t num_route_entries;
-#define NUM_ROUTE_ENTRIES num_route_entries
-
-enum {
-	IP_CLASS_A,
-	IP_CLASS_B,
-	IP_CLASS_C
-};
-
-/* struct route_rule_count defines the total number of rules in following a/b/c
- * each item in a[]/b[]/c[] is the number of common IP address class A/B/C, not
- * including the ones for private local network.
- */
-struct route_rule_count {
-	uint32_t a[RTE_LPM_MAX_DEPTH];
-	uint32_t b[RTE_LPM_MAX_DEPTH];
-	uint32_t c[RTE_LPM_MAX_DEPTH];
-};
-
-/* All following numbers of each depth of each common IP class are just
- * got from previous large constant table in app/test/test_lpm_routes.h .
- * In order to match similar performance, they keep same depth and IP
- * address coverage as previous constant table. These numbers don't
- * include any private local IP address. As previous large const rule
- * table was just dumped from a real router, there are no any IP address
- * in class C or D.
- */
-static struct route_rule_count rule_count = {
-	.a = { /* IP class A in which the most significant bit is 0 */
-		    0, /* depth =  1 */
-		    0, /* depth =  2 */
-		    1, /* depth =  3 */
-		    0, /* depth =  4 */
-		    2, /* depth =  5 */
-		    1, /* depth =  6 */
-		    3, /* depth =  7 */
-		  185, /* depth =  8 */
-		   26, /* depth =  9 */
-		   16, /* depth = 10 */
-		   39, /* depth = 11 */
-		  144, /* depth = 12 */
-		  233, /* depth = 13 */
-		  528, /* depth = 14 */
-		  866, /* depth = 15 */
-		 3856, /* depth = 16 */
-		 3268, /* depth = 17 */
-		 5662, /* depth = 18 */
-		17301, /* depth = 19 */
-		22226, /* depth = 20 */
-		11147, /* depth = 21 */
-		16746, /* depth = 22 */
-		17120, /* depth = 23 */
-		77578, /* depth = 24 */
-		  401, /* depth = 25 */
-		  656, /* depth = 26 */
-		 1107, /* depth = 27 */
-		 1121, /* depth = 28 */
-		 2316, /* depth = 29 */
-		  717, /* depth = 30 */
-		   10, /* depth = 31 */
-		   66  /* depth = 32 */
-	},
-	.b = { /* IP class A in which the most 2 significant bits are 10 */
-		    0, /* depth =  1 */
-		    0, /* depth =  2 */
-		    0, /* depth =  3 */
-		    0, /* depth =  4 */
-		    1, /* depth =  5 */
-		    1, /* depth =  6 */
-		    1, /* depth =  7 */
-		    3, /* depth =  8 */
-		    3, /* depth =  9 */
-		   30, /* depth = 10 */
-		   25, /* depth = 11 */
-		  168, /* depth = 12 */
-		  305, /* depth = 13 */
-		  569, /* depth = 14 */
-		 1129, /* depth = 15 */
-		50800, /* depth = 16 */
-		 1645, /* depth = 17 */
-		 1820, /* depth = 18 */
-		 3506, /* depth = 19 */
-		 3258, /* depth = 20 */
-		 3424, /* depth = 21 */
-		 4971, /* depth = 22 */
-		 6885, /* depth = 23 */
-		39771, /* depth = 24 */
-		  424, /* depth = 25 */
-		  170, /* depth = 26 */
-		  433, /* depth = 27 */
-		   92, /* depth = 28 */
-		  366, /* depth = 29 */
-		  377, /* depth = 30 */
-		    2, /* depth = 31 */
-		  200  /* depth = 32 */
-	},
-	.c = { /* IP class A in which the most 3 significant bits are 110 */
-		     0, /* depth =  1 */
-		     0, /* depth =  2 */
-		     0, /* depth =  3 */
-		     0, /* depth =  4 */
-		     0, /* depth =  5 */
-		     0, /* depth =  6 */
-		     0, /* depth =  7 */
-		    12, /* depth =  8 */
-		     8, /* depth =  9 */
-		     9, /* depth = 10 */
-		    33, /* depth = 11 */
-		    69, /* depth = 12 */
-		   237, /* depth = 13 */
-		  1007, /* depth = 14 */
-		  1717, /* depth = 15 */
-		 14663, /* depth = 16 */
-		  8070, /* depth = 17 */
-		 16185, /* depth = 18 */
-		 48261, /* depth = 19 */
-		 36870, /* depth = 20 */
-		 33960, /* depth = 21 */
-		 50638, /* depth = 22 */
-		 61422, /* depth = 23 */
-		466549, /* depth = 24 */
-		  1829, /* depth = 25 */
-		  4824, /* depth = 26 */
-		  4927, /* depth = 27 */
-		  5914, /* depth = 28 */
-		 10254, /* depth = 29 */
-		  4905, /* depth = 30 */
-		     1, /* depth = 31 */
-		   716  /* depth = 32 */
-	}
-};
-
-static void generate_random_rule_prefix(uint32_t ip_class, uint8_t depth)
-{
-/* IP address class A, the most significant bit is 0 */
-#define IP_HEAD_MASK_A			0x00000000
-#define IP_HEAD_BIT_NUM_A		1
-
-/* IP address class B, the most significant 2 bits are 10 */
-#define IP_HEAD_MASK_B			0x80000000
-#define IP_HEAD_BIT_NUM_B		2
-
-/* IP address class C, the most significant 3 bits are 110 */
-#define IP_HEAD_MASK_C			0xC0000000
-#define IP_HEAD_BIT_NUM_C		3
-
-	uint32_t class_depth;
-	uint32_t range;
-	uint32_t mask;
-	uint32_t step;
-	uint32_t start;
-	uint32_t fixed_bit_num;
-	uint32_t ip_head_mask;
-	uint32_t rule_num;
-	uint32_t k;
-	struct route_rule *ptr_rule;
-
-	if (ip_class == IP_CLASS_A) {        /* IP Address class A */
-		fixed_bit_num = IP_HEAD_BIT_NUM_A;
-		ip_head_mask = IP_HEAD_MASK_A;
-		rule_num = rule_count.a[depth - 1];
-	} else if (ip_class == IP_CLASS_B) { /* IP Address class B */
-		fixed_bit_num = IP_HEAD_BIT_NUM_B;
-		ip_head_mask = IP_HEAD_MASK_B;
-		rule_num = rule_count.b[depth - 1];
-	} else {                             /* IP Address class C */
-		fixed_bit_num = IP_HEAD_BIT_NUM_C;
-		ip_head_mask = IP_HEAD_MASK_C;
-		rule_num = rule_count.c[depth - 1];
-	}
-
-	if (rule_num == 0)
-		return;
-
-	/* the number of rest bits which don't include the most significant
-	 * fixed bits for this IP address class
-	 */
-	class_depth = depth - fixed_bit_num;
-
-	/* range is the maximum number of rules for this depth and
-	 * this IP address class
-	 */
-	range = 1 << class_depth;
-
-	/* only mask the most depth significant generated bits
-	 * except fixed bits for IP address class
-	 */
-	mask = range - 1;
-
-	/* Widen coverage of IP address in generated rules */
-	if (range <= rule_num)
-		step = 1;
-	else
-		step = round((double)range / rule_num);
-
-	/* Only generate rest bits except the most significant
-	 * fixed bits for IP address class
-	 */
-	start = lrand48() & mask;
-	ptr_rule = &large_route_table[num_route_entries];
-	for (k = 0; k < rule_num; k++) {
-		ptr_rule->ip = (start << (RTE_LPM_MAX_DEPTH - depth))
-			| ip_head_mask;
-		ptr_rule->depth = depth;
-		ptr_rule++;
-		start = (start + step) & mask;
-	}
-	num_route_entries += rule_num;
-}
-
-static void insert_rule_in_random_pos(uint32_t ip, uint8_t depth)
-{
-	uint32_t pos;
-	int try_count = 0;
-	struct route_rule tmp;
-
-	do {
-		pos = lrand48();
-		try_count++;
-	} while ((try_count < 10) && (pos > num_route_entries));
-
-	if ((pos > num_route_entries) || (pos >= MAX_RULE_NUM))
-		pos = num_route_entries >> 1;
-
-	tmp = large_route_table[pos];
-	large_route_table[pos].ip = ip;
-	large_route_table[pos].depth = depth;
-	if (num_route_entries < MAX_RULE_NUM)
-		large_route_table[num_route_entries++] = tmp;
-}
-
-static void generate_large_route_rule_table(void)
-{
-	uint32_t ip_class;
-	uint8_t  depth;
-
-	num_route_entries = 0;
-	memset(large_route_table, 0, sizeof(large_route_table));
-
-	for (ip_class = IP_CLASS_A; ip_class <= IP_CLASS_C; ip_class++) {
-		for (depth = 1; depth <= RTE_LPM_MAX_DEPTH; depth++) {
-			generate_random_rule_prefix(ip_class, depth);
-		}
-	}
-
-	/* Add following rules to keep same as previous large constant table,
-	 * they are 4 rules with private local IP address and 1 all-zeros prefix
-	 * with depth = 8.
-	 */
-	insert_rule_in_random_pos(RTE_IPV4(0, 0, 0, 0), 8);
-	insert_rule_in_random_pos(RTE_IPV4(10, 2, 23, 147), 32);
-	insert_rule_in_random_pos(RTE_IPV4(192, 168, 100, 10), 24);
-	insert_rule_in_random_pos(RTE_IPV4(192, 168, 25, 100), 24);
-	insert_rule_in_random_pos(RTE_IPV4(192, 168, 129, 124), 32);
-}
-
-static void
-print_route_distribution(const struct route_rule *table, uint32_t n)
-{
-	unsigned i, j;
-
-	printf("Route distribution per prefix width: \n");
-	printf("DEPTH    QUANTITY (PERCENT)\n");
-	printf("--------------------------- \n");
-
-	/* Count depths. */
-	for (i = 1; i <= 32; i++) {
-		unsigned depth_counter = 0;
-		double percent_hits;
-
-		for (j = 0; j < n; j++)
-			if (table[j].depth == (uint8_t) i)
-				depth_counter++;
-
-		percent_hits = ((double)depth_counter)/((double)n) * 100;
-		printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits);
-	}
-	printf("\n");
-}
-
 static int
 test_lpm_perf(void)
 {
@@ -375,7 +86,7 @@ test_lpm_perf(void)
 			(unsigned) cache_line_counter, (unsigned) cache_line_counter * 64);
 
 	printf("Average LPM Add: %g cycles\n",
-			(double)total_time / NUM_ROUTE_ENTRIES);
+	       (double)total_time / NUM_ROUTE_ENTRIES);
 
 	/* Measure single Lookup */
 	total_time = 0;
diff --git a/app/test/test_lpm_routes.c b/app/test/test_lpm_routes.c
new file mode 100644
index 000000000..edd1eba1b
--- /dev/null
+++ b/app/test/test_lpm_routes.c
@@ -0,0 +1,287 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ */
+
+#include <math.h>
+
+#include "rte_lpm.h"
+#include "test_lpm_routes.h"
+
+uint32_t num_route_entries;
+struct route_rule large_route_table[MAX_RULE_NUM];
+
+enum {
+	IP_CLASS_A,
+	IP_CLASS_B,
+	IP_CLASS_C
+};
+
+/* struct route_rule_count defines the total number of rules in following a/b/c
+ * each item in a[]/b[]/c[] is the number of common IP address class A/B/C, not
+ * including the ones for private local network.
+ */
+struct route_rule_count {
+	uint32_t a[RTE_LPM_MAX_DEPTH];
+	uint32_t b[RTE_LPM_MAX_DEPTH];
+	uint32_t c[RTE_LPM_MAX_DEPTH];
+};
+
+/* All following numbers of each depth of each common IP class are just
+ * got from previous large constant table in app/test/test_lpm_routes.h .
+ * In order to match similar performance, they keep same depth and IP
+ * address coverage as previous constant table. These numbers don't
+ * include any private local IP address. As previous large const rule
+ * table was just dumped from a real router, there are no any IP address
+ * in class C or D.
+ */
+static struct route_rule_count rule_count = {
+	.a = { /* IP class A in which the most significant bit is 0 */
+		    0, /* depth =  1 */
+		    0, /* depth =  2 */
+		    1, /* depth =  3 */
+		    0, /* depth =  4 */
+		    2, /* depth =  5 */
+		    1, /* depth =  6 */
+		    3, /* depth =  7 */
+		  185, /* depth =  8 */
+		   26, /* depth =  9 */
+		   16, /* depth = 10 */
+		   39, /* depth = 11 */
+		  144, /* depth = 12 */
+		  233, /* depth = 13 */
+		  528, /* depth = 14 */
+		  866, /* depth = 15 */
+		 3856, /* depth = 16 */
+		 3268, /* depth = 17 */
+		 5662, /* depth = 18 */
+		17301, /* depth = 19 */
+		22226, /* depth = 20 */
+		11147, /* depth = 21 */
+		16746, /* depth = 22 */
+		17120, /* depth = 23 */
+		77578, /* depth = 24 */
+		  401, /* depth = 25 */
+		  656, /* depth = 26 */
+		 1107, /* depth = 27 */
+		 1121, /* depth = 28 */
+		 2316, /* depth = 29 */
+		  717, /* depth = 30 */
+		   10, /* depth = 31 */
+		   66  /* depth = 32 */
+	},
+	.b = { /* IP class A in which the most 2 significant bits are 10 */
+		    0, /* depth =  1 */
+		    0, /* depth =  2 */
+		    0, /* depth =  3 */
+		    0, /* depth =  4 */
+		    1, /* depth =  5 */
+		    1, /* depth =  6 */
+		    1, /* depth =  7 */
+		    3, /* depth =  8 */
+		    3, /* depth =  9 */
+		   30, /* depth = 10 */
+		   25, /* depth = 11 */
+		  168, /* depth = 12 */
+		  305, /* depth = 13 */
+		  569, /* depth = 14 */
+		 1129, /* depth = 15 */
+		50800, /* depth = 16 */
+		 1645, /* depth = 17 */
+		 1820, /* depth = 18 */
+		 3506, /* depth = 19 */
+		 3258, /* depth = 20 */
+		 3424, /* depth = 21 */
+		 4971, /* depth = 22 */
+		 6885, /* depth = 23 */
+		39771, /* depth = 24 */
+		  424, /* depth = 25 */
+		  170, /* depth = 26 */
+		  433, /* depth = 27 */
+		   92, /* depth = 28 */
+		  366, /* depth = 29 */
+		  377, /* depth = 30 */
+		    2, /* depth = 31 */
+		  200  /* depth = 32 */
+	},
+	.c = { /* IP class A in which the most 3 significant bits are 110 */
+		     0, /* depth =  1 */
+		     0, /* depth =  2 */
+		     0, /* depth =  3 */
+		     0, /* depth =  4 */
+		     0, /* depth =  5 */
+		     0, /* depth =  6 */
+		     0, /* depth =  7 */
+		    12, /* depth =  8 */
+		     8, /* depth =  9 */
+		     9, /* depth = 10 */
+		    33, /* depth = 11 */
+		    69, /* depth = 12 */
+		   237, /* depth = 13 */
+		  1007, /* depth = 14 */
+		  1717, /* depth = 15 */
+		 14663, /* depth = 16 */
+		  8070, /* depth = 17 */
+		 16185, /* depth = 18 */
+		 48261, /* depth = 19 */
+		 36870, /* depth = 20 */
+		 33960, /* depth = 21 */
+		 50638, /* depth = 22 */
+		 61422, /* depth = 23 */
+		466549, /* depth = 24 */
+		  1829, /* depth = 25 */
+		  4824, /* depth = 26 */
+		  4927, /* depth = 27 */
+		  5914, /* depth = 28 */
+		 10254, /* depth = 29 */
+		  4905, /* depth = 30 */
+		     1, /* depth = 31 */
+		   716  /* depth = 32 */
+	}
+};
+
+static void generate_random_rule_prefix(uint32_t ip_class, uint8_t depth)
+{
+/* IP address class A, the most significant bit is 0 */
+#define IP_HEAD_MASK_A			0x00000000
+#define IP_HEAD_BIT_NUM_A		1
+
+/* IP address class B, the most significant 2 bits are 10 */
+#define IP_HEAD_MASK_B			0x80000000
+#define IP_HEAD_BIT_NUM_B		2
+
+/* IP address class C, the most significant 3 bits are 110 */
+#define IP_HEAD_MASK_C			0xC0000000
+#define IP_HEAD_BIT_NUM_C		3
+
+	uint32_t class_depth;
+	uint32_t range;
+	uint32_t mask;
+	uint32_t step;
+	uint32_t start;
+	uint32_t fixed_bit_num;
+	uint32_t ip_head_mask;
+	uint32_t rule_num;
+	uint32_t k;
+	struct route_rule *ptr_rule;
+
+	if (ip_class == IP_CLASS_A) {        /* IP Address class A */
+		fixed_bit_num = IP_HEAD_BIT_NUM_A;
+		ip_head_mask = IP_HEAD_MASK_A;
+		rule_num = rule_count.a[depth - 1];
+	} else if (ip_class == IP_CLASS_B) { /* IP Address class B */
+		fixed_bit_num = IP_HEAD_BIT_NUM_B;
+		ip_head_mask = IP_HEAD_MASK_B;
+		rule_num = rule_count.b[depth - 1];
+	} else {                             /* IP Address class C */
+		fixed_bit_num = IP_HEAD_BIT_NUM_C;
+		ip_head_mask = IP_HEAD_MASK_C;
+		rule_num = rule_count.c[depth - 1];
+	}
+
+	if (rule_num == 0)
+		return;
+
+	/* the number of rest bits which don't include the most significant
+	 * fixed bits for this IP address class
+	 */
+	class_depth = depth - fixed_bit_num;
+
+	/* range is the maximum number of rules for this depth and
+	 * this IP address class
+	 */
+	range = 1 << class_depth;
+
+	/* only mask the most depth significant generated bits
+	 * except fixed bits for IP address class
+	 */
+	mask = range - 1;
+
+	/* Widen coverage of IP address in generated rules */
+	if (range <= rule_num)
+		step = 1;
+	else
+		step = round((double)range / rule_num);
+
+	/* Only generate rest bits except the most significant
+	 * fixed bits for IP address class
+	 */
+	start = lrand48() & mask;
+	ptr_rule = &large_route_table[num_route_entries];
+	for (k = 0; k < rule_num; k++) {
+		ptr_rule->ip = (start << (RTE_LPM_MAX_DEPTH - depth))
+			| ip_head_mask;
+		ptr_rule->depth = depth;
+		ptr_rule++;
+		start = (start + step) & mask;
+	}
+	num_route_entries += rule_num;
+}
+
+static void insert_rule_in_random_pos(uint32_t ip, uint8_t depth)
+{
+	uint32_t pos;
+	int try_count = 0;
+	struct route_rule tmp;
+
+	do {
+		pos = lrand48();
+		try_count++;
+	} while ((try_count < 10) && (pos > num_route_entries));
+
+	if ((pos > num_route_entries) || (pos >= MAX_RULE_NUM))
+		pos = num_route_entries >> 1;
+
+	tmp = large_route_table[pos];
+	large_route_table[pos].ip = ip;
+	large_route_table[pos].depth = depth;
+	if (num_route_entries < MAX_RULE_NUM)
+		large_route_table[num_route_entries++] = tmp;
+}
+
+void generate_large_route_rule_table(void)
+{
+	uint32_t ip_class;
+	uint8_t  depth;
+
+	num_route_entries = 0;
+	memset(large_route_table, 0, sizeof(large_route_table));
+
+	for (ip_class = IP_CLASS_A; ip_class <= IP_CLASS_C; ip_class++) {
+		for (depth = 1; depth <= RTE_LPM_MAX_DEPTH; depth++)
+			generate_random_rule_prefix(ip_class, depth);
+	}
+
+	/* Add following rules to keep same as previous large constant table,
+	 * they are 4 rules with private local IP address and 1 all-zeros prefix
+	 * with depth = 8.
+	 */
+	insert_rule_in_random_pos(RTE_IPV4(0, 0, 0, 0), 8);
+	insert_rule_in_random_pos(RTE_IPV4(10, 2, 23, 147), 32);
+	insert_rule_in_random_pos(RTE_IPV4(192, 168, 100, 10), 24);
+	insert_rule_in_random_pos(RTE_IPV4(192, 168, 25, 100), 24);
+	insert_rule_in_random_pos(RTE_IPV4(192, 168, 129, 124), 32);
+}
+
+void
+print_route_distribution(const struct route_rule *table, uint32_t n)
+{
+	unsigned int i, j;
+
+	printf("Route distribution per prefix width:\n");
+	printf("DEPTH    QUANTITY (PERCENT)\n");
+	printf("---------------------------\n");
+
+	/* Count depths. */
+	for (i = 1; i <= 32; i++) {
+		unsigned int depth_counter = 0;
+		double percent_hits;
+
+		for (j = 0; j < n; j++)
+			if (table[j].depth == (uint8_t) i)
+				depth_counter++;
+
+		percent_hits = ((double)depth_counter)/((double)n) * 100;
+		printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits);
+	}
+	printf("\n");
+}
diff --git a/app/test/test_lpm_routes.h b/app/test/test_lpm_routes.h
new file mode 100644
index 000000000..c7874ea8f
--- /dev/null
+++ b/app/test/test_lpm_routes.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ */
+
+#ifndef _TEST_LPM_ROUTES_H_
+#define _TEST_LPM_ROUTES_H_
+
+#include <rte_ip.h>
+
+#define MAX_RULE_NUM (1200000)
+
+struct route_rule {
+	uint32_t ip;
+	uint8_t depth;
+};
+
+extern struct route_rule large_route_table[MAX_RULE_NUM];
+
+extern uint32_t num_route_entries;
+#define NUM_ROUTE_ENTRIES num_route_entries
+
+void generate_large_route_rule_table(void);
+void print_route_distribution(const struct route_rule *table, uint32_t n);
+
+#endif
diff --git a/app/test/v2.0/dcompat.h b/app/test/v2.0/dcompat.h
new file mode 100644
index 000000000..e66206156
--- /dev/null
+++ b/app/test/v2.0/dcompat.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ */
+
+#ifndef _DCOMPAT_H_
+#define _DCOMPAT_H_
+
+#include <rte_compat.h>
+
+#define ABI_VERSION 2.0
+
+#define MAP_ABI_SYMBOL(name) \
+	BIND_VERSION_SYMBOL(name, ABI_VERSION)
+
+MAP_ABI_SYMBOL(rte_lpm_add);
+MAP_ABI_SYMBOL(rte_lpm_find_existing);
+MAP_ABI_SYMBOL(rte_lpm_create);
+MAP_ABI_SYMBOL(rte_lpm_free);
+MAP_ABI_SYMBOL(rte_lpm_is_rule_present);
+MAP_ABI_SYMBOL(rte_lpm_delete);
+MAP_ABI_SYMBOL(rte_lpm_delete_all);
+
+MAP_ABI_SYMBOL(rte_lpm6_add);
+MAP_ABI_SYMBOL(rte_lpm6_is_rule_present);
+MAP_ABI_SYMBOL(rte_lpm6_lookup);
+MAP_ABI_SYMBOL(rte_lpm6_lookup_bulk_func);
+
+#undef MAP_ABI_SYMBOL
+
+#endif
diff --git a/app/test/v2.0/rte_lpm.h b/app/test/v2.0/rte_lpm.h
new file mode 100644
index 000000000..5e05015cb
--- /dev/null
+++ b/app/test/v2.0/rte_lpm.h
@@ -0,0 +1,451 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#ifndef _RTE_LPM_H_
+#define _RTE_LPM_H_
+
+/**
+ * @file
+ * RTE Longest Prefix Match (LPM)
+ */
+
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <rte_branch_prediction.h>
+#include <rte_byteorder.h>
+#include <rte_memory.h>
+#include <rte_common.h>
+#include <rte_vect.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Max number of characters in LPM name. */
+#define RTE_LPM_NAMESIZE                32
+
+/** Maximum depth value possible for IPv4 LPM. */
+#define RTE_LPM_MAX_DEPTH               32
+
+/** @internal Total number of tbl24 entries. */
+#define RTE_LPM_TBL24_NUM_ENTRIES       (1 << 24)
+
+/** @internal Number of entries in a tbl8 group. */
+#define RTE_LPM_TBL8_GROUP_NUM_ENTRIES  256
+
+/** @internal Total number of tbl8 groups in the tbl8. */
+#define RTE_LPM_TBL8_NUM_GROUPS         256
+
+/** @internal Total number of tbl8 entries. */
+#define RTE_LPM_TBL8_NUM_ENTRIES        (RTE_LPM_TBL8_NUM_GROUPS * \
+					RTE_LPM_TBL8_GROUP_NUM_ENTRIES)
+
+/** @internal Macro to enable/disable run-time checks. */
+#if defined(RTE_LIBRTE_LPM_DEBUG)
+#define RTE_LPM_RETURN_IF_TRUE(cond, retval) do { \
+	if (cond) return (retval);                \
+} while (0)
+#else
+#define RTE_LPM_RETURN_IF_TRUE(cond, retval)
+#endif
+
+/** @internal bitmask with valid and ext_entry/valid_group fields set */
+#define RTE_LPM_VALID_EXT_ENTRY_BITMASK 0x0300
+
+/** Bitmask used to indicate successful lookup */
+#define RTE_LPM_LOOKUP_SUCCESS          0x0100
+
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+/** @internal Tbl24 entry structure. */
+struct rte_lpm_tbl24_entry {
+	/* Stores Next hop or group index (i.e. gindex)into tbl8. */
+	union {
+		uint8_t next_hop;
+		uint8_t tbl8_gindex;
+	};
+	/* Using single uint8_t to store 3 values. */
+	uint8_t valid     :1; /**< Validation flag. */
+	uint8_t ext_entry :1; /**< External entry. */
+	uint8_t depth     :6; /**< Rule depth. */
+};
+
+/** @internal Tbl8 entry structure. */
+struct rte_lpm_tbl8_entry {
+	uint8_t next_hop; /**< next hop. */
+	/* Using single uint8_t to store 3 values. */
+	uint8_t valid       :1; /**< Validation flag. */
+	uint8_t valid_group :1; /**< Group validation flag. */
+	uint8_t depth       :6; /**< Rule depth. */
+};
+#else
+struct rte_lpm_tbl24_entry {
+	uint8_t depth       :6;
+	uint8_t ext_entry   :1;
+	uint8_t valid       :1;
+	union {
+		uint8_t tbl8_gindex;
+		uint8_t next_hop;
+	};
+};
+
+struct rte_lpm_tbl8_entry {
+	uint8_t depth       :6;
+	uint8_t valid_group :1;
+	uint8_t valid       :1;
+	uint8_t next_hop;
+};
+#endif
+
+/** @internal Rule structure. */
+struct rte_lpm_rule {
+	uint32_t ip; /**< Rule IP address. */
+	uint8_t  next_hop; /**< Rule next hop. */
+};
+
+/** @internal Contains metadata about the rules table. */
+struct rte_lpm_rule_info {
+	uint32_t used_rules; /**< Used rules so far. */
+	uint32_t first_rule; /**< Indexes the first rule of a given depth. */
+};
+
+/** @internal LPM structure. */
+struct rte_lpm {
+	/* LPM metadata. */
+	char name[RTE_LPM_NAMESIZE];        /**< Name of the lpm. */
+	uint32_t max_rules; /**< Max. balanced rules per lpm. */
+	struct rte_lpm_rule_info rule_info[RTE_LPM_MAX_DEPTH]; /**< Rule info table. */
+
+	/* LPM Tables. */
+	struct rte_lpm_tbl24_entry tbl24[RTE_LPM_TBL24_NUM_ENTRIES] \
+			__rte_cache_aligned; /**< LPM tbl24 table. */
+	struct rte_lpm_tbl8_entry tbl8[RTE_LPM_TBL8_NUM_ENTRIES] \
+			__rte_cache_aligned; /**< LPM tbl8 table. */
+	struct rte_lpm_rule rules_tbl[0] \
+			__rte_cache_aligned; /**< LPM rules. */
+};
+
+/**
+ * Create an LPM object.
+ *
+ * @param name
+ *   LPM object name
+ * @param socket_id
+ *   NUMA socket ID for LPM table memory allocation
+ * @param max_rules
+ *   Maximum number of LPM rules that can be added
+ * @param flags
+ *   This parameter is currently unused
+ * @return
+ *   Handle to LPM object on success, NULL otherwise with rte_errno set
+ *   to an appropriate values. Possible rte_errno values include:
+ *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ *    - E_RTE_SECONDARY - function was called from a secondary process instance
+ *    - EINVAL - invalid parameter passed to function
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a memzone with the same name already exists
+ *    - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+struct rte_lpm *
+rte_lpm_create(const char *name, int socket_id, int max_rules, int flags);
+
+/**
+ * Find an existing LPM object and return a pointer to it.
+ *
+ * @param name
+ *   Name of the lpm object as passed to rte_lpm_create()
+ * @return
+ *   Pointer to lpm object or NULL if object not found with rte_errno
+ *   set appropriately. Possible rte_errno values include:
+ *    - ENOENT - required entry not available to return.
+ */
+struct rte_lpm *
+rte_lpm_find_existing(const char *name);
+
+/**
+ * Free an LPM object.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @return
+ *   None
+ */
+void
+rte_lpm_free(struct rte_lpm *lpm);
+
+/**
+ * Add a rule to the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP of the rule to be added to the LPM table
+ * @param depth
+ *   Depth of the rule to be added to the LPM table
+ * @param next_hop
+ *   Next hop of the rule to be added to the LPM table
+ * @return
+ *   0 on success, negative value otherwise
+ */
+int
+rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint8_t next_hop);
+
+/**
+ * Check if a rule is present in the LPM table,
+ * and provide its next hop if it is.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP of the rule to be searched
+ * @param depth
+ *   Depth of the rule to searched
+ * @param next_hop
+ *   Next hop of the rule (valid only if it is found)
+ * @return
+ *   1 if the rule exists, 0 if it does not, a negative value on failure
+ */
+int
+rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+uint8_t *next_hop);
+
+/**
+ * Delete a rule from the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP of the rule to be deleted from the LPM table
+ * @param depth
+ *   Depth of the rule to be deleted from the LPM table
+ * @return
+ *   0 on success, negative value otherwise
+ */
+int
+rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
+
+/**
+ * Delete all rules from the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ */
+void
+rte_lpm_delete_all(struct rte_lpm *lpm);
+
+/**
+ * Lookup an IP into the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP to be looked up in the LPM table
+ * @param next_hop
+ *   Next hop of the most specific rule found for IP (valid on lookup hit only)
+ * @return
+ *   -EINVAL for incorrect arguments, -ENOENT on lookup miss, 0 on lookup hit
+ */
+static inline int
+rte_lpm_lookup(struct rte_lpm *lpm, uint32_t ip, uint8_t *next_hop)
+{
+	unsigned tbl24_index = (ip >> 8);
+	uint16_t tbl_entry;
+
+	/* DEBUG: Check user input arguments. */
+	RTE_LPM_RETURN_IF_TRUE(((lpm == NULL) || (next_hop == NULL)), -EINVAL);
+
+	/* Copy tbl24 entry */
+	tbl_entry = *(const uint16_t *)&lpm->tbl24[tbl24_index];
+
+	/* Copy tbl8 entry (only if needed) */
+	if (unlikely((tbl_entry & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+
+		unsigned tbl8_index = (uint8_t)ip +
+				((uint8_t)tbl_entry * RTE_LPM_TBL8_GROUP_NUM_ENTRIES);
+
+		tbl_entry = *(const uint16_t *)&lpm->tbl8[tbl8_index];
+	}
+
+	*next_hop = (uint8_t)tbl_entry;
+	return (tbl_entry & RTE_LPM_LOOKUP_SUCCESS) ? 0 : -ENOENT;
+}
+
+/**
+ * Lookup multiple IP addresses in an LPM table. This may be implemented as a
+ * macro, so the address of the function should not be used.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ips
+ *   Array of IPs to be looked up in the LPM table
+ * @param next_hops
+ *   Next hop of the most specific rule found for IP (valid on lookup hit only).
+ *   This is an array of two byte values. The most significant byte in each
+ *   value says whether the lookup was successful (bitmask
+ *   RTE_LPM_LOOKUP_SUCCESS is set). The least significant byte is the
+ *   actual next hop.
+ * @param n
+ *   Number of elements in ips (and next_hops) array to lookup. This should be a
+ *   compile time constant, and divisible by 8 for best performance.
+ *  @return
+ *   -EINVAL for incorrect arguments, otherwise 0
+ */
+#define rte_lpm_lookup_bulk(lpm, ips, next_hops, n) \
+		rte_lpm_lookup_bulk_func(lpm, ips, next_hops, n)
+
+static inline int
+rte_lpm_lookup_bulk_func(const struct rte_lpm *lpm, const uint32_t * ips,
+		uint16_t * next_hops, const unsigned n)
+{
+	unsigned i;
+	unsigned tbl24_indexes[n];
+
+	/* DEBUG: Check user input arguments. */
+	RTE_LPM_RETURN_IF_TRUE(((lpm == NULL) || (ips == NULL) ||
+			(next_hops == NULL)), -EINVAL);
+
+	for (i = 0; i < n; i++) {
+		tbl24_indexes[i] = ips[i] >> 8;
+	}
+
+	for (i = 0; i < n; i++) {
+		/* Simply copy tbl24 entry to output */
+		next_hops[i] = *(const uint16_t *)&lpm->tbl24[tbl24_indexes[i]];
+
+		/* Overwrite output with tbl8 entry if needed */
+		if (unlikely((next_hops[i] & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+				RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+
+			unsigned tbl8_index = (uint8_t)ips[i] +
+					((uint8_t)next_hops[i] *
+					 RTE_LPM_TBL8_GROUP_NUM_ENTRIES);
+
+			next_hops[i] = *(const uint16_t *)&lpm->tbl8[tbl8_index];
+		}
+	}
+	return 0;
+}
+
+/* Mask four results. */
+#define	 RTE_LPM_MASKX4_RES	UINT64_C(0x00ff00ff00ff00ff)
+
+/**
+ * Lookup four IP addresses in an LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   Four IPs to be looked up in the LPM table
+ * @param hop
+ *   Next hop of the most specific rule found for IP (valid on lookup hit only).
+ *   This is an 4 elements array of two byte values.
+ *   If the lookup was succesfull for the given IP, then least significant byte
+ *   of the corresponding element is the  actual next hop and the most
+ *   significant byte is zero.
+ *   If the lookup for the given IP failed, then corresponding element would
+ *   contain default value, see description of then next parameter.
+ * @param defv
+ *   Default value to populate into corresponding element of hop[] array,
+ *   if lookup would fail.
+ */
+static inline void
+rte_lpm_lookupx4(const struct rte_lpm *lpm, __m128i ip, uint16_t hop[4],
+	uint16_t defv)
+{
+	__m128i i24;
+	rte_xmm_t i8;
+	uint16_t tbl[4];
+	uint64_t idx, pt;
+
+	const __m128i mask8 =
+		_mm_set_epi32(UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX);
+
+	/*
+	 * RTE_LPM_VALID_EXT_ENTRY_BITMASK for 4 LPM entries
+	 * as one 64-bit value (0x0300030003000300).
+	 */
+	const uint64_t mask_xv =
+		((uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK |
+		(uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 16 |
+		(uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 32 |
+		(uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 48);
+
+	/*
+	 * RTE_LPM_LOOKUP_SUCCESS for 4 LPM entries
+	 * as one 64-bit value (0x0100010001000100).
+	 */
+	const uint64_t mask_v =
+		((uint64_t)RTE_LPM_LOOKUP_SUCCESS |
+		(uint64_t)RTE_LPM_LOOKUP_SUCCESS << 16 |
+		(uint64_t)RTE_LPM_LOOKUP_SUCCESS << 32 |
+		(uint64_t)RTE_LPM_LOOKUP_SUCCESS << 48);
+
+	/* get 4 indexes for tbl24[]. */
+	i24 = _mm_srli_epi32(ip, CHAR_BIT);
+
+	/* extract values from tbl24[] */
+	idx = _mm_cvtsi128_si64(i24);
+	i24 = _mm_srli_si128(i24, sizeof(uint64_t));
+
+	tbl[0] = *(const uint16_t *)&lpm->tbl24[(uint32_t)idx];
+	tbl[1] = *(const uint16_t *)&lpm->tbl24[idx >> 32];
+
+	idx = _mm_cvtsi128_si64(i24);
+
+	tbl[2] = *(const uint16_t *)&lpm->tbl24[(uint32_t)idx];
+	tbl[3] = *(const uint16_t *)&lpm->tbl24[idx >> 32];
+
+	/* get 4 indexes for tbl8[]. */
+	i8.x = _mm_and_si128(ip, mask8);
+
+	pt = (uint64_t)tbl[0] |
+		(uint64_t)tbl[1] << 16 |
+		(uint64_t)tbl[2] << 32 |
+		(uint64_t)tbl[3] << 48;
+
+	/* search successfully finished for all 4 IP addresses. */
+	if (likely((pt & mask_xv) == mask_v)) {
+		uintptr_t ph = (uintptr_t)hop;
+		*(uint64_t *)ph = pt & RTE_LPM_MASKX4_RES;
+		return;
+	}
+
+	if (unlikely((pt & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+		i8.u32[0] = i8.u32[0] +
+			(uint8_t)tbl[0] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
+		tbl[0] = *(const uint16_t *)&lpm->tbl8[i8.u32[0]];
+	}
+	if (unlikely((pt >> 16 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+		i8.u32[1] = i8.u32[1] +
+			(uint8_t)tbl[1] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
+		tbl[1] = *(const uint16_t *)&lpm->tbl8[i8.u32[1]];
+	}
+	if (unlikely((pt >> 32 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+		i8.u32[2] = i8.u32[2] +
+			(uint8_t)tbl[2] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
+		tbl[2] = *(const uint16_t *)&lpm->tbl8[i8.u32[2]];
+	}
+	if (unlikely((pt >> 48 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+		i8.u32[3] = i8.u32[3] +
+			(uint8_t)tbl[3] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
+		tbl[3] = *(const uint16_t *)&lpm->tbl8[i8.u32[3]];
+	}
+
+	hop[0] = (tbl[0] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[0] : defv;
+	hop[1] = (tbl[1] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[1] : defv;
+	hop[2] = (tbl[2] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[2] : defv;
+	hop[3] = (tbl[3] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[3] : defv;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_LPM_H_ */
diff --git a/app/test/v2.0/rte_lpm6.h b/app/test/v2.0/rte_lpm6.h
new file mode 100644
index 000000000..4892a84e4
--- /dev/null
+++ b/app/test/v2.0/rte_lpm6.h
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+#ifndef _RTE_LPM6_H_
+#define _RTE_LPM6_H_
+
+/**
+ * @file
+ * RTE Longest Prefix Match for IPv6 (LPM6)
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define RTE_LPM6_MAX_DEPTH               128
+#define RTE_LPM6_IPV6_ADDR_SIZE           16
+/** Max number of characters in LPM name. */
+#define RTE_LPM6_NAMESIZE                 32
+
+/** LPM structure. */
+struct rte_lpm6;
+
+/** LPM configuration structure. */
+struct rte_lpm6_config {
+	uint32_t max_rules;      /**< Max number of rules. */
+	uint32_t number_tbl8s;   /**< Number of tbl8s to allocate. */
+	int flags;               /**< This field is currently unused. */
+};
+
+/**
+ * Create an LPM object.
+ *
+ * @param name
+ *   LPM object name
+ * @param socket_id
+ *   NUMA socket ID for LPM table memory allocation
+ * @param config
+ *   Structure containing the configuration
+ * @return
+ *   Handle to LPM object on success, NULL otherwise with rte_errno set
+ *   to an appropriate values. Possible rte_errno values include:
+ *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ *    - E_RTE_SECONDARY - function was called from a secondary process instance
+ *    - EINVAL - invalid parameter passed to function
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a memzone with the same name already exists
+ *    - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+struct rte_lpm6 *
+rte_lpm6_create(const char *name, int socket_id,
+		const struct rte_lpm6_config *config);
+
+/**
+ * Find an existing LPM object and return a pointer to it.
+ *
+ * @param name
+ *   Name of the lpm object as passed to rte_lpm6_create()
+ * @return
+ *   Pointer to lpm object or NULL if object not found with rte_errno
+ *   set appropriately. Possible rte_errno values include:
+ *    - ENOENT - required entry not available to return.
+ */
+struct rte_lpm6 *
+rte_lpm6_find_existing(const char *name);
+
+/**
+ * Free an LPM object.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @return
+ *   None
+ */
+void
+rte_lpm6_free(struct rte_lpm6 *lpm);
+
+/**
+ * Add a rule to the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP of the rule to be added to the LPM table
+ * @param depth
+ *   Depth of the rule to be added to the LPM table
+ * @param next_hop
+ *   Next hop of the rule to be added to the LPM table
+ * @return
+ *   0 on success, negative value otherwise
+ */
+int
+rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+		uint8_t next_hop);
+
+/**
+ * Check if a rule is present in the LPM table,
+ * and provide its next hop if it is.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP of the rule to be searched
+ * @param depth
+ *   Depth of the rule to searched
+ * @param next_hop
+ *   Next hop of the rule (valid only if it is found)
+ * @return
+ *   1 if the rule exists, 0 if it does not, a negative value on failure
+ */
+int
+rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+uint8_t *next_hop);
+
+/**
+ * Delete a rule from the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP of the rule to be deleted from the LPM table
+ * @param depth
+ *   Depth of the rule to be deleted from the LPM table
+ * @return
+ *   0 on success, negative value otherwise
+ */
+int
+rte_lpm6_delete(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth);
+
+/**
+ * Delete a rule from the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ips
+ *   Array of IPs to be deleted from the LPM table
+ * @param depths
+ *   Array of depths of the rules to be deleted from the LPM table
+ * @param n
+ *   Number of rules to be deleted from the LPM table
+ * @return
+ *   0 on success, negative value otherwise.
+ */
+int
+rte_lpm6_delete_bulk_func(struct rte_lpm6 *lpm,
+		uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], uint8_t *depths, unsigned n);
+
+/**
+ * Delete all rules from the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ */
+void
+rte_lpm6_delete_all(struct rte_lpm6 *lpm);
+
+/**
+ * Lookup an IP into the LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ip
+ *   IP to be looked up in the LPM table
+ * @param next_hop
+ *   Next hop of the most specific rule found for IP (valid on lookup hit only)
+ * @return
+ *   -EINVAL for incorrect arguments, -ENOENT on lookup miss, 0 on lookup hit
+ */
+int
+rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop);
+
+/**
+ * Lookup multiple IP addresses in an LPM table.
+ *
+ * @param lpm
+ *   LPM object handle
+ * @param ips
+ *   Array of IPs to be looked up in the LPM table
+ * @param next_hops
+ *   Next hop of the most specific rule found for IP (valid on lookup hit only).
+ *   This is an array of two byte values. The next hop will be stored on
+ *   each position on success; otherwise the position will be set to -1.
+ * @param n
+ *   Number of elements in ips (and next_hops) array to lookup.
+ *  @return
+ *   -EINVAL for incorrect arguments, otherwise 0
+ */
+int
+rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
+		uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
+		int16_t * next_hops, unsigned n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/app/test/v2.0/test_lpm.c b/app/test/v2.0/test_lpm.c
new file mode 100644
index 000000000..3ae4a121a
--- /dev/null
+++ b/app/test/v2.0/test_lpm.c
@@ -0,0 +1,1139 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ *
+ * LPM Autotests from DPDK v2.2.0 for v2.0 abi compability testing.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_random.h>
+#include <rte_branch_prediction.h>
+#include <rte_ip.h>
+#include <time.h>
+
+#include "../test.h"
+
+/* remapping of DPDK v2.0 symbols */
+#include "dcompat.h"
+/* backported header from DPDK v2.0 */
+#include "rte_lpm.h"
+#include "../test_lpm_routes.h"
+
+
+#define TEST_LPM_ASSERT(cond) do {                                            \
+	if (!(cond)) {                                                        \
+		printf("Error at line %d:\n", __LINE__);                      \
+		return -1;                                                    \
+	}                                                                     \
+} while (0)
+
+typedef int32_t (*rte_lpm_test)(void);
+
+static int32_t test0(void);
+static int32_t test1(void);
+static int32_t test2(void);
+static int32_t test3(void);
+static int32_t test4(void);
+static int32_t test5(void);
+static int32_t test6(void);
+static int32_t test7(void);
+static int32_t test8(void);
+static int32_t test9(void);
+static int32_t test10(void);
+static int32_t test11(void);
+static int32_t test12(void);
+static int32_t test13(void);
+static int32_t test14(void);
+static int32_t test15(void);
+static int32_t test16(void);
+static int32_t test17(void);
+
+static rte_lpm_test tests[] = {
+/* Test Cases */
+	test0,
+	test1,
+	test2,
+	test3,
+	test4,
+	test5,
+	test6,
+	test7,
+	test8,
+	test9,
+	test10,
+	test11,
+	test12,
+	test13,
+	test14,
+	test15,
+	test16,
+	test17,
+};
+
+#define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0]))
+#define MAX_DEPTH 32
+#define MAX_RULES 256
+#define PASS 0
+
+/*
+ * Check that rte_lpm_create fails gracefully for incorrect user input
+ * arguments
+ */
+int32_t
+test0(void)
+{
+	struct rte_lpm *lpm = NULL;
+
+	/* rte_lpm_create: lpm name == NULL */
+	lpm = rte_lpm_create(NULL, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm == NULL);
+
+	/* rte_lpm_create: max_rules = 0 */
+	/* Note: __func__ inserts the function name, in this case "test0". */
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 0, 0);
+	TEST_LPM_ASSERT(lpm == NULL);
+
+	/* socket_id < -1 is invalid */
+	lpm = rte_lpm_create(__func__, -2, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm == NULL);
+
+	return PASS;
+}
+
+/*
+ * Create lpm table then delete lpm table 100 times
+ * Use a slightly different rules size each time
+ * */
+int32_t
+test1(void)
+{
+	struct rte_lpm *lpm = NULL;
+	int32_t i;
+
+	/* rte_lpm_free: Free NULL */
+	for (i = 0; i < 100; i++) {
+		lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES - i, 0);
+		TEST_LPM_ASSERT(lpm != NULL);
+
+		rte_lpm_free(lpm);
+	}
+
+	/* Can not test free so return success */
+	return PASS;
+}
+
+/*
+ * Call rte_lpm_free for NULL pointer user input. Note: free has no return and
+ * therefore it is impossible to check for failure but this test is added to
+ * increase function coverage metrics and to validate that freeing null does
+ * not crash.
+ */
+int32_t
+test2(void)
+{
+	struct rte_lpm *lpm = NULL;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	rte_lpm_free(lpm);
+	rte_lpm_free(NULL);
+	return PASS;
+}
+
+/*
+ * Check that rte_lpm_add fails gracefully for incorrect user input arguments
+ */
+int32_t
+test3(void)
+{
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip = RTE_IPV4(0, 0, 0, 0);
+	uint8_t depth = 24, next_hop = 100;
+	int32_t status = 0;
+
+	/* rte_lpm_add: lpm == NULL */
+	status = rte_lpm_add(NULL, ip, depth, next_hop);
+	TEST_LPM_ASSERT(status < 0);
+
+	/*Create vaild lpm to use in rest of test. */
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* rte_lpm_add: depth < 1 */
+	status = rte_lpm_add(lpm, ip, 0, next_hop);
+	TEST_LPM_ASSERT(status < 0);
+
+	/* rte_lpm_add: depth > MAX_DEPTH */
+	status = rte_lpm_add(lpm, ip, (MAX_DEPTH + 1), next_hop);
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Check that rte_lpm_delete fails gracefully for incorrect user input
+ * arguments
+ */
+int32_t
+test4(void)
+{
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip = RTE_IPV4(0, 0, 0, 0);
+	uint8_t depth = 24;
+	int32_t status = 0;
+
+	/* rte_lpm_delete: lpm == NULL */
+	status = rte_lpm_delete(NULL, ip, depth);
+	TEST_LPM_ASSERT(status < 0);
+
+	/*Create vaild lpm to use in rest of test. */
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* rte_lpm_delete: depth < 1 */
+	status = rte_lpm_delete(lpm, ip, 0);
+	TEST_LPM_ASSERT(status < 0);
+
+	/* rte_lpm_delete: depth > MAX_DEPTH */
+	status = rte_lpm_delete(lpm, ip, (MAX_DEPTH + 1));
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Check that rte_lpm_lookup fails gracefully for incorrect user input
+ * arguments
+ */
+int32_t
+test5(void)
+{
+#if defined(RTE_LIBRTE_LPM_DEBUG)
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip = RTE_IPV4(0, 0, 0, 0);
+	uint8_t next_hop_return = 0;
+	int32_t status = 0;
+
+	/* rte_lpm_lookup: lpm == NULL */
+	status = rte_lpm_lookup(NULL, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status < 0);
+
+	/*Create vaild lpm to use in rest of test. */
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* rte_lpm_lookup: depth < 1 */
+	status = rte_lpm_lookup(lpm, ip, NULL);
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm_free(lpm);
+#endif
+	return PASS;
+}
+
+
+
+/*
+ * Call add, lookup and delete for a single rule with depth <= 24
+ */
+int32_t
+test6(void)
+{
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip = RTE_IPV4(0, 0, 0, 0);
+	uint8_t depth = 24, next_hop_add = 100, next_hop_return = 0;
+	int32_t status = 0;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Call add, lookup and delete for a single rule with depth > 24
+ */
+
+int32_t
+test7(void)
+{
+	__m128i ipx4;
+	uint16_t hop[4];
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip = RTE_IPV4(0, 0, 0, 0);
+	uint8_t depth = 32, next_hop_add = 100, next_hop_return = 0;
+	int32_t status = 0;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	ipx4 = _mm_set_epi32(ip, ip + 0x100, ip - 0x100, ip);
+	rte_lpm_lookupx4(lpm, ipx4, hop, UINT16_MAX);
+	TEST_LPM_ASSERT(hop[0] == next_hop_add);
+	TEST_LPM_ASSERT(hop[1] == UINT16_MAX);
+	TEST_LPM_ASSERT(hop[2] == UINT16_MAX);
+	TEST_LPM_ASSERT(hop[3] == next_hop_add);
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Use rte_lpm_add to add rules which effect only the second half of the lpm
+ * table. Use all possible depths ranging from 1..32. Set the next hop = to the
+ * depth. Check lookup hit for on every add and check for lookup miss on the
+ * first half of the lpm table after each add. Finally delete all rules going
+ * backwards (i.e. from depth = 32 ..1) and carry out a lookup after each
+ * delete. The lookup should return the next_hop_add value related to the
+ * previous depth value (i.e. depth -1).
+ */
+int32_t
+test8(void)
+{
+	__m128i ipx4;
+	uint16_t hop[4];
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip1 = RTE_IPV4(127, 255, 255, 255), ip2 = RTE_IPV4(128, 0, 0, 0);
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* Loop with rte_lpm_add. */
+	for (depth = 1; depth <= 32; depth++) {
+		/* Let the next_hop_add value = depth. Just for change. */
+		next_hop_add = depth;
+
+		status = rte_lpm_add(lpm, ip2, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+
+		/* Check IP in first half of tbl24 which should be empty. */
+		status = rte_lpm_lookup(lpm, ip1, &next_hop_return);
+		TEST_LPM_ASSERT(status == -ENOENT);
+
+		status = rte_lpm_lookup(lpm, ip2, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) &&
+			(next_hop_return == next_hop_add));
+
+		ipx4 = _mm_set_epi32(ip2, ip1, ip2, ip1);
+		rte_lpm_lookupx4(lpm, ipx4, hop, UINT16_MAX);
+		TEST_LPM_ASSERT(hop[0] == UINT16_MAX);
+		TEST_LPM_ASSERT(hop[1] == next_hop_add);
+		TEST_LPM_ASSERT(hop[2] == UINT16_MAX);
+		TEST_LPM_ASSERT(hop[3] == next_hop_add);
+	}
+
+	/* Loop with rte_lpm_delete. */
+	for (depth = 32; depth >= 1; depth--) {
+		next_hop_add = (uint8_t) (depth - 1);
+
+		status = rte_lpm_delete(lpm, ip2, depth);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm_lookup(lpm, ip2, &next_hop_return);
+
+		if (depth != 1) {
+			TEST_LPM_ASSERT((status == 0) &&
+				(next_hop_return == next_hop_add));
+		}
+		else {
+			TEST_LPM_ASSERT(status == -ENOENT);
+		}
+
+		status = rte_lpm_lookup(lpm, ip1, &next_hop_return);
+		TEST_LPM_ASSERT(status == -ENOENT);
+
+		ipx4 = _mm_set_epi32(ip1, ip1, ip2, ip2);
+		rte_lpm_lookupx4(lpm, ipx4, hop, UINT16_MAX);
+		if (depth != 1) {
+			TEST_LPM_ASSERT(hop[0] == next_hop_add);
+			TEST_LPM_ASSERT(hop[1] == next_hop_add);
+		} else {
+			TEST_LPM_ASSERT(hop[0] == UINT16_MAX);
+			TEST_LPM_ASSERT(hop[1] == UINT16_MAX);
+		}
+		TEST_LPM_ASSERT(hop[2] == UINT16_MAX);
+		TEST_LPM_ASSERT(hop[3] == UINT16_MAX);
+	}
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * - Add & lookup to hit invalid TBL24 entry
+ * - Add & lookup to hit valid TBL24 entry not extended
+ * - Add & lookup to hit valid extended TBL24 entry with invalid TBL8 entry
+ * - Add & lookup to hit valid extended TBL24 entry with valid TBL8 entry
+ *
+ */
+int32_t
+test9(void)
+{
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip, ip_1, ip_2;
+	uint8_t depth, depth_1, depth_2, next_hop_add, next_hop_add_1,
+		next_hop_add_2, next_hop_return;
+	int32_t status = 0;
+
+	/* Add & lookup to hit invalid TBL24 entry */
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_delete_all(lpm);
+
+	/* Add & lookup to hit valid TBL24 entry not extended */
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 23;
+	next_hop_add = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	depth = 24;
+	next_hop_add = 101;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	depth = 24;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 23;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_delete_all(lpm);
+
+	/* Add & lookup to hit valid extended TBL24 entry with invalid TBL8
+	 * entry */
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	ip = RTE_IPV4(128, 0, 0, 5);
+	depth = 32;
+	next_hop_add = 101;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 100;
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_delete_all(lpm);
+
+	/* Add & lookup to hit valid extended TBL24 entry with valid TBL8
+	 * entry */
+	ip_1 = RTE_IPV4(128, 0, 0, 0);
+	depth_1 = 25;
+	next_hop_add_1 = 101;
+
+	ip_2 = RTE_IPV4(128, 0, 0, 5);
+	depth_2 = 32;
+	next_hop_add_2 = 102;
+
+	next_hop_return = 0;
+
+	status = rte_lpm_add(lpm, ip_1, depth_1, next_hop_add_1);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip_1, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1));
+
+	status = rte_lpm_add(lpm, ip_2, depth_2, next_hop_add_2);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip_2, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_2));
+
+	status = rte_lpm_delete(lpm, ip_2, depth_2);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip_2, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1));
+
+	status = rte_lpm_delete(lpm, ip_1, depth_1);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip_1, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+
+/*
+ * - Add rule that covers a TBL24 range previously invalid & lookup (& delete &
+ *   lookup)
+ * - Add rule that extends a TBL24 invalid entry & lookup (& delete & lookup)
+ * - Add rule that extends a TBL24 valid entry & lookup for both rules (&
+ *   delete & lookup)
+ * - Add rule that updates the next hop in TBL24 & lookup (& delete & lookup)
+ * - Add rule that updates the next hop in TBL8 & lookup (& delete & lookup)
+ * - Delete a rule that is not present in the TBL24 & lookup
+ * - Delete a rule that is not present in the TBL8 & lookup
+ *
+ */
+int32_t
+test10(void)
+{
+
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip;
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	/* Add rule that covers a TBL24 range previously invalid & lookup
+	 * (& delete & lookup) */
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 16;
+	next_hop_add = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_delete_all(lpm);
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 25;
+	next_hop_add = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	rte_lpm_delete_all(lpm);
+
+	/* Add rule that extends a TBL24 valid entry & lookup for both rules
+	 * (& delete & lookup) */
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	ip = RTE_IPV4(128, 0, 0, 10);
+	depth = 32;
+	next_hop_add = 101;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	next_hop_add = 100;
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 24;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	ip = RTE_IPV4(128, 0, 0, 10);
+	depth = 32;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_delete_all(lpm);
+
+	/* Add rule that updates the next hop in TBL24 & lookup
+	 * (& delete & lookup) */
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	next_hop_add = 101;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_delete_all(lpm);
+
+	/* Add rule that updates the next hop in TBL8 & lookup
+	 * (& delete & lookup) */
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	next_hop_add = 101;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_delete_all(lpm);
+
+	/* Delete a rule that is not present in the TBL24 & lookup */
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 24;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status < 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_delete_all(lpm);
+
+	/* Delete a rule that is not present in the TBL8 & lookup */
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 32;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status < 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Add two rules, lookup to hit the more specific one, lookup to hit the less
+ * specific one delete the less specific rule and lookup previous values again;
+ * add a more specific rule than the existing rule, lookup again
+ *
+ * */
+int32_t
+test11(void)
+{
+
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip;
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	ip = RTE_IPV4(128, 0, 0, 10);
+	depth = 32;
+	next_hop_add = 101;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	next_hop_add = 100;
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 24;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	ip = RTE_IPV4(128, 0, 0, 10);
+	depth = 32;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Add an extended rule (i.e. depth greater than 24, lookup (hit), delete,
+ * lookup (miss) in a for loop of 1000 times. This will check tbl8 extension
+ * and contraction.
+ *
+ * */
+
+int32_t
+test12(void)
+{
+	__m128i ipx4;
+	uint16_t hop[4];
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip, i;
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 100;
+
+	for (i = 0; i < 1000; i++) {
+		status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) &&
+				(next_hop_return == next_hop_add));
+
+		ipx4 = _mm_set_epi32(ip, ip + 1, ip, ip - 1);
+		rte_lpm_lookupx4(lpm, ipx4, hop, UINT16_MAX);
+		TEST_LPM_ASSERT(hop[0] == UINT16_MAX);
+		TEST_LPM_ASSERT(hop[1] == next_hop_add);
+		TEST_LPM_ASSERT(hop[2] == UINT16_MAX);
+		TEST_LPM_ASSERT(hop[3] == next_hop_add);
+
+		status = rte_lpm_delete(lpm, ip, depth);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT(status == -ENOENT);
+	}
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Add a rule to tbl24, lookup (hit), then add a rule that will extend this
+ * tbl24 entry, lookup (hit). delete the rule that caused the tbl24 extension,
+ * lookup (miss) and repeat for loop of 1000 times. This will check tbl8
+ * extension and contraction.
+ *
+ * */
+
+int32_t
+test13(void)
+{
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip, i;
+	uint8_t depth, next_hop_add_1, next_hop_add_2, next_hop_return;
+	int32_t status = 0;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	ip = RTE_IPV4(128, 0, 0, 0);
+	depth = 24;
+	next_hop_add_1 = 100;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add_1);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1));
+
+	depth = 32;
+	next_hop_add_2 = 101;
+
+	for (i = 0; i < 1000; i++) {
+		status = rte_lpm_add(lpm, ip, depth, next_hop_add_2);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) &&
+				(next_hop_return == next_hop_add_2));
+
+		status = rte_lpm_delete(lpm, ip, depth);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) &&
+				(next_hop_return == next_hop_add_1));
+	}
+
+	depth = 24;
+
+	status = rte_lpm_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Fore TBL8 extension exhaustion. Add 256 rules that require a tbl8 extension.
+ * No more tbl8 extensions will be allowed. Now add one more rule that required
+ * a tbl8 extension and get fail.
+ * */
+int32_t
+test14(void)
+{
+
+	/* We only use depth = 32 in the loop below so we must make sure
+	 * that we have enough storage for all rules at that depth*/
+
+	struct rte_lpm *lpm = NULL;
+	uint32_t ip;
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	/* Add enough space for 256 rules for every depth */
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 256 * 32, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	depth = 32;
+	next_hop_add = 100;
+	ip = RTE_IPV4(0, 0, 0, 0);
+
+	/* Add 256 rules that require a tbl8 extension */
+	for (; ip <= RTE_IPV4(0, 0, 255, 0); ip += 256) {
+		status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) &&
+				(next_hop_return == next_hop_add));
+	}
+
+	/* All tbl8 extensions have been used above. Try to add one more and
+	 * we get a fail */
+	ip = RTE_IPV4(1, 0, 0, 0);
+	depth = 32;
+
+	status = rte_lpm_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Sequence of operations for find existing lpm table
+ *
+ *  - create table
+ *  - find existing table: hit
+ *  - find non-existing table: miss
+ *
+ */
+int32_t
+test15(void)
+{
+	struct rte_lpm *lpm = NULL, *result = NULL;
+
+	/* Create lpm  */
+	lpm = rte_lpm_create("lpm_find_existing", SOCKET_ID_ANY, 256 * 32, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* Try to find existing lpm */
+	result = rte_lpm_find_existing("lpm_find_existing");
+	TEST_LPM_ASSERT(result == lpm);
+
+	/* Try to find non-existing lpm */
+	result = rte_lpm_find_existing("lpm_find_non_existing");
+	TEST_LPM_ASSERT(result == NULL);
+
+	/* Cleanup. */
+	rte_lpm_delete_all(lpm);
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * test failure condition of overloading the tbl8 so no more will fit
+ * Check we get an error return value in that case
+ */
+int32_t
+test16(void)
+{
+	uint32_t ip;
+	struct rte_lpm *lpm = rte_lpm_create(__func__, SOCKET_ID_ANY,
+			256 * 32, 0);
+
+	/* ip loops through all possibilities for top 24 bits of address */
+	for (ip = 0; ip < 0xFFFFFF; ip++){
+		/* add an entry within a different tbl8 each time, since
+		 * depth >24 and the top 24 bits are different */
+		if (rte_lpm_add(lpm, (ip << 8) + 0xF0, 30, 0) < 0)
+			break;
+	}
+
+	if (ip != RTE_LPM_TBL8_NUM_GROUPS) {
+		printf("Error, unexpected failure with filling tbl8 groups\n");
+		printf("Failed after %u additions, expected after %u\n",
+				(unsigned)ip, (unsigned)RTE_LPM_TBL8_NUM_GROUPS);
+	}
+
+	rte_lpm_free(lpm);
+	return 0;
+}
+
+/*
+ * Test for overwriting of tbl8:
+ *  - add rule /32 and lookup
+ *  - add new rule /24 and lookup
+ *	- add third rule /25 and lookup
+ *	- lookup /32 and /24 rule to ensure the table has not been overwritten.
+ */
+int32_t
+test17(void)
+{
+	struct rte_lpm *lpm = NULL;
+	const uint32_t ip_10_32 = RTE_IPV4(10, 10, 10, 2);
+	const uint32_t ip_10_24 = RTE_IPV4(10, 10, 10, 0);
+	const uint32_t ip_20_25 = RTE_IPV4(10, 10, 20, 2);
+	const uint8_t d_ip_10_32 = 32,
+			d_ip_10_24 = 24,
+			d_ip_20_25 = 25;
+	const uint8_t next_hop_ip_10_32 = 100,
+			next_hop_ip_10_24 = 105,
+			next_hop_ip_20_25 = 111;
+	uint8_t next_hop_return = 0;
+	int32_t status = 0;
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	if ((status = rte_lpm_add(lpm, ip_10_32, d_ip_10_32,
+			next_hop_ip_10_32)) < 0)
+		return -1;
+
+	status = rte_lpm_lookup(lpm, ip_10_32, &next_hop_return);
+	uint8_t test_hop_10_32 = next_hop_return;
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32);
+
+	if ((status = rte_lpm_add(lpm, ip_10_24, d_ip_10_24,
+			next_hop_ip_10_24)) < 0)
+			return -1;
+
+	status = rte_lpm_lookup(lpm, ip_10_24, &next_hop_return);
+	uint8_t test_hop_10_24 = next_hop_return;
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24);
+
+	if ((status = rte_lpm_add(lpm, ip_20_25, d_ip_20_25,
+			next_hop_ip_20_25)) < 0)
+		return -1;
+
+	status = rte_lpm_lookup(lpm, ip_20_25, &next_hop_return);
+	uint8_t test_hop_20_25 = next_hop_return;
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_20_25);
+
+	if (test_hop_10_32 == test_hop_10_24) {
+		printf("Next hop return equal\n");
+		return -1;
+	}
+
+	if (test_hop_10_24 == test_hop_20_25){
+		printf("Next hop return equal\n");
+		return -1;
+	}
+
+	status = rte_lpm_lookup(lpm, ip_10_32, &next_hop_return);
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32);
+
+	status = rte_lpm_lookup(lpm, ip_10_24, &next_hop_return);
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24);
+
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+
+/*
+ * Do all unit tests.
+ */
+
+static int
+test_lpm(void)
+{
+	unsigned int i;
+	int status, global_status = 0;
+
+	for (i = 0; i < NUM_LPM_TESTS; i++) {
+		status = tests[i]();
+		if (status < 0) {
+			printf("ERROR: LPM Test %s: FAIL\n", RTE_STR(tests[i]));
+			global_status = status;
+		}
+	}
+
+	return global_status;
+}
+
+REGISTER_TEST_COMMAND_VERSION(lpm_autotest,
+			      test_lpm, TEST_DPDK_ABI_VERSION_V20);
diff --git a/app/test/v2.0/test_lpm6.c b/app/test/v2.0/test_lpm6.c
new file mode 100644
index 000000000..6c6694259
--- /dev/null
+++ b/app/test/v2.0/test_lpm6.c
@@ -0,0 +1,1748 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ *
+ * LPM6 Autotests from DPDK v17.02 for v2.0 abi compatibility testing.
+ *
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <rte_memory.h>
+/* remapping of DPDK v2.0 symbols */
+#include "dcompat.h"
+/* backported header from DPDK v2.0 */
+#include "rte_lpm6.h"
+
+#include "../test.h"
+#include "../test_lpm6_data.h"
+
+#define TEST_LPM_ASSERT(cond) do {                                            \
+	if (!(cond)) {                                                        \
+		printf("Error at line %d: \n", __LINE__);                     \
+		return -1;                                                    \
+	}                                                                     \
+} while(0)
+
+typedef int32_t (* rte_lpm6_test)(void);
+
+static int32_t test0(void);
+static int32_t test1(void);
+static int32_t test2(void);
+static int32_t test3(void);
+static int32_t test4(void);
+static int32_t test5(void);
+static int32_t test6(void);
+static int32_t test7(void);
+static int32_t test8(void);
+static int32_t test9(void);
+static int32_t test10(void);
+static int32_t test11(void);
+static int32_t test12(void);
+static int32_t test13(void);
+static int32_t test14(void);
+static int32_t test15(void);
+static int32_t test16(void);
+static int32_t test17(void);
+static int32_t test18(void);
+static int32_t test19(void);
+static int32_t test20(void);
+static int32_t test21(void);
+static int32_t test22(void);
+static int32_t test23(void);
+static int32_t test24(void);
+static int32_t test25(void);
+static int32_t test26(void);
+static int32_t test27(void);
+
+static rte_lpm6_test tests6[] = {
+/* Test Cases */
+	test0,
+	test1,
+	test2,
+	test3,
+	test4,
+	test5,
+	test6,
+	test7,
+	test8,
+	test9,
+	test10,
+	test11,
+	test12,
+	test13,
+	test14,
+	test15,
+	test16,
+	test17,
+	test18,
+	test19,
+	test20,
+	test21,
+	test22,
+	test23,
+	test24,
+	test25,
+	test26,
+	test27,
+};
+
+#define NUM_LPM6_TESTS                (sizeof(tests6)/sizeof(tests6[0]))
+#define MAX_DEPTH                                                    128
+#define MAX_RULES                                                1000000
+#define NUMBER_TBL8S                                           (1 << 16)
+#define MAX_NUM_TBL8S                                          (1 << 21)
+#define PASS 0
+
+static void
+IPv6(uint8_t *ip, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5,
+		uint8_t b6, uint8_t b7, uint8_t b8, uint8_t b9, uint8_t b10,
+		uint8_t b11, uint8_t b12, uint8_t b13, uint8_t b14, uint8_t b15,
+		uint8_t b16)
+{
+	ip[0] = b1;
+	ip[1] = b2;
+	ip[2] = b3;
+	ip[3] = b4;
+	ip[4] = b5;
+	ip[5] = b6;
+	ip[6] = b7;
+	ip[7] = b8;
+	ip[8] = b9;
+	ip[9] = b10;
+	ip[10] = b11;
+	ip[11] = b12;
+	ip[12] = b13;
+	ip[13] = b14;
+	ip[14] = b15;
+	ip[15] = b16;
+}
+
+/*
+ * Check that rte_lpm6_create fails gracefully for incorrect user input
+ * arguments
+ */
+int32_t
+test0(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* rte_lpm6_create: lpm name == NULL */
+	lpm = rte_lpm6_create(NULL, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm == NULL);
+
+	/* rte_lpm6_create: max_rules = 0 */
+	/* Note: __func__ inserts the function name, in this case "test0". */
+	config.max_rules = 0;
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm == NULL);
+
+	/* socket_id < -1 is invalid */
+	config.max_rules = MAX_RULES;
+	lpm = rte_lpm6_create(__func__, -2, &config);
+	TEST_LPM_ASSERT(lpm == NULL);
+
+	/* rte_lpm6_create: number_tbl8s is bigger than the maximum */
+	config.number_tbl8s = MAX_NUM_TBL8S + 1;
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm == NULL);
+
+	/* rte_lpm6_create: config = NULL */
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, NULL);
+	TEST_LPM_ASSERT(lpm == NULL);
+
+	return PASS;
+}
+
+/*
+ * Creates two different LPM tables. Tries to create a third one with the same
+ * name as the first one and expects the create function to return the same
+ * pointer.
+ */
+int32_t
+test1(void)
+{
+	struct rte_lpm6 *lpm1 = NULL, *lpm2 = NULL, *lpm3 = NULL;
+	struct rte_lpm6_config config;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* rte_lpm6_create: lpm name == LPM1 */
+	lpm1 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm1 != NULL);
+
+	/* rte_lpm6_create: lpm name == LPM2 */
+	lpm2 = rte_lpm6_create("LPM2", SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm2 != NULL);
+
+	/* rte_lpm6_create: lpm name == LPM2 */
+	lpm3 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm3 == NULL);
+
+	rte_lpm6_free(lpm1);
+	rte_lpm6_free(lpm2);
+
+	return PASS;
+}
+
+/*
+ * Create lpm table then delete lpm table 20 times
+ * Use a slightly different rules size each time
+ */
+int32_t
+test2(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	int32_t i;
+
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* rte_lpm6_free: Free NULL */
+	for (i = 0; i < 20; i++) {
+		config.max_rules = MAX_RULES - i;
+		lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+		TEST_LPM_ASSERT(lpm != NULL);
+
+		rte_lpm6_free(lpm);
+	}
+
+	/* Can not test free so return success */
+	return PASS;
+}
+
+/*
+ * Call rte_lpm6_free for NULL pointer user input. Note: free has no return and
+ * therefore it is impossible to check for failure but this test is added to
+ * increase function coverage metrics and to validate that freeing null does
+ * not crash.
+ */
+int32_t
+test3(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	rte_lpm6_free(lpm);
+	rte_lpm6_free(NULL);
+	return PASS;
+}
+
+/*
+ * Check that rte_lpm6_add fails gracefully for incorrect user input arguments
+ */
+int32_t
+test4(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth = 24, next_hop = 100;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* rte_lpm6_add: lpm == NULL */
+	status = rte_lpm6_add(NULL, ip, depth, next_hop);
+	TEST_LPM_ASSERT(status < 0);
+
+	/*Create vaild lpm to use in rest of test. */
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* rte_lpm6_add: depth < 1 */
+	status = rte_lpm6_add(lpm, ip, 0, next_hop);
+	TEST_LPM_ASSERT(status < 0);
+
+	/* rte_lpm6_add: depth > MAX_DEPTH */
+	status = rte_lpm6_add(lpm, ip, (MAX_DEPTH + 1), next_hop);
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Check that rte_lpm6_delete fails gracefully for incorrect user input
+ * arguments
+ */
+int32_t
+test5(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth = 24;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* rte_lpm_delete: lpm == NULL */
+	status = rte_lpm6_delete(NULL, ip, depth);
+	TEST_LPM_ASSERT(status < 0);
+
+	/*Create vaild lpm to use in rest of test. */
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* rte_lpm_delete: depth < 1 */
+	status = rte_lpm6_delete(lpm, ip, 0);
+	TEST_LPM_ASSERT(status < 0);
+
+	/* rte_lpm_delete: depth > MAX_DEPTH */
+	status = rte_lpm6_delete(lpm, ip, (MAX_DEPTH + 1));
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Check that rte_lpm6_lookup fails gracefully for incorrect user input
+ * arguments
+ */
+int32_t
+test6(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t next_hop_return = 0;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* rte_lpm6_lookup: lpm == NULL */
+	status = rte_lpm6_lookup(NULL, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status < 0);
+
+	/*Create vaild lpm to use in rest of test. */
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* rte_lpm6_lookup: ip = NULL */
+	status = rte_lpm6_lookup(lpm, NULL, &next_hop_return);
+	TEST_LPM_ASSERT(status < 0);
+
+	/* rte_lpm6_lookup: next_hop = NULL */
+	status = rte_lpm6_lookup(lpm, ip, NULL);
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Checks that rte_lpm6_lookup_bulk_func fails gracefully for incorrect user
+ * input arguments
+ */
+int32_t
+test7(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[10][16];
+	int16_t next_hop_return[10];
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* rte_lpm6_lookup: lpm == NULL */
+	status = rte_lpm6_lookup_bulk_func(NULL, ip, next_hop_return, 10);
+	TEST_LPM_ASSERT(status < 0);
+
+	/*Create vaild lpm to use in rest of test. */
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* rte_lpm6_lookup: ip = NULL */
+	status = rte_lpm6_lookup_bulk_func(lpm, NULL, next_hop_return, 10);
+	TEST_LPM_ASSERT(status < 0);
+
+	/* rte_lpm6_lookup: next_hop = NULL */
+	status = rte_lpm6_lookup_bulk_func(lpm, ip, NULL, 10);
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Checks that rte_lpm6_delete_bulk_func fails gracefully for incorrect user
+ * input arguments
+ */
+int32_t
+test8(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[10][16];
+	uint8_t depth[10];
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* rte_lpm6_delete: lpm == NULL */
+	status = rte_lpm6_delete_bulk_func(NULL, ip, depth, 10);
+	TEST_LPM_ASSERT(status < 0);
+
+	/*Create vaild lpm to use in rest of test. */
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* rte_lpm6_delete: ip = NULL */
+	status = rte_lpm6_delete_bulk_func(lpm, NULL, depth, 10);
+	TEST_LPM_ASSERT(status < 0);
+
+	/* rte_lpm6_delete: next_hop = NULL */
+	status = rte_lpm6_delete_bulk_func(lpm, ip, NULL, 10);
+	TEST_LPM_ASSERT(status < 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Call add, lookup and delete for a single rule with depth < 24.
+ * Check all the combinations for the first three bytes that result in a hit.
+ * Delete the rule and check that the same test returs a miss.
+ */
+int32_t
+test9(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth = 16, next_hop_add = 100, next_hop_return = 0;
+	int32_t status = 0;
+	uint8_t i;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	for (i = 0; i < UINT8_MAX; i++) {
+		ip[2] = i;
+		status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+	}
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	for (i = 0; i < UINT8_MAX; i++) {
+		ip[2] = i;
+		status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT(status == -ENOENT);
+	}
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Adds max_rules + 1 and expects a failure. Deletes a rule, then adds
+ * another one and expects success.
+ */
+int32_t
+test10(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth, next_hop_add = 100;
+	int32_t status = 0;
+	int i;
+
+	config.max_rules = 127;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	for (i = 1; i < 128; i++) {
+		depth = (uint8_t)i;
+		status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+	}
+
+	depth = 128;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == -ENOSPC);
+
+	depth = 127;
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 128;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Creates an LPM table with a small number of tbl8s and exhaust them in the
+ * middle of the process of creating a rule.
+ */
+int32_t
+test11(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth, next_hop_add = 100;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = 16;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	depth = 128;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	ip[0] = 1;
+	depth = 25;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 33;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 41;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 49;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == -ENOSPC);
+
+	depth = 41;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Creates an LPM table with a small number of tbl8s and exhaust them in the
+ * middle of the process of adding a rule when there is already an existing rule
+ * in that position and needs to be extended.
+ */
+int32_t
+test12(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth, next_hop_add = 100;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = 16;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	depth = 128;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	ip[0] = 1;
+	depth = 41;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 49;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == -ENOSPC);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Creates an LPM table with max_rules = 2 and tries to add 3 rules.
+ * Delete one of the rules and tries to add the third one again.
+ */
+int32_t
+test13(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth, next_hop_add = 100;
+	int32_t status = 0;
+
+	config.max_rules = 2;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	depth = 1;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 2;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 3;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == -ENOSPC);
+
+	depth = 2;
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 3;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Add 2^12 routes with different first 12 bits and depth 25.
+ * Add one more route with the same depth and check that results in a failure.
+ * After that delete the last rule and create the one that was attempted to be
+ * created. This checks tbl8 exhaustion.
+ */
+int32_t
+test14(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth = 25, next_hop_add = 100;
+	int32_t status = 0;
+	int i;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = 256;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	for (i = 0; i < 256; i++) {
+		ip[0] = (uint8_t)i;
+		status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+	}
+
+	ip[0] = 255;
+	ip[1] = 1;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == -ENOSPC);
+
+	ip[0] = 255;
+	ip[1] = 0;
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	ip[0] = 255;
+	ip[1] = 1;
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Call add, lookup and delete for a single rule with depth = 24
+ */
+int32_t
+test15(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth = 24, next_hop_add = 100, next_hop_return = 0;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Call add, lookup and delete for a single rule with depth > 24
+ */
+int32_t
+test16(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[] = {12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth = 128, next_hop_add = 100, next_hop_return = 0;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Use rte_lpm6_add to add rules which effect only the second half of the lpm
+ * table. Use all possible depths ranging from 1..32. Set the next hop = to the
+ * depth. Check lookup hit for on every add and check for lookup miss on the
+ * first half of the lpm table after each add. Finally delete all rules going
+ * backwards (i.e. from depth = 32 ..1) and carry out a lookup after each
+ * delete. The lookup should return the next_hop_add value related to the
+ * previous depth value (i.e. depth -1).
+ */
+int32_t
+test17(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip1[] = {127,255,255,255,255,255,255,255,255,
+			255,255,255,255,255,255,255};
+	uint8_t ip2[] = {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* Loop with rte_lpm6_add. */
+	for (depth = 1; depth <= 16; depth++) {
+		/* Let the next_hop_add value = depth. Just for change. */
+		next_hop_add = depth;
+
+		status = rte_lpm6_add(lpm, ip2, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+
+		/* Check IP in first half of tbl24 which should be empty. */
+		status = rte_lpm6_lookup(lpm, ip1, &next_hop_return);
+		TEST_LPM_ASSERT(status == -ENOENT);
+
+		status = rte_lpm6_lookup(lpm, ip2, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) &&
+			(next_hop_return == next_hop_add));
+	}
+
+	/* Loop with rte_lpm6_delete. */
+	for (depth = 16; depth >= 1; depth--) {
+		next_hop_add = (uint8_t) (depth - 1);
+
+		status = rte_lpm6_delete(lpm, ip2, depth);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm6_lookup(lpm, ip2, &next_hop_return);
+
+		if (depth != 1) {
+			TEST_LPM_ASSERT((status == 0) &&
+				(next_hop_return == next_hop_add));
+		}
+		else {
+			TEST_LPM_ASSERT(status == -ENOENT);
+		}
+
+		status = rte_lpm6_lookup(lpm, ip1, &next_hop_return);
+		TEST_LPM_ASSERT(status == -ENOENT);
+	}
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * - Add & lookup to hit invalid TBL24 entry
+ * - Add & lookup to hit valid TBL24 entry not extended
+ * - Add & lookup to hit valid extended TBL24 entry with invalid TBL8 entry
+ * - Add & lookup to hit valid extended TBL24 entry with valid TBL8 entry
+ */
+int32_t
+test18(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[16], ip_1[16], ip_2[16];
+	uint8_t depth, depth_1, depth_2, next_hop_add, next_hop_add_1,
+		next_hop_add_2, next_hop_return;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* Add & lookup to hit invalid TBL24 entry */
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_delete_all(lpm);
+
+	/* Add & lookup to hit valid TBL24 entry not extended */
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 23;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	depth = 24;
+	next_hop_add = 101;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	depth = 24;
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	depth = 23;
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_delete_all(lpm);
+
+	/* Add & lookup to hit valid extended TBL24 entry with invalid TBL8
+	 * entry.
+	 */
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	IPv6(ip, 128, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 101;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 100;
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_delete_all(lpm);
+
+	/* Add & lookup to hit valid extended TBL24 entry with valid TBL8
+	 * entry
+	 */
+	IPv6(ip_1, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth_1 = 25;
+	next_hop_add_1 = 101;
+
+	IPv6(ip_2, 128, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth_2 = 32;
+	next_hop_add_2 = 102;
+
+	next_hop_return = 0;
+
+	status = rte_lpm6_add(lpm, ip_1, depth_1, next_hop_add_1);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip_1, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1));
+
+	status = rte_lpm6_add(lpm, ip_2, depth_2, next_hop_add_2);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip_2, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_2));
+
+	status = rte_lpm6_delete(lpm, ip_2, depth_2);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip_2, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1));
+
+	status = rte_lpm6_delete(lpm, ip_1, depth_1);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip_1, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * - Add rule that covers a TBL24 range previously invalid & lookup (& delete &
+ *   lookup)
+ * - Add rule that extends a TBL24 invalid entry & lookup (& delete & lookup)
+ * - Add rule that extends a TBL24 valid entry & lookup for both rules (&
+ *   delete & lookup)
+ * - Add rule that updates the next hop in TBL24 & lookup (& delete & lookup)
+ * - Add rule that updates the next hop in TBL8 & lookup (& delete & lookup)
+ * - Delete a rule that is not present in the TBL24 & lookup
+ * - Delete a rule that is not present in the TBL8 & lookup
+ */
+int32_t
+test19(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[16];
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* Add rule that covers a TBL24 range previously invalid & lookup
+	 * (& delete & lookup)
+	 */
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 16;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_delete_all(lpm);
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 25;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	rte_lpm6_delete_all(lpm);
+
+	/*
+	 * Add rule that extends a TBL24 valid entry & lookup for both rules
+	 * (& delete & lookup)
+	 */
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip, 128, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 101;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	next_hop_add = 100;
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 24;
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	IPv6(ip, 128, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 32;
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_delete_all(lpm);
+
+	/*
+	 * Add rule that updates the next hop in TBL24 & lookup
+	 * (& delete & lookup)
+	 */
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	next_hop_add = 101;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_delete_all(lpm);
+
+	/*
+	 * Add rule that updates the next hop in TBL8 & lookup
+	 * (& delete & lookup)
+	 */
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	next_hop_add = 101;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_delete_all(lpm);
+
+	/* Delete a rule that is not present in the TBL24 & lookup */
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status < 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_delete_all(lpm);
+
+	/* Delete a rule that is not present in the TBL8 & lookup */
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 32;
+	next_hop_add = 100;
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status < 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Add two rules, lookup to hit the more specific one, lookup to hit the less
+ * specific one delete the less specific rule and lookup previous values again;
+ * add a more specific rule than the existing rule, lookup again
+ */
+int32_t
+test20(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[16];
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 24;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10);
+	depth = 128;
+	next_hop_add = 101;
+
+	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	next_hop_add = 100;
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 24;
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10);
+	depth = 128;
+
+	status = rte_lpm6_delete(lpm, ip, depth);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+	TEST_LPM_ASSERT(status == -ENOENT);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Adds 3 rules and look them up through the lookup_bulk function.
+ * Includes in the lookup a fourth IP address that won't match
+ * and checks that the result is as expected.
+ */
+int32_t
+test21(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip_batch[4][16];
+	uint8_t depth, next_hop_add;
+	int16_t next_hop_return[4];
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	IPv6(ip_batch[0], 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 48;
+	next_hop_add = 100;
+
+	status = rte_lpm6_add(lpm, ip_batch[0], depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip_batch[1], 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 48;
+	next_hop_add = 101;
+
+	status = rte_lpm6_add(lpm, ip_batch[1], depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip_batch[2], 128, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 48;
+	next_hop_add = 102;
+
+	status = rte_lpm6_add(lpm, ip_batch[2], depth, next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip_batch[3], 128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+	status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
+			next_hop_return, 4);
+	TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == 100
+			&& next_hop_return[1] == 101 && next_hop_return[2] == 102
+			&& next_hop_return[3] == -1);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Adds 5 rules and look them up.
+ * Use the delete_bulk function to delete two of them. Lookup again.
+ * Use the delete_bulk function to delete one more. Lookup again.
+ * Use the delete_bulk function to delete two more, one invalid. Lookup again.
+ * Use the delete_bulk function to delete the remaining one. Lookup again.
+ */
+int32_t
+test22(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip_batch[5][16];
+	uint8_t depth[5], next_hop_add;
+	int16_t next_hop_return[5];
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* Adds 5 rules and look them up */
+
+	IPv6(ip_batch[0], 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth[0] = 48;
+	next_hop_add = 101;
+
+	status = rte_lpm6_add(lpm, ip_batch[0], depth[0], next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip_batch[1], 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth[1] = 48;
+	next_hop_add = 102;
+
+	status = rte_lpm6_add(lpm, ip_batch[1], depth[1], next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip_batch[2], 128, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth[2] = 48;
+	next_hop_add = 103;
+
+	status = rte_lpm6_add(lpm, ip_batch[2], depth[2], next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip_batch[3], 128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth[3] = 48;
+	next_hop_add = 104;
+
+	status = rte_lpm6_add(lpm, ip_batch[3], depth[3], next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip_batch[4], 128, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth[4] = 48;
+	next_hop_add = 105;
+
+	status = rte_lpm6_add(lpm, ip_batch[4], depth[4], next_hop_add);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
+			next_hop_return, 5);
+	TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == 101
+			&& next_hop_return[1] == 102 && next_hop_return[2] == 103
+			&& next_hop_return[3] == 104 && next_hop_return[4] == 105);
+
+	/* Use the delete_bulk function to delete two of them. Lookup again */
+
+	status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[0], depth, 2);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
+			next_hop_return, 5);
+	TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1
+			&& next_hop_return[1] == -1 && next_hop_return[2] == 103
+			&& next_hop_return[3] == 104 && next_hop_return[4] == 105);
+
+	/* Use the delete_bulk function to delete one more. Lookup again */
+
+	status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[2], depth, 1);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
+			next_hop_return, 5);
+	TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1
+			&& next_hop_return[1] == -1 && next_hop_return[2] == -1
+			&& next_hop_return[3] == 104 && next_hop_return[4] == 105);
+
+	/* Use the delete_bulk function to delete two, one invalid. Lookup again */
+
+	IPv6(ip_batch[4], 128, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[3], depth, 2);
+	TEST_LPM_ASSERT(status == 0);
+
+	IPv6(ip_batch[4], 128, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
+			next_hop_return, 5);
+	TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1
+			&& next_hop_return[1] == -1 && next_hop_return[2] == -1
+			&& next_hop_return[3] == -1 && next_hop_return[4] == 105);
+
+	/* Use the delete_bulk function to delete the remaining one. Lookup again */
+
+	status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[4], depth, 1);
+	TEST_LPM_ASSERT(status == 0);
+
+	status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
+			next_hop_return, 5);
+	TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1
+			&& next_hop_return[1] == -1 && next_hop_return[2] == -1
+			&& next_hop_return[3] == -1 && next_hop_return[4] == -1);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Add an extended rule (i.e. depth greater than 24, lookup (hit), delete,
+ * lookup (miss) in a for loop of 30 times. This will check tbl8 extension
+ * and contraction.
+ */
+int32_t
+test23(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint32_t i;
+	uint8_t ip[16];
+	uint8_t depth, next_hop_add, next_hop_return;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	depth = 128;
+	next_hop_add = 100;
+
+	for (i = 0; i < 30; i++) {
+		status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) &&
+				(next_hop_return == next_hop_add));
+
+		status = rte_lpm6_delete(lpm, ip, depth);
+		TEST_LPM_ASSERT(status == 0);
+
+		status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT(status == -ENOENT);
+	}
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Sequence of operations for find existing lpm table
+ *
+ *  - create table
+ *  - find existing table: hit
+ *  - find non-existing table: miss
+ */
+int32_t
+test24(void)
+{
+	struct rte_lpm6 *lpm = NULL, *result = NULL;
+	struct rte_lpm6_config config;
+
+	config.max_rules = 256 * 32;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	/* Create lpm  */
+	lpm = rte_lpm6_create("lpm_find_existing", SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* Try to find existing lpm */
+	result = rte_lpm6_find_existing("lpm_find_existing");
+	TEST_LPM_ASSERT(result == lpm);
+
+	/* Try to find non-existing lpm */
+	result = rte_lpm6_find_existing("lpm_find_non_existing");
+	TEST_LPM_ASSERT(result == NULL);
+
+	/* Cleanup. */
+	rte_lpm6_delete_all(lpm);
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Add a set of random routes with random depths.
+ * Lookup different IP addresses that match the routes previously added.
+ * Checks that the next hop is the expected one.
+ * The routes, IP addresses and expected result for every case have been
+ * precalculated by using a python script and stored in a .h file.
+ */
+int32_t
+test25(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip[16];
+	uint32_t i;
+	uint8_t depth, next_hop_add, next_hop_return, next_hop_expected;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	for (i = 0; i < 1000; i++) {
+		memcpy(ip, large_route_table[i].ip, 16);
+		depth = large_route_table[i].depth;
+		next_hop_add = large_route_table[i].next_hop;
+		status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+	}
+
+	/* generate large IPS table and expected next_hops */
+	generate_large_ips_table(1);
+
+	for (i = 0; i < 100000; i++) {
+		memcpy(ip, large_ips_table[i].ip, 16);
+		next_hop_expected = large_ips_table[i].next_hop;
+
+		status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+		TEST_LPM_ASSERT((status == 0) &&
+				(next_hop_return == next_hop_expected));
+	}
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Test for overwriting of tbl8:
+ *  - add rule /32 and lookup
+ *  - add new rule /24 and lookup
+ *	- add third rule /25 and lookup
+ *	- lookup /32 and /24 rule to ensure the table has not been overwritten.
+ */
+int32_t
+test26(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint8_t ip_10_32[] = {10, 10, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	uint8_t ip_10_24[] = {10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	uint8_t ip_20_25[] = {10, 10, 20, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	uint8_t d_ip_10_32 = 32;
+	uint8_t	d_ip_10_24 = 24;
+	uint8_t	d_ip_20_25 = 25;
+	uint8_t next_hop_ip_10_32 = 100;
+	uint8_t	next_hop_ip_10_24 = 105;
+	uint8_t	next_hop_ip_20_25 = 111;
+	uint8_t next_hop_return = 0;
+	int32_t status = 0;
+
+	config.max_rules = MAX_RULES;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	if ((status = rte_lpm6_add(lpm, ip_10_32, d_ip_10_32,
+			next_hop_ip_10_32)) < 0)
+		return -1;
+
+	status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return);
+	uint8_t test_hop_10_32 = next_hop_return;
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32);
+
+	if ((status = rte_lpm6_add(lpm, ip_10_24, d_ip_10_24,
+			next_hop_ip_10_24)) < 0)
+			return -1;
+
+	status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return);
+	uint8_t test_hop_10_24 = next_hop_return;
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24);
+
+	if ((status = rte_lpm6_add(lpm, ip_20_25, d_ip_20_25,
+			next_hop_ip_20_25)) < 0)
+		return -1;
+
+	status = rte_lpm6_lookup(lpm, ip_20_25, &next_hop_return);
+	uint8_t test_hop_20_25 = next_hop_return;
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_20_25);
+
+	if (test_hop_10_32 == test_hop_10_24) {
+		printf("Next hop return equal\n");
+		return -1;
+	}
+
+	if (test_hop_10_24 == test_hop_20_25){
+		printf("Next hop return equal\n");
+		return -1;
+	}
+
+	status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return);
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32);
+
+	status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return);
+	TEST_LPM_ASSERT(status == 0);
+	TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24);
+
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+/*
+ * Add a rule that reaches the end of the tree.
+ * Add a rule that is more generic than the first one.
+ * Check every possible combination that produces a match for the second rule.
+ * This tests tbl expansion.
+ */
+int32_t
+test27(void)
+{
+		struct rte_lpm6 *lpm = NULL;
+		struct rte_lpm6_config config;
+		uint8_t ip[] = {128,128,128,128,128,128,128,128,128,128,128,128,128,128,0,0};
+		uint8_t depth = 128, next_hop_add = 100, next_hop_return;
+		int32_t status = 0;
+		int i, j;
+
+		config.max_rules = MAX_RULES;
+		config.number_tbl8s = NUMBER_TBL8S;
+		config.flags = 0;
+
+		lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+		TEST_LPM_ASSERT(lpm != NULL);
+
+		depth = 128;
+		next_hop_add = 128;
+		status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+
+		depth = 112;
+		next_hop_add = 112;
+		status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
+		TEST_LPM_ASSERT(status == 0);
+
+		for (i = 0; i < 256; i++) {
+			ip[14] = (uint8_t)i;
+			for (j = 0; j < 256; j++) {
+				ip[15] = (uint8_t)j;
+				status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
+				if (i == 0 && j == 0)
+					TEST_LPM_ASSERT(status == 0 && next_hop_return == 128);
+				else
+					TEST_LPM_ASSERT(status == 0 && next_hop_return == 112);
+				}
+		}
+
+		rte_lpm6_free(lpm);
+
+		return PASS;
+}
+
+/*
+ * Do all unit and performance tests.
+ */
+static int
+test_lpm6(void)
+{
+	unsigned i;
+	int status = -1, global_status = 0;
+
+	for (i = 0; i < NUM_LPM6_TESTS; i++) {
+		printf("# test %02d\n", i);
+		status = tests6[i]();
+
+		if (status < 0) {
+			printf("ERROR: LPM Test %s: FAIL\n", RTE_STR(tests6[i]));
+			global_status = status;
+		}
+	}
+
+	return global_status;
+}
+
+REGISTER_TEST_COMMAND_VERSION(lpm6_autotest,
+			      test_lpm6, TEST_DPDK_ABI_VERSION_V20);
diff --git a/app/test/v2.0/test_lpm6_perf.c b/app/test/v2.0/test_lpm6_perf.c
new file mode 100644
index 000000000..abbd0a30e
--- /dev/null
+++ b/app/test/v2.0/test_lpm6_perf.c
@@ -0,0 +1,179 @@
+
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ *
+ * LPM6 Autotests from DPDK v17.02 for v2.0 abi compatibility testing.
+ *
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_cycles.h>
+#include <rte_random.h>
+#include <rte_memory.h>
+
+/* remapping of DPDK v2.0 symbols */
+#include "dcompat.h"
+/* backported header from DPDK v2.0 */
+#include "rte_lpm6.h"
+
+#include "../test.h"
+#include "../test_lpm6_data.h"
+
+#define TEST_LPM_ASSERT(cond) do {              \
+    if (!(cond)) {                              \
+      printf("Error at line %d: \n", __LINE__); \
+      return -1;                                \
+    }                                           \
+  } while(0)
+
+static int32_t test_lpm6_perf(void);
+
+#define NUMBER_TBL8S                                           (1 << 16)
+#define PASS 0
+
+/*
+ * Lookup performance test
+ */
+
+#define ITERATIONS (1 << 10)
+#define BATCH_SIZE 100000
+
+static void
+print_route_distribution(const struct rules_tbl_entry *table, uint32_t n)
+{
+	unsigned i, j;
+
+	printf("Route distribution per prefix width: \n");
+	printf("DEPTH    QUANTITY (PERCENT)\n");
+	printf("--------------------------- \n");
+
+	/* Count depths. */
+	for(i = 1; i <= 128; i++) {
+		unsigned depth_counter = 0;
+		double percent_hits;
+
+		for (j = 0; j < n; j++)
+			if (table[j].depth == (uint8_t) i)
+				depth_counter++;
+
+		percent_hits = ((double)depth_counter)/((double)n) * 100;
+		printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits);
+	}
+	printf("\n");
+}
+
+static int
+test_lpm6_perf(void)
+{
+	struct rte_lpm6 *lpm = NULL;
+	struct rte_lpm6_config config;
+	uint64_t begin, total_time;
+	unsigned i, j;
+	uint8_t next_hop_add = 0xAA, next_hop_return = 0;
+	int status = 0;
+	int64_t count = 0;
+
+	config.max_rules = 1000000;
+	config.number_tbl8s = NUMBER_TBL8S;
+	config.flags = 0;
+
+	rte_srand(rte_rdtsc());
+
+	printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES);
+
+	print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES);
+
+  /* Only generate IPv6 address of each item in large IPS table,
+	 * here next_hop is not needed.
+	 */
+	generate_large_ips_table(0);
+
+	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* Measure add. */
+	begin = rte_rdtsc();
+
+	for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
+		if (rte_lpm6_add(lpm, large_route_table[i].ip,
+				large_route_table[i].depth, next_hop_add) == 0)
+			status++;
+	}
+	/* End Timer. */
+	total_time = rte_rdtsc() - begin;
+
+	printf("Unique added entries = %d\n", status);
+	printf("Average LPM Add: %g cycles\n",
+			(double)total_time / NUM_ROUTE_ENTRIES);
+
+	/* Measure single Lookup */
+	total_time = 0;
+	count = 0;
+
+	for (i = 0; i < ITERATIONS; i ++) {
+		begin = rte_rdtsc();
+
+		for (j = 0; j < NUM_IPS_ENTRIES; j ++) {
+			if (rte_lpm6_lookup(lpm, large_ips_table[j].ip,
+					&next_hop_return) != 0)
+				count++;
+		}
+
+		total_time += rte_rdtsc() - begin;
+
+	}
+	printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
+			(double)total_time / ((double)ITERATIONS * BATCH_SIZE),
+			(count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
+
+	/* Measure bulk Lookup */
+	total_time = 0;
+	count = 0;
+
+	uint8_t ip_batch[NUM_IPS_ENTRIES][16];
+	int16_t next_hops[NUM_IPS_ENTRIES];
+
+	for (i = 0; i < NUM_IPS_ENTRIES; i++)
+		memcpy(ip_batch[i], large_ips_table[i].ip, 16);
+
+	for (i = 0; i < ITERATIONS; i ++) {
+
+		/* Lookup per batch */
+		begin = rte_rdtsc();
+		rte_lpm6_lookup_bulk_func(lpm, ip_batch, next_hops, NUM_IPS_ENTRIES);
+		total_time += rte_rdtsc() - begin;
+
+		for (j = 0; j < NUM_IPS_ENTRIES; j++)
+			if (next_hops[j] < 0)
+				count++;
+	}
+	printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
+			(double)total_time / ((double)ITERATIONS * BATCH_SIZE),
+			(count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
+
+	/* Delete */
+	status = 0;
+	begin = rte_rdtsc();
+
+	for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
+		/* rte_lpm_delete(lpm, ip, depth) */
+		status += rte_lpm6_delete(lpm, large_route_table[i].ip,
+				large_route_table[i].depth);
+	}
+
+	total_time += rte_rdtsc() - begin;
+
+	printf("Average LPM Delete: %g cycles\n",
+			(double)total_time / NUM_ROUTE_ENTRIES);
+
+	rte_lpm6_delete_all(lpm);
+	rte_lpm6_free(lpm);
+
+	return PASS;
+}
+
+REGISTER_TEST_COMMAND_VERSION(lpm6_perf_autotest,
+			      test_lpm6_perf, TEST_DPDK_ABI_VERSION_V20);
diff --git a/app/test/v2.0/test_lpm_perf.c b/app/test/v2.0/test_lpm_perf.c
new file mode 100644
index 000000000..3c16213fe
--- /dev/null
+++ b/app/test/v2.0/test_lpm_perf.c
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ *
+ * LPM Autotests from DPDK v2.2.0 for v2.0 abi compability testing.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_random.h>
+#include <rte_branch_prediction.h>
+#include <rte_ip.h>
+#include <time.h>
+
+#include "../test.h"
+
+/* remapping of DPDK v2.0 symbols */
+#include "dcompat.h"
+/* backported header from DPDK v2.0 */
+#include "rte_lpm.h"
+#include "../test_lpm_routes.h"
+
+#define TEST_LPM_ASSERT(cond) do {              \
+    if (!(cond)) {                              \
+      printf("Error at line %d:\n", __LINE__);  \
+      return -1;                                \
+    }                                           \
+  } while (0)
+
+
+#define PASS 0
+
+/*
+ * Lookup performance test
+ */
+
+#define ITERATIONS (1 << 10)
+#define BATCH_SIZE (1 << 12)
+#define BULK_SIZE 32
+
+static int32_t test_lpm_perf(void);
+
+int32_t
+test_lpm_perf(void)
+{
+	struct rte_lpm *lpm = NULL;
+	uint64_t begin, total_time, lpm_used_entries = 0;
+	unsigned i, j;
+	uint8_t next_hop_add = 0xAA, next_hop_return = 0;
+	int status = 0;
+	uint64_t cache_line_counter = 0;
+	int64_t count = 0;
+
+	rte_srand(rte_rdtsc());
+
+	/* (re) generate the routing table */
+	generate_large_route_rule_table();
+
+	printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES);
+
+	print_route_distribution(large_route_table,
+				 (uint32_t) NUM_ROUTE_ENTRIES);
+
+	lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 1000000, 0);
+	TEST_LPM_ASSERT(lpm != NULL);
+
+	/* Measue add. */
+	begin = rte_rdtsc();
+
+	for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
+		if (rte_lpm_add(lpm, large_route_table[i].ip,
+				large_route_table[i].depth, next_hop_add) == 0)
+			status++;
+	}
+	/* End Timer. */
+	total_time = rte_rdtsc() - begin;
+
+	printf("Unique added entries = %d\n", status);
+	/* Obtain add statistics. */
+	for (i = 0; i < RTE_LPM_TBL24_NUM_ENTRIES; i++) {
+		if (lpm->tbl24[i].valid)
+			lpm_used_entries++;
+
+		if (i % 32 == 0){
+			if ((uint64_t)count < lpm_used_entries) {
+				cache_line_counter++;
+				count = lpm_used_entries;
+			}
+		}
+	}
+
+	printf("Used table 24 entries = %u (%g%%)\n",
+			(unsigned) lpm_used_entries,
+			(lpm_used_entries * 100.0) / RTE_LPM_TBL24_NUM_ENTRIES);
+	printf("64 byte Cache entries used = %u (%u bytes)\n",
+			(unsigned) cache_line_counter, (unsigned) cache_line_counter * 64);
+
+	printf("Average LPM Add: %g cycles\n", (double)total_time / NUM_ROUTE_ENTRIES);
+
+	/* Measure single Lookup */
+	total_time = 0;
+	count = 0;
+
+	for (i = 0; i < ITERATIONS; i++) {
+		static uint32_t ip_batch[BATCH_SIZE];
+
+		for (j = 0; j < BATCH_SIZE; j++)
+			ip_batch[j] = rte_rand();
+
+		/* Lookup per batch */
+		begin = rte_rdtsc();
+
+		for (j = 0; j < BATCH_SIZE; j++) {
+			if (rte_lpm_lookup(lpm, ip_batch[j], &next_hop_return) != 0)
+				count++;
+		}
+
+		total_time += rte_rdtsc() - begin;
+
+	}
+	printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
+			(double)total_time / ((double)ITERATIONS * BATCH_SIZE),
+			(count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
+
+	/* Measure bulk Lookup */
+	total_time = 0;
+	count = 0;
+	for (i = 0; i < ITERATIONS; i++) {
+		static uint32_t ip_batch[BATCH_SIZE];
+		uint16_t next_hops[BULK_SIZE];
+
+		/* Create array of random IP addresses */
+		for (j = 0; j < BATCH_SIZE; j++)
+			ip_batch[j] = rte_rand();
+
+		/* Lookup per batch */
+		begin = rte_rdtsc();
+		for (j = 0; j < BATCH_SIZE; j += BULK_SIZE) {
+			unsigned k;
+			rte_lpm_lookup_bulk(lpm, &ip_batch[j], next_hops, BULK_SIZE);
+			for (k = 0; k < BULK_SIZE; k++)
+				if (unlikely(!(next_hops[k] & RTE_LPM_LOOKUP_SUCCESS)))
+					count++;
+		}
+
+		total_time += rte_rdtsc() - begin;
+	}
+	printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
+			(double)total_time / ((double)ITERATIONS * BATCH_SIZE),
+			(count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
+
+	/* Measure LookupX4 */
+	total_time = 0;
+	count = 0;
+	for (i = 0; i < ITERATIONS; i++) {
+		static uint32_t ip_batch[BATCH_SIZE];
+		uint16_t next_hops[4];
+
+		/* Create array of random IP addresses */
+		for (j = 0; j < BATCH_SIZE; j++)
+			ip_batch[j] = rte_rand();
+
+		/* Lookup per batch */
+		begin = rte_rdtsc();
+		for (j = 0; j < BATCH_SIZE; j += RTE_DIM(next_hops)) {
+			unsigned k;
+			__m128i ipx4;
+
+			ipx4 = _mm_loadu_si128((__m128i *)(ip_batch + j));
+			ipx4 = *(__m128i *)(ip_batch + j);
+			rte_lpm_lookupx4(lpm, ipx4, next_hops, UINT16_MAX);
+			for (k = 0; k < RTE_DIM(next_hops); k++)
+				if (unlikely(next_hops[k] == UINT16_MAX))
+					count++;
+		}
+
+		total_time += rte_rdtsc() - begin;
+	}
+	printf("LPM LookupX4: %.1f cycles (fails = %.1f%%)\n",
+			(double)total_time / ((double)ITERATIONS * BATCH_SIZE),
+			(count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
+
+	/* Delete */
+	status = 0;
+	begin = rte_rdtsc();
+
+	for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
+		/* rte_lpm_delete(lpm, ip, depth) */
+		status += rte_lpm_delete(lpm, large_route_table[i].ip,
+				large_route_table[i].depth);
+	}
+
+	total_time += rte_rdtsc() - begin;
+
+	printf("Average LPM Delete: %g cycles\n",
+			(double)total_time / NUM_ROUTE_ENTRIES);
+
+	rte_lpm_delete_all(lpm);
+	rte_lpm_free(lpm);
+
+	return PASS;
+}
+
+REGISTER_TEST_COMMAND_VERSION(lpm_perf_autotest,
+			      test_lpm_perf, TEST_DPDK_ABI_VERSION_V20);
diff --git a/app/test/v2.0/test_v20.c b/app/test/v2.0/test_v20.c
new file mode 100644
index 000000000..6285e2882
--- /dev/null
+++ b/app/test/v2.0/test_v20.c
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <rte_ip.h>
+#include <rte_lpm.h>
+
+#include "../test.h"
+
+REGISTER_TEST_ABI_VERSION(v20, TEST_DPDK_ABI_VERSION_V20);
-- 
2.17.1


^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2 1/2] app/test: add abi version testing functionality
  2019-08-22 16:07  9% [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test Ray Kinsella
@ 2019-08-22 16:07 14% ` Ray Kinsella
  2019-08-22 16:07  4% ` [dpdk-dev] [PATCH v2 2/2] app/test: lpm abi version testing Ray Kinsella
  2019-08-23 15:49  4% ` [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test Aaron Conole
  2 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-22 16:07 UTC (permalink / raw)
  To: dev
  Cc: mdr, bruce.richardson, vladimir.medvedkin, john.mcnamara,
	marko.kovacevic

This patchset adds ABI Version Testing functionality to the app/test
unit test framework, comprised of

1. The TEST_DPDK_ABI_VERSION_* and REGISTER_TEST_ABI_VERSION macros to
   register abi versions with infrastructure.
2. The MAP_ABI_SYMBOL_VERSION macro to remap symbols based on their ABI
   version.
3. The set_abi_version command to switch between ABI versions.
4. The BIND_VERSION_SYMBOL macro to bind against specific symbol
   versions.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 app/test/commands.c                        | 131 ++++++++++++++++++---
 app/test/test.c                            |   2 +
 app/test/test.h                            |  52 ++++++--
 doc/guides/contributing/versioning.rst     |   4 +
 lib/librte_eal/common/include/rte_compat.h |   7 ++
 5 files changed, 170 insertions(+), 26 deletions(-)

diff --git a/app/test/commands.c b/app/test/commands.c
index 8d5a03a95..06fc33ee5 100644
--- a/app/test/commands.c
+++ b/app/test/commands.c
@@ -50,12 +50,22 @@
 
 /****************/
 
+static uint8_t test_abi_version = TEST_DPDK_ABI_VERSION_DEFAULT;
+
+static struct test_abi_version_list abi_version_list =
+	TAILQ_HEAD_INITIALIZER(abi_version_list);
+
 static struct test_commands_list commands_list =
 	TAILQ_HEAD_INITIALIZER(commands_list);
 
-void
-add_test_command(struct test_command *t)
+void add_abi_version(struct test_abi_version *av)
+{
+	TAILQ_INSERT_TAIL(&abi_version_list, av, next);
+}
+
+void add_test_command(struct test_command *t, uint8_t abi_version)
 {
+	t->abi_version = abi_version;
 	TAILQ_INSERT_TAIL(&commands_list, t, next);
 }
 
@@ -63,6 +73,12 @@ struct cmd_autotest_result {
 	cmdline_fixed_string_t autotest;
 };
 
+cmdline_parse_token_string_t
+cmd_autotest_autotest[TEST_DPDK_ABI_VERSION_MAX] = {
+	[0 ... TEST_DPDK_ABI_VERSION_MAX-1] =
+	TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest, "")
+};
+
 static void cmd_autotest_parsed(void *parsed_result,
 				__attribute__((unused)) struct cmdline *cl,
 				__attribute__((unused)) void *data)
@@ -72,7 +88,8 @@ static void cmd_autotest_parsed(void *parsed_result,
 	int ret = 0;
 
 	TAILQ_FOREACH(t, &commands_list, next) {
-		if (!strcmp(res->autotest, t->command))
+		if (!strcmp(res->autotest, t->command)
+				&& t->abi_version == test_abi_version)
 			ret = t->callback();
 	}
 
@@ -86,10 +103,6 @@ static void cmd_autotest_parsed(void *parsed_result,
 	fflush(stdout);
 }
 
-cmdline_parse_token_string_t cmd_autotest_autotest =
-	TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest,
-				 "");
-
 cmdline_parse_inst_t cmd_autotest = {
 	.f = cmd_autotest_parsed,  /* function to call */
 	.data = NULL,      /* 2nd arg of func */
@@ -244,6 +257,53 @@ cmdline_parse_inst_t cmd_quit = {
 
 /****************/
 
+struct cmd_set_abi_version_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t abi_version_name;
+};
+
+static void cmd_set_abi_version_parsed(
+				void *parsed_result,
+				__attribute__((unused)) struct cmdline *cl,
+				__attribute__((unused)) void *data)
+{
+	struct test_abi_version *av;
+	struct cmd_set_abi_version_result *res = parsed_result;
+
+	TAILQ_FOREACH(av, &abi_version_list, next) {
+		if (!strcmp(res->abi_version_name, av->version_name)) {
+
+			printf("abi version set to %s\n", av->version_name);
+			test_abi_version = av->version_id;
+			cmd_autotest.tokens[0] =
+				(void *)&cmd_autotest_autotest[av->version_id];
+		}
+	}
+
+	fflush(stdout);
+}
+
+cmdline_parse_token_string_t cmd_set_abi_version_set =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_abi_version_result, set,
+				"set_abi_version");
+
+cmdline_parse_token_string_t cmd_set_abi_version_abi_version =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_abi_version_result,
+				abi_version_name, NULL);
+
+cmdline_parse_inst_t cmd_set_abi_version = {
+	.f = cmd_set_abi_version_parsed,  /* function to call */
+	.data = NULL,      /* 2nd arg of func */
+	.help_str = "set abi version: ",
+	.tokens = {        /* token list, NULL terminated */
+		(void *)&cmd_set_abi_version_set,
+		(void *)&cmd_set_abi_version_abi_version,
+		NULL,
+	},
+};
+
+/****************/
+
 struct cmd_set_rxtx_result {
 	cmdline_fixed_string_t set;
 	cmdline_fixed_string_t mode;
@@ -259,7 +319,7 @@ static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl,
 
 cmdline_parse_token_string_t cmd_set_rxtx_set =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set,
-				 "set_rxtx_mode");
+				"set_rxtx_mode");
 
 cmdline_parse_token_string_t cmd_set_rxtx_mode =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL);
@@ -360,29 +420,66 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_rxtx,
 	(cmdline_parse_inst_t *)&cmd_set_rxtx_anchor,
 	(cmdline_parse_inst_t *)&cmd_set_rxtx_sc,
+	(cmdline_parse_inst_t *)&cmd_set_abi_version,
 	NULL,
 };
 
 int commands_init(void)
 {
+	struct test_abi_version *av;
 	struct test_command *t;
-	char *commands;
-	int commands_len = 0;
+	char *commands[TEST_DPDK_ABI_VERSION_MAX];
+	char *help;
+
+	int commands_len[TEST_DPDK_ABI_VERSION_MAX] = {
+		[0 ... TEST_DPDK_ABI_VERSION_MAX-1] = 0
+	};
+	int help_len = strlen(cmd_set_abi_version.help_str);
+	int abi_version;
+
+	/* set the set_abi_version command help string */
+	TAILQ_FOREACH(av, &abi_version_list, next) {
+		help_len += strlen(av->version_name) + 1;
+	}
+
+	help = (char *)calloc(help_len, sizeof(char));
+	if (!help)
+		return -1;
+
+	strlcat(help, cmd_set_abi_version.help_str, help_len);
+	TAILQ_FOREACH(av, &abi_version_list, next) {
+		strlcat(help, av->version_name, help_len);
+		if (TAILQ_NEXT(av, next) != NULL)
+			strlcat(help, "|", help_len);
+	}
+
+	cmd_set_abi_version.help_str = help;
 
+	/* set the parse strings for the command lists */
 	TAILQ_FOREACH(t, &commands_list, next) {
-		commands_len += strlen(t->command) + 1;
+		commands_len[t->abi_version] += strlen(t->command) + 1;
 	}
 
-	commands = (char *)calloc(commands_len, sizeof(char));
-	if (!commands)
-		return -1;
+	for (abi_version = 0; abi_version < TEST_DPDK_ABI_VERSION_MAX;
+		abi_version++) {
+		commands[abi_version] =
+			(char *)calloc(commands_len[abi_version], sizeof(char));
+		if (!commands[abi_version])
+			return -1;
+	}
 
 	TAILQ_FOREACH(t, &commands_list, next) {
-		strlcat(commands, t->command, commands_len);
+		strlcat(commands[t->abi_version],
+			t->command, commands_len[t->abi_version]);
 		if (TAILQ_NEXT(t, next) != NULL)
-			strlcat(commands, "#", commands_len);
+			strlcat(commands[t->abi_version],
+				"#", commands_len[t->abi_version]);
 	}
 
-	cmd_autotest_autotest.string_data.str = commands;
+	for (abi_version = 0; abi_version < TEST_DPDK_ABI_VERSION_MAX;
+		abi_version++)
+		cmd_autotest_autotest[abi_version].string_data.str =
+			commands[abi_version];
+
 	return 0;
 }
diff --git a/app/test/test.c b/app/test/test.c
index cd7aaf645..67179d4af 100644
--- a/app/test/test.c
+++ b/app/test/test.c
@@ -307,3 +307,5 @@ unit_test_suite_runner(struct unit_test_suite *suite)
 		return TEST_SKIPPED;
 	return TEST_SUCCESS;
 }
+
+REGISTER_TEST_ABI_VERSION(default, TEST_DPDK_ABI_VERSION_DEFAULT)
diff --git a/app/test/test.h b/app/test/test.h
index ac0c50616..5ec3728d0 100644
--- a/app/test/test.h
+++ b/app/test/test.h
@@ -162,25 +162,59 @@ int test_set_rxtx_conf(cmdline_fixed_string_t mode);
 int test_set_rxtx_anchor(cmdline_fixed_string_t type);
 int test_set_rxtx_sc(cmdline_fixed_string_t type);
 
+#define MAP_ABI_SYMBOL_VERSION(name, abi_version)                             \
+	__asm(".symver "RTE_STR(name)","RTE_STR(name)"@"RTE_STR(abi_version))
+
+#define TEST_DPDK_ABI_VERSION_DEFAULT 0
+#define TEST_DPDK_ABI_VERSION_V1604   1
+#define TEST_DPDK_ABI_VERSION_V20     2
+#define TEST_DPDK_ABI_VERSION_MAX     3
+
+TAILQ_HEAD(test_abi_version_list, test_abi_version);
+struct test_abi_version {
+	TAILQ_ENTRY(test_abi_version) next;
+	const char *version_name;
+	uint8_t version_id;
+};
+
+void add_abi_version(struct test_abi_version *av);
+
+/* Register a test function with its command string */
+#define REGISTER_TEST_ABI_VERSION(name, id)                                   \
+	static struct test_abi_version test_struct_##name = {                 \
+		.version_name = RTE_STR(name),                                \
+		.version_id = id,                                             \
+	};                                                                    \
+	RTE_INIT(test_register_##name)                                        \
+	{                                                                     \
+		add_abi_version(&test_struct_##name);                         \
+	}
+
 typedef int (test_callback)(void);
 TAILQ_HEAD(test_commands_list, test_command);
 struct test_command {
 	TAILQ_ENTRY(test_command) next;
 	const char *command;
 	test_callback *callback;
+	uint8_t abi_version;
 };
 
-void add_test_command(struct test_command *t);
+void add_test_command(struct test_command *t, uint8_t abi_version);
+
+/* Register a test function with its command string and abi version */
+#define REGISTER_TEST_COMMAND_VERSION(cmd, func, abi_version)                 \
+	static struct test_command test_struct_##cmd = {                      \
+		.command = RTE_STR(cmd),                                      \
+		.callback = func,                                             \
+	};                                                                    \
+	RTE_INIT(test_register_##cmd)                                         \
+	{                                                                     \
+		add_test_command(&test_struct_##cmd, abi_version);            \
+	}
 
 /* Register a test function with its command string */
+
 #define REGISTER_TEST_COMMAND(cmd, func) \
-	static struct test_command test_struct_##cmd = { \
-		.command = RTE_STR(cmd), \
-		.callback = func, \
-	}; \
-	RTE_INIT(test_register_##cmd) \
-	{ \
-		add_test_command(&test_struct_##cmd); \
-	}
+	REGISTER_TEST_COMMAND_VERSION(cmd, func, TEST_DPDK_ABI_VERSION_DEFAULT)
 
 #endif
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 3ab2c4346..63ef53ea3 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -221,6 +221,10 @@ The macros exported are:
   the linker to bind references to symbol ``b`` to the internal symbol
   ``b_e``.
 
+* ``BIND_VERSION_SYMBOL(b, n)``: Creates a symbol version entry instructing
+  the linker to bind references to symbol ``b`` to the external symbol
+  ``b@DPDK_n``
+
 * ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
   fully qualified function ``p``, so that if a symbol becomes versioned, it
   can still be mapped back to the public symbol name.
diff --git a/lib/librte_eal/common/include/rte_compat.h b/lib/librte_eal/common/include/rte_compat.h
index 92ff28faf..be9724f4c 100644
--- a/lib/librte_eal/common/include/rte_compat.h
+++ b/lib/librte_eal/common/include/rte_compat.h
@@ -50,6 +50,13 @@
 #define BIND_DEFAULT_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@@DPDK_" RTE_STR(n))
 #define __vsym __attribute__((used))
 
+/*
+ * BIND_VERSION_SYMBOL
+ * Creates a symbol version entry instructing the linker to bind references to
+ * symbol <b> to the symbol version <b>@DPDK_<n>
+ */
+#define BIND_VERSION_SYMBOL(b, n) __asm__(".symver " RTE_STR(b) ", " RTE_STR(b) "@DPDK_" RTE_STR(n))
+
 /*
  * MAP_STATIC_SYMBOL
  * If a function has been bifurcated into multiple versions, none of which
-- 
2.17.1


^ permalink raw reply	[relevance 14%]

* [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test
@ 2019-08-22 16:07  9% Ray Kinsella
  2019-08-22 16:07 14% ` [dpdk-dev] [PATCH v2 1/2] app/test: add abi version testing functionality Ray Kinsella
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Ray Kinsella @ 2019-08-22 16:07 UTC (permalink / raw)
  To: dev
  Cc: mdr, bruce.richardson, vladimir.medvedkin, john.mcnamara,
	marko.kovacevic

This patchset adds ABI version testing to the app/test unit test framework,
addressing two issues previously raised during ML conversations on ABI
stability;

1. How do we unit test still supported previous ABI versions?
2. How to we unit test inline functions from still supported previous ABI
versions?

Starting with rte_lpm, I did the following:-

* I reproduced mostly unmodified unit tests for the v2.0 ABI, taken from DPDK
  2.2 and 17.02.
* I reproduced the rte_lpm interface header from v2.0, including the inline
  functions and remapping symbols to their appropriate versions.
* I added support for multiple abi versions to the app/test unit test framework
  to allow users to switch between abi versions (set_abi_version), without
  further polluting the already long list of unit tests available in app/test.

The intention here is that in future as developers need to deprecate APIs, the
associated unit tests may move into the ABI version testing mechanism of the
app/test instead of being replaced by the latest set of unit tests as would be
the case today.

v2:

* Added LPM IPv6 test cases for the v2.0 ABI.
* Fixed a number of checkpatch errors, stop short of substantially reworking
  the test code from the v2.0 ABI. 
* Removed duplicating test cases published in the original v1 patch.

Ray Kinsella (2):
  app/test: add abi version testing functionality
  app/test: lpm abi version testing

 app/test/Makefile                          |   12 +-
 app/test/commands.c                        |  131 +-
 app/test/meson.build                       |    6 +
 app/test/test.c                            |    2 +
 app/test/test.h                            |   48 +-
 app/test/test_lpm.c                        |    3 +-
 app/test/test_lpm6.c                       |    2 +-
 app/test/test_lpm_perf.c                   |  293 +---
 app/test/test_lpm_routes.c                 |  287 ++++
 app/test/test_lpm_routes.h                 |   25 +
 app/test/v2.0/dcompat.h                    |   30 +
 app/test/v2.0/rte_lpm.h                    |  451 +++++
 app/test/v2.0/rte_lpm6.h                   |  198 +++
 app/test/v2.0/test_lpm.c                   | 1139 +++++++++++++
 app/test/v2.0/test_lpm6.c                  | 1748 ++++++++++++++++++++
 app/test/v2.0/test_lpm6_perf.c             |  179 ++
 app/test/v2.0/test_lpm_perf.c              |  212 +++
 app/test/v2.0/test_v20.c                   |   14 +
 doc/guides/contributing/versioning.rst     |    4 +
 lib/librte_eal/common/include/rte_compat.h |    7 +
 20 files changed, 4471 insertions(+), 320 deletions(-)
 create mode 100644 app/test/test_lpm_routes.c
 create mode 100644 app/test/test_lpm_routes.h
 create mode 100644 app/test/v2.0/dcompat.h
 create mode 100644 app/test/v2.0/rte_lpm.h
 create mode 100644 app/test/v2.0/rte_lpm6.h
 create mode 100644 app/test/v2.0/test_lpm.c
 create mode 100644 app/test/v2.0/test_lpm6.c
 create mode 100644 app/test/v2.0/test_lpm6_perf.c
 create mode 100644 app/test/v2.0/test_lpm_perf.c
 create mode 100644 app/test/v2.0/test_v20.c

-- 
2.17.1


^ permalink raw reply	[relevance 9%]

* Re: [dpdk-dev] [PATCH v2] ethdev: add more protocol support in flow API
  2019-08-14  9:08  4%   ` Adrien Mazarguil
@ 2019-08-19 11:53  0%     ` Zhang, Qi Z
  0 siblings, 0 replies; 200+ results
From: Zhang, Qi Z @ 2019-08-19 11:53 UTC (permalink / raw)
  To: Adrien Mazarguil, Wang, Ying A; +Cc: Ye, Xiaolong, Yang, Qiming, dev



> -----Original Message-----
> From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> Sent: Wednesday, August 14, 2019 5:08 PM
> To: Wang, Ying A <ying.a.wang@intel.com>
> Cc: Zhang, Qi Z <qi.z.zhang@intel.com>; Ye, Xiaolong <xiaolong.ye@intel.com>;
> Yang, Qiming <qiming.yang@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2] ethdev: add more protocol support in flow
> API
> 
> Hi Wang Ying,
> 
> On Wed, Aug 14, 2019 at 11:24:30AM +0800, Wang Ying A wrote:
> > Add new protocol header match support as below
> >
> > RTE_FLOW_ITEM_TYPE_GTP_PSC
> > 	- matches a GTP PDU extension header (type is 0x85:
> > 	PDU Session Container)
> > RTE_FLOW_ITEM_TYPE_PPPOES
> > 	- matches a PPPoE Session header.
> > RTE_FLOW_ITEM_TYPE_PPPOED
> > 	- matches a PPPoE Discovery stage header.
> >
> > Signed-off-by: Wang Ying A <ying.a.wang@intel.com>
> 
> OK, please split this patch, one for GTP and the other for PPPoE to make title
> less vague than "add more protocol support".
> 
> For PPPoE, the distinction between session and discovery is not a bad idea but
> since discovery packets typically have a different format (tags in place of
> protocol), I'm not sure they should share a common structure.
> 
> How about a single "PPPOE" item without proto_id to cover both session and
> discovery, then later add separate tag items on a needed basis for each
> possible/optional tag (e.g. PPPOE_TAG_SERVICE_NAME)? Likewise proto_id
> would be provided through a separate optional item if relevant
> (PPPOE_PROTO_ID).

PPPoE Discovery had PPPoE Session has different ethertype 0x8863 , 0x8864, so I think they should belong to separate
match item,( image the case we only need to match a PPPoE Session flow but don't care what kind of protocol payload it have )
but I agree they should only share the common part of the header,
then for PPPoED, it can append optional PPPoE Tag item(s) and for PPPoES , it can append optional PPPoE Protocol item(s)

> Such an approach is already used for IPV6 and IPV6_EXT.
> 
> Another benefit is that applications could match PPPoE regardless of session or
> discovery when they do not care, while PPPOED/PPPOES make that distinction
> mandatory.
> 
> Also by inserting new entries in the middle of the pattern items list, this patch
> breaks ABI. I think it's not on purpose, so please move them to the end (not
> grouping them with existing GTP stuff is fine, ABI compat is more
> important.) This must be reflected in rte_flow.h, rte_flow.c, testpmd and
> documentation.
> 
> More nits below.
> 
> > ---
> > ---
> > v2: Remove Gerrit Change-Id's.
> > ---
> >  app/test-pmd/cmdline_flow.c                 | 80
> +++++++++++++++++++++++++++++
> >  doc/guides/prog_guide/rte_flow.rst          | 25 +++++++++
> >  doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 ++++
> >  lib/librte_ethdev/rte_flow.c                |  3 ++
> >  lib/librte_ethdev/rte_flow.h                | 71
> +++++++++++++++++++++++++
> >  5 files changed, 189 insertions(+)
> >
> > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> [...]
> > +	[ITEM_PPPOES] = {
> > +		.name = "pppoes",
> > +		.help = "match PPPoE Session header",
> 
> Session => session
> 
> > +		.priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
> > +		.next = NEXT(item_pppoe),
> > +		.call = parse_vc,
> > +	},
> > +	[ITEM_PPPOED] = {
> > +		.name = "pppoed",
> > +		.help = "match PPPoE Discovery stage header",
> 
> Discovery => discovery
> 
> > +		.priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
> > +		.next = NEXT(item_pppoe),
> > +		.call = parse_vc,
> > +	},
> > +	[ITEM_PPPOE_SEID] = {
> > +		.name = "seid",
> > +		.help = "Session identifier",
> 
> Session => session
> 
> [...]
> > diff --git a/doc/guides/prog_guide/rte_flow.rst
> > b/doc/guides/prog_guide/rte_flow.rst
> > index 821b524b3..d09c42071 100644
> > --- a/doc/guides/prog_guide/rte_flow.rst
> > +++ b/doc/guides/prog_guide/rte_flow.rst
> > @@ -1055,6 +1055,31 @@ flow rules.
> >  - ``teid``: tunnel endpoint identifier.
> >  - Default ``mask`` matches teid only.
> >
> > +Item: ``GTP_PSC``
> > +^^^^^^^^^^^^^^^^^^^^^^^
> 
> Too many "^^^"'s.
> 
> [...]
> > +Item: ``PPPOES``, ``PPPOED``
> > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > +
> > +Matches a PPPOE header.
> 
> PPPOE => PPPoE
> 
> > +
> > +Note: PPPOES and PPPOED use the same structure. PPPOES and PPPOED
> > +item
> 
> item => items (or better, "pattern items")
> 
> > +are defined for a user-friendly API when creating PPPOE-Session and
> > +PPPOE-Discovery flow rules.
> 
> Super nit: use "PPPoE" when mentioning the protocol itself and "PPPOE" when
> mentioning the pattern item.
> 
> > +
> > +- ``v_t_flags``: version (4b), type (4b).
> 
> Why "flags"? I don't see any so you could name it "version_type" (same in
> documentation).
> 
> > +- ``code``: Message type.
> 
> Message => message
> 
> > +- ``session_id``: Session identifier.
> 
> Session => session
> 
> > +- ``length``: Payload length.
> 
> Payload => payload
> 
> > +- ``proto_id``: PPP Protocol identifier.
> 
> Protocol => protocol
> 
> > +- Default ``mask`` matches session_id,proto_id.
> 
> Missing space between session_id and proto_id.
> 
> > +
> >  Item: ``ESP``
> >  ^^^^^^^^^^^^^
> >
> > diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> > b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> > index 313e0707e..0da36d5f1 100644
> > --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> > +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> > @@ -3904,6 +3904,16 @@ This section lists supported pattern items and
> their attributes, if any.
> >
> >    - ``teid {unsigned}``: tunnel endpoint identifier.
> >
> > +- ``gtp_psc``: match GTPv1 entension header (type is 0x85).
> > +
> > +  - ``pdu_type {unsigned}``: PDU type (0 or 1).
> > +  - ``qfi {unsigned}``: QoS flow identifier.
> > +
> > +- ``pppoes``, ``pppoed``: match PPPOE header.
> 
> PPPOE => PPPoE
> 
> [...]
> > diff --git a/lib/librte_ethdev/rte_flow.h
> > b/lib/librte_ethdev/rte_flow.h index b66bf1495..ad5e46190 100644
> > --- a/lib/librte_ethdev/rte_flow.h
> > +++ b/lib/librte_ethdev/rte_flow.h
> > @@ -328,6 +328,34 @@ enum rte_flow_item_type {
> >  	 */
> >  	RTE_FLOW_ITEM_TYPE_GTPU,
> >
> > +	/**
> > +	 * Matches a GTP PDU extension header (type is 0x85:
> > +	 * PDU Session Container).
> 
> Session Container => session container
> 
> > +	 *
> > +	 * Configure flow for GTP packets with extension header type 0x85.
> > +	 *
> > +	 * See struct rte_flow_item_gtp_psc.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_GTP_PSC,
> > +
> > +	/**
> > +	 * Matches a PPPOE header.
> > +	 *
> > +	 * Configure flow for PPPoE Session packets.
> 
> Session => session
> 
> > +	 *
> > +	 * See struct rte_flow_item_pppoe.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_PPPOES,
> > +
> > +	/**
> > +	 * Matches a PPPOE header.
> > +	 *
> > +	 * Configure flow for PPPoE Discovery stage packets.
> 
> Discovery => discovery
> 
> > +	 *
> > +	 * See struct rte_flow_item_pppoe.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_PPPOED,
> > +
> >  	/**
> >  	 * Matches a ESP header.
> >  	 *
> > @@ -922,6 +950,49 @@ static const struct rte_flow_item_gtp
> > rte_flow_item_gtp_mask = {  };  #endif
> >
> > +/**
> > + * RTE_FLOW_ITEM_TYPE_GTP_PSC.
> > + *
> > + * Matches a GTP-extension header
> > + * (type is 0x85: PDU Session Container).
> 
> Session Container => session container
> 
> (crusade against superfluous caps!)
> 
> [...]
> > +/**
> > + * RTE_FLOW_ITEM_TYPE_PPPOE.
> > + *
> > + * Matches a PPPOE header.
> > + */
> > +struct rte_flow_item_pppoe {
> > +	/**
> > +	 * Version (4b), type (4b).
> > +	 */
> > +	uint8_t v_t_flags;
> 
> v_t_flags => version_type
> 
> > +	uint8_t code; /**< Message type. */
> > +	rte_be16_t session_id; /**< Session identifier. */
> > +	rte_be16_t length; /**< Payload length. */
> > +	rte_be16_t proto_id; /**< PPP Protocol identifier. */
> 
> As discussed, I suggest dropping proto_id to make this a generic match for
> PPPoE.
> 
> > +};
> > +
> > +/** Default mask for RTE_FLOW_ITEM_TYPE_PPPOE. */ #ifndef __cplusplus
> > +static const struct rte_flow_item_pppoe rte_flow_item_pppoe_mask = {
> > +	.session_id = RTE_BE16(0xffff),
> > +	.proto_id = RTE_BE16(0xffff),
> > +};
> 
> I think the default for PPPoE should be an empty mask that simply says "match
> PPPoE" since session_id only becomes known after negotiation and proto_id
> shouldn't be part of this object.
> 
> --
> Adrien Mazarguil
> 6WIND

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v10 3/5] kni: add app specific mempool create and free routines
  @ 2019-08-16  6:12  3%   ` vattunuru
  0 siblings, 0 replies; 200+ results
From: vattunuru @ 2019-08-16  6:12 UTC (permalink / raw)
  To: dev
  Cc: thomas, jerinj, olivier.matz, ferruh.yigit, anatoly.burakov,
	arybchenko, kirankumark, Vamsi Attunuru

From: Vamsi Attunuru <vattunuru@marvell.com>

When KNI operates in IOVA = VA mode, it requires mbuf memory
to be physically contiguous to ensure KNI kernel module could
translate IOVA addresses properly. Patch adds a KNI specific
mempool create routine to populate the KNI packet mbuf pool
with memory objects that are being on a page.

KNI applications need to use this mempool create & free routines
so that mbuf related requirements in IOVA = VA mode are handled
inside those routines based on the enabled mode.

Updated the release notes with these new routine details.

Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
 doc/guides/rel_notes/release_19_11.rst |  5 +++
 examples/kni/main.c                    |  5 ++-
 lib/librte_kni/Makefile                |  1 +
 lib/librte_kni/meson.build             |  1 +
 lib/librte_kni/rte_kni.c               | 60 ++++++++++++++++++++++++++++++++++
 lib/librte_kni/rte_kni.h               | 48 +++++++++++++++++++++++++++
 lib/librte_kni/rte_kni_version.map     |  2 ++
 7 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 8490d89..8813a10 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -85,6 +85,11 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* kni: ``rte_kni_pktmbuf_pool_create`` ``rte_kni_pktmbuf_pool_free`` functions
+  were introduced for KNI applications for creating & freeing packet pool.
+  Since IOVA=VA mode was added in KNI, packet pool's mbuf memory should be
+  physically contiguous for the KNI kernel module to work in IOVA=VA mode,
+  this requirement was taken care in the kni packet pool creation fucntions.
 
 ABI Changes
 -----------
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 4710d71..fdfeed2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -975,7 +975,7 @@ main(int argc, char** argv)
 		rte_exit(EXIT_FAILURE, "Could not parse input parameters\n");
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+	pktmbuf_pool = rte_kni_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
 		MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool\n");
@@ -1043,6 +1043,9 @@ main(int argc, char** argv)
 			continue;
 		kni_free_kni(port);
 	}
+
+	rte_kni_pktmbuf_pool_free(pktmbuf_pool);
+
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
 		if (kni_port_params_array[i]) {
 			rte_free(kni_port_params_array[i]);
diff --git a/lib/librte_kni/Makefile b/lib/librte_kni/Makefile
index ab15d10..5e3dd01 100644
--- a/lib/librte_kni/Makefile
+++ b/lib/librte_kni/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 # library name
 LIB = librte_kni.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing
 CFLAGS += -I$(RTE_SDK)/drivers/bus/pci
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev
diff --git a/lib/librte_kni/meson.build b/lib/librte_kni/meson.build
index fd46f87..e357445 100644
--- a/lib/librte_kni/meson.build
+++ b/lib/librte_kni/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 if not is_linux or not dpdk_conf.get('RTE_ARCH_64')
 	build = false
 	reason = 'only supported on 64-bit linux'
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 2aaaeaa..15dda45 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -22,6 +22,7 @@
 #include <rte_tailq.h>
 #include <rte_rwlock.h>
 #include <rte_eal_memconfig.h>
+#include <rte_mbuf_pool_ops.h>
 #include <rte_kni_common.h>
 #include "rte_kni_fifo.h"
 
@@ -681,6 +682,65 @@ kni_allocate_mbufs(struct rte_kni *kni)
 	}
 }
 
+struct rte_mempool *
+rte_kni_pktmbuf_pool_create(const char *name, unsigned int n,
+	unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id)
+{
+	struct rte_pktmbuf_pool_private mbp_priv;
+	const char *mp_ops_name;
+	struct rte_mempool *mp;
+	unsigned int elt_size;
+	int ret;
+
+	if (RTE_ALIGN(priv_size, RTE_MBUF_PRIV_ALIGN) != priv_size) {
+		RTE_LOG(ERR, MBUF, "mbuf priv_size=%u is not aligned\n",
+			priv_size);
+		rte_errno = EINVAL;
+		return NULL;
+	}
+	elt_size = sizeof(struct rte_mbuf) + (unsigned int)priv_size +
+		(unsigned int)data_room_size;
+	mbp_priv.mbuf_data_room_size = data_room_size;
+	mbp_priv.mbuf_priv_size = priv_size;
+
+	mp = rte_mempool_create_empty(name, n, elt_size, cache_size,
+		 sizeof(struct rte_pktmbuf_pool_private), socket_id, 0);
+	if (mp == NULL)
+		return NULL;
+
+	mp_ops_name = rte_mbuf_best_mempool_ops();
+	ret = rte_mempool_set_ops_byname(mp, mp_ops_name, NULL);
+	if (ret != 0) {
+		RTE_LOG(ERR, MBUF, "error setting mempool handler\n");
+		rte_mempool_free(mp);
+		rte_errno = -ret;
+		return NULL;
+	}
+	rte_pktmbuf_pool_init(mp, &mbp_priv);
+
+	if (rte_eal_iova_mode() == RTE_IOVA_VA)
+		ret = rte_mempool_populate_from_pg_sz_chunks(mp);
+	else
+		ret = rte_mempool_populate_default(mp);
+
+	if (ret < 0) {
+		rte_mempool_free(mp);
+		rte_errno = -ret;
+		return NULL;
+	}
+
+	rte_mempool_obj_iter(mp, rte_pktmbuf_init, NULL);
+
+	return mp;
+}
+
+void
+rte_kni_pktmbuf_pool_free(struct rte_mempool *mp)
+{
+	rte_mempool_free(mp);
+}
+
 struct rte_kni *
 rte_kni_get(const char *name)
 {
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 5699a64..99d263d 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -184,6 +184,54 @@ unsigned rte_kni_tx_burst(struct rte_kni *kni, struct rte_mbuf **mbufs,
 		unsigned num);
 
 /**
+ * Create a kni packet mbuf pool.
+ *
+ * This function creates and initializes a packet mbuf pool for KNI applications
+ * It calls the required mempool populate routine based on the IOVA mode.
+ *
+ * @param name
+ *   The name of the mbuf pool.
+ * @param n
+ *   The number of elements in the mbuf pool. The optimum size (in terms
+ *   of memory usage) for a mempool is when n is a power of two minus one:
+ *   n = (2^q - 1).
+ * @param cache_size
+ *   Size of the per-core object cache. See rte_mempool_create() for
+ *   details.
+ * @param priv_size
+ *   Size of application private are between the rte_mbuf structure
+ *   and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
+ * @param data_room_size
+ *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
+ * @param socket_id
+ *   The socket identifier where the memory should be allocated. The
+ *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
+ *   reserved zone.
+ * @return
+ *   The pointer to the new allocated mempool, on success. NULL on error
+ *   with rte_errno set appropriately. Possible rte_errno values include:
+ *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ *    - E_RTE_SECONDARY - function was called from a secondary process instance
+ *    - EINVAL - cache size provided is too large, or priv_size is not aligned.
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a memzone with the same name already exists
+ *    - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+__rte_experimental
+struct rte_mempool *rte_kni_pktmbuf_pool_create(const char *name,
+		unsigned int n, unsigned int cache_size, uint16_t priv_size,
+		uint16_t data_room_size, int socket_id);
+
+/**
+ * Free the given packet mempool.
+ *
+ * @param mp
+ *  The mempool pointer.
+ */
+__rte_experimental
+void rte_kni_pktmbuf_pool_free(struct rte_mempool *mp);
+
+/**
  * Get the KNI context of its name.
  *
  * @param name
diff --git a/lib/librte_kni/rte_kni_version.map b/lib/librte_kni/rte_kni_version.map
index c877dc6..aba9728 100644
--- a/lib/librte_kni/rte_kni_version.map
+++ b/lib/librte_kni/rte_kni_version.map
@@ -20,4 +20,6 @@ EXPERIMENTAL {
 	global:
 
 	rte_kni_update_link;
+	rte_kni_pktmbuf_pool_create;
+	rte_kni_pktmbuf_pool_free;
 };
-- 
2.8.4


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC] ethdev: configure SR-IOV VF from host
@ 2019-08-16  5:16  0% Jerin Jacob Kollanukkaran
  0 siblings, 0 replies; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-08-16  5:16 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Ferruh Yigit, Andrew Rybchenko, dev, Bernard Iremonger,
	Shahaf Shuler, E. Scott Daniels, Wenzhuo Lu, Alex Zelezniak,
	Ajit Khaparde, Declan Doherty



> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Thursday, August 15, 2019 11:29 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> Cc: Ferruh Yigit <ferruh.yigit@intel.com>; Andrew Rybchenko
> <arybchenko@solarflare.com>; dev@dpdk.org; Bernard Iremonger
> <bernard.iremonger@intel.com>; Shahaf Shuler <shahafs@mellanox.com>;
> E. Scott Daniels <daniels@research.att.com>; Wenzhuo Lu
> <wenzhuo.lu@intel.com>; Alex Zelezniak <alexz@att.com>; Ajit Khaparde
> <ajit.khaparde@broadcom.com>; Declan Doherty
> <declan.doherty@intel.com>
> Subject: [EXT] Re: [dpdk-dev] [RFC] ethdev: configure SR-IOV VF from host
> 
> External Email
> 
> ----------------------------------------------------------------------
> 15/08/2019 17:34, Jerin Jacob Kollanukkaran:
> > From: Thomas Monjalon
> > >
> > > In a virtual environment, the network controller may have to
> > > configure some SR-IOV VF parameters for security reasons.
> > >
> > > When the PF (host port) is drived by DPDK (OVS-DPDK case), we face
> > > two different cases:
> > > 	- driver is bifurcated (Mellanox case),
> > > 	so the VF can be configured via the kernel.
> > > 	- driver is on top of UIO or VFIO, so DPDK API is required.
> > >
> > > This RFC proposes to use generic DPDK API for VF configuration.
> > > The impacted functions are (can be extended):
> > >
> > > 	- rte_eth_dev_is_valid_port
> > > 	- rte_eth_promiscuous_enable
> > > 	- rte_eth_promiscuous_disable
> > > 	- rte_eth_promiscuous_get
> > > 	- rte_eth_allmulticast_enable
> > > 	- rte_eth_allmulticast_disable
> > > 	- rte_eth_allmulticast_get
> > > 	- rte_eth_dev_set_mc_addr_list
> > > 	- rte_eth_dev_default_mac_addr_set
> > > 	- rte_eth_macaddr_get
> > > 	- rte_eth_dev_mac_addr_add
> > > 	- rte_eth_dev_mac_addr_remove
> > > 	- rte_eth_dev_vlan_filter
> > > 	- rte_eth_dev_get_mtu
> > > 	- rte_eth_dev_set_mtu
> > >
> > > In order to target these functions to a VF (which has no port id in
> > > the host), the higher bit of port id is reserved:
> > >
> > > #define RTE_ETH_VF_PORT_FLAG (1 << 15)
> >
> > Instead of changing the port number behavior, How about adding a bit
> > field/ I think, There is no ABI breakage as the parent type of bit
> > field  is uint8_t and there is still more room.
> >
> > --- a/lib/librte_ethdev/rte_ethdev_core.h
> > +++ b/lib/librte_ethdev/rte_ethdev_core.h
> > @@ -621,6 +621,7 @@ struct rte_eth_dev_data {
> >                 all_multicast : 1, /**< RX all multicast mode ON(1) / OFF(0). */
> >                 dev_started : 1,   /**< Device state: STARTED(1) / STOPPED(0). */
> >                 lro         : 1;   /**< RX LRO is ON(1) / OFF(0) */
> > +               vf         : 1;   /**< SR-IOV VF device */
> >         uint8_t rx_queue_state[RTE_MAX_QUEUES_PER_PORT];
> >                         /**< Queues state: STARTED(1) / STOPPED(0). */
> >         uint8_t tx_queue_state[RTE_MAX_QUEUES_PER_PORT];
> 
> Sorry I don't understand how it can help.
> We need to specify which VF we want to configure.
> 
> My proposal is to use the representor port, which is connected to a VF.

I got confused with non-representor case. Yes, My comment is not valid for
port representor case.


> We distinguish the representor and the VF with a flag in the port id
> parameter passed to the functions.
> 


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] ethdev: configure SR-IOV VF from host
  2019-08-15 15:34  3% ` Jerin Jacob Kollanukkaran
@ 2019-08-15 17:59  0%   ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-08-15 17:59 UTC (permalink / raw)
  To: Jerin Jacob Kollanukkaran
  Cc: Ferruh Yigit, Andrew Rybchenko, dev, Bernard Iremonger,
	Shahaf Shuler, E. Scott Daniels, Wenzhuo Lu, Alex Zelezniak,
	Ajit Khaparde, Declan Doherty

15/08/2019 17:34, Jerin Jacob Kollanukkaran:
> From: Thomas Monjalon
> > 
> > In a virtual environment, the network controller may have to configure some
> > SR-IOV VF parameters for security reasons.
> > 
> > When the PF (host port) is drived by DPDK (OVS-DPDK case), we face two
> > different cases:
> > 	- driver is bifurcated (Mellanox case),
> > 	so the VF can be configured via the kernel.
> > 	- driver is on top of UIO or VFIO, so DPDK API is required.
> > 
> > This RFC proposes to use generic DPDK API for VF configuration.
> > The impacted functions are (can be extended):
> > 
> > 	- rte_eth_dev_is_valid_port
> > 	- rte_eth_promiscuous_enable
> > 	- rte_eth_promiscuous_disable
> > 	- rte_eth_promiscuous_get
> > 	- rte_eth_allmulticast_enable
> > 	- rte_eth_allmulticast_disable
> > 	- rte_eth_allmulticast_get
> > 	- rte_eth_dev_set_mc_addr_list
> > 	- rte_eth_dev_default_mac_addr_set
> > 	- rte_eth_macaddr_get
> > 	- rte_eth_dev_mac_addr_add
> > 	- rte_eth_dev_mac_addr_remove
> > 	- rte_eth_dev_vlan_filter
> > 	- rte_eth_dev_get_mtu
> > 	- rte_eth_dev_set_mtu
> > 
> > In order to target these functions to a VF (which has no port id in the host),
> > the higher bit of port id is reserved:
> > 
> > #define RTE_ETH_VF_PORT_FLAG (1 << 15)
> 
> Instead of changing the port number behavior, How about adding a bit field/
> I think, There is no ABI breakage as the parent type of bit field  is uint8_t and there
> is still more room.
> 
> --- a/lib/librte_ethdev/rte_ethdev_core.h
> +++ b/lib/librte_ethdev/rte_ethdev_core.h
> @@ -621,6 +621,7 @@ struct rte_eth_dev_data {
>                 all_multicast : 1, /**< RX all multicast mode ON(1) / OFF(0). */
>                 dev_started : 1,   /**< Device state: STARTED(1) / STOPPED(0). */
>                 lro         : 1;   /**< RX LRO is ON(1) / OFF(0) */
> +               vf         : 1;   /**< SR-IOV VF device */
>         uint8_t rx_queue_state[RTE_MAX_QUEUES_PER_PORT];
>                         /**< Queues state: STARTED(1) / STOPPED(0). */
>         uint8_t tx_queue_state[RTE_MAX_QUEUES_PER_PORT];

Sorry I don't understand how it can help.
We need to specify which VF we want to configure.

My proposal is to use the representor port,
which is connected to a VF.
We distinguish the representor and the VF with a flag in the port id
parameter passed to the functions.



^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] ethdev: configure SR-IOV VF from host
  @ 2019-08-15 15:34  3% ` Jerin Jacob Kollanukkaran
  2019-08-15 17:59  0%   ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-08-15 15:34 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: dev, Bernard Iremonger, Shahaf Shuler, E. Scott Daniels,
	Wenzhuo Lu, Alex Zelezniak, Ajit Khaparde, Declan Doherty

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> Sent: Thursday, August 15, 2019 8:36 PM
> To: Ferruh Yigit <ferruh.yigit@intel.com>; Andrew Rybchenko
> <arybchenko@solarflare.com>
> Cc: dev@dpdk.org; Bernard Iremonger <bernard.iremonger@intel.com>;
> Shahaf Shuler <shahafs@mellanox.com>; E. Scott Daniels
> <daniels@research.att.com>; Wenzhuo Lu <wenzhuo.lu@intel.com>; Alex
> Zelezniak <alexz@att.com>; Ajit Khaparde <ajit.khaparde@broadcom.com>;
> Declan Doherty <declan.doherty@intel.com>
> Subject: [dpdk-dev] [RFC] ethdev: configure SR-IOV VF from host
> 
> In a virtual environment, the network controller may have to configure some
> SR-IOV VF parameters for security reasons.
> 
> When the PF (host port) is drived by DPDK (OVS-DPDK case), we face two
> different cases:
> 	- driver is bifurcated (Mellanox case),
> 	so the VF can be configured via the kernel.
> 	- driver is on top of UIO or VFIO, so DPDK API is required.
> 
> This RFC proposes to use generic DPDK API for VF configuration.
> The impacted functions are (can be extended):
> 
> 	- rte_eth_dev_is_valid_port
> 	- rte_eth_promiscuous_enable
> 	- rte_eth_promiscuous_disable
> 	- rte_eth_promiscuous_get
> 	- rte_eth_allmulticast_enable
> 	- rte_eth_allmulticast_disable
> 	- rte_eth_allmulticast_get
> 	- rte_eth_dev_set_mc_addr_list
> 	- rte_eth_dev_default_mac_addr_set
> 	- rte_eth_macaddr_get
> 	- rte_eth_dev_mac_addr_add
> 	- rte_eth_dev_mac_addr_remove
> 	- rte_eth_dev_vlan_filter
> 	- rte_eth_dev_get_mtu
> 	- rte_eth_dev_set_mtu
> 
> In order to target these functions to a VF (which has no port id in the host),
> the higher bit of port id is reserved:
> 
> #define RTE_ETH_VF_PORT_FLAG (1 << 15)

Instead of changing the port number behavior, How about adding a bit field/
I think, There is no ABI breakage as the parent type of bit field  is uint8_t and there
is still more room.

diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index 2922d5b7c..19a60cab2 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -621,6 +621,7 @@ struct rte_eth_dev_data {
                all_multicast : 1, /**< RX all multicast mode ON(1) / OFF(0). */
                dev_started : 1,   /**< Device state: STARTED(1) / STOPPED(0). */
                lro         : 1;   /**< RX LRO is ON(1) / OFF(0) */
+               vf         : 1;   /**< SR-IOV VF device */
        uint8_t rx_queue_state[RTE_MAX_QUEUES_PER_PORT];
                        /**< Queues state: STARTED(1) / STOPPED(0). */
        uint8_t tx_queue_state[RTE_MAX_QUEUES_PER_PORT];


> 
> This bit can be combined only with the port id of a representor.
> The meaning is to target the VF connected with the representor port, instead
> of the representor port itself.
> 
> If a function is not expected to support VF configuration, it will return -
> EINVAL, i.e. there is no code change.
> If an API function (listed above) can support VF configuration, but the PMD
> does not support it, then -ENOTSUP must be returned.
> 
> As an example, this is the change required in rte_eth_dev_is_valid_port:
> 
>  int
>  rte_eth_dev_is_valid_port(uint16_t port_id)  {
> +       uint32_t dev_flags;
> +       uint16_t vf_flag;
> +
> +       vf_flag = port_id & RTE_ETH_VF_PORT_FLAG;
> +       port_id &= RTE_ETH_VF_PORT_FLAG - 1; /* remove VF flag */
> +
>         if (port_id >= RTE_MAX_ETHPORTS ||
>             (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED))
>                 return 0;
> -       else
> -               return 1;
> +
> +       dev_flags = rte_eth_dev_shared_data->data[port_id].dev_flags;
> +       if (vf_flag != 0 && (dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0)
> +               return 0; /* VF flag has no meaning if not a representor
> + */
> +
> +       return 1;
>  }
> 
> 


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v3 1/4] doc: separate versioning.rst into version and policy
  2019-08-15 10:23 11% [dpdk-dev] [PATCH v3 0/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
@ 2019-08-15 10:23 13% ` Ray Kinsella
  2019-08-15 10:23 31% ` [dpdk-dev] [PATCH v3 2/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-15 10:23 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, john.mcnamara, marko.kovacevic, hemant.agrawal

Separate versioning.rst into abi versioning and abi policy guidance, in
preparation for adding more detail to the abi policy.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 doc/guides/contributing/abi_policy.rst     | 169 +++++++++
 doc/guides/contributing/abi_versioning.rst | 427 +++++++++++++++++++++
 doc/guides/contributing/index.rst          |   3 +-
 doc/guides/contributing/versioning.rst     | 591 -----------------------------
 4 files changed, 598 insertions(+), 592 deletions(-)
 create mode 100644 doc/guides/contributing/abi_policy.rst
 create mode 100644 doc/guides/contributing/abi_versioning.rst
 delete mode 100644 doc/guides/contributing/versioning.rst

diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
new file mode 100644
index 0000000..55bacb4
--- /dev/null
+++ b/doc/guides/contributing/abi_policy.rst
@@ -0,0 +1,169 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
+.. abi_api_policy:
+
+DPDK ABI/API policy
+===================
+
+Description
+-----------
+
+This document details some methods for handling ABI management in the DPDK.
+
+General Guidelines
+------------------
+
+#. Whenever possible, ABI should be preserved
+#. ABI/API may be changed with a deprecation process
+#. The modification of symbols can generally be managed with versioning
+#. Libraries or APIs marked in ``experimental`` state may change without constraint
+#. New APIs will be marked as ``experimental`` for at least one release to allow
+   any issues found by users of the new API to be fixed quickly
+#. The addition of symbols is generally not problematic
+#. The removal of symbols generally is an ABI break and requires bumping of the
+   LIBABIVER macro
+#. Updates to the minimum hardware requirements, which drop support for hardware which
+   was previously supported, should be treated as an ABI change.
+
+What is an ABI
+~~~~~~~~~~~~~~
+
+An ABI (Application Binary Interface) is the set of runtime interfaces exposed
+by a library. It is similar to an API (Application Programming Interface) but
+is the result of compilation.  It is also effectively cloned when applications
+link to dynamic libraries.  That is to say when an application is compiled to
+link against dynamic libraries, it is assumed that the ABI remains constant
+between the time the application is compiled/linked, and the time that it runs.
+Therefore, in the case of dynamic linking, it is critical that an ABI is
+preserved, or (when modified), done in such a way that the application is unable
+to behave improperly or in an unexpected fashion.
+
+
+ABI/API Deprecation
+-------------------
+
+The DPDK ABI policy
+~~~~~~~~~~~~~~~~~~~
+
+ABI versions are set at the time of major release labeling, and the ABI may
+change multiple times, without warning, between the last release label and the
+HEAD label of the git tree.
+
+ABI versions, once released, are available until such time as their
+deprecation has been noted in the Release Notes for at least one major release
+cycle. For example consider the case where the ABI for DPDK 2.0 has been
+shipped and then a decision is made to modify it during the development of
+DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
+release and the modification will be made available in the DPDK 2.2 release.
+
+ABI versions may be deprecated in whole or in part as needed by a given
+update.
+
+Some ABI changes may be too significant to reasonably maintain multiple
+versions. In those cases ABI's may be updated without backward compatibility
+being provided. The requirements for doing so are:
+
+#. At least 3 acknowledgments of the need to do so must be made on the
+   dpdk.org mailing list.
+
+   - The acknowledgment of the maintainer of the component is mandatory, or if
+     no maintainer is available for the component, the tree/sub-tree maintainer
+     for that component must acknowledge the ABI change instead.
+
+   - It is also recommended that acknowledgments from different "areas of
+     interest" be sought for each deprecation, for example: from NIC vendors,
+     CPU vendors, end-users, etc.
+
+#. The changes (including an alternative map file) can be included with
+   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
+   to provide more details about oncoming changes.
+   ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
+   More preferred way to provide this information is sending the feature
+   as a separate patch and reference it in deprecation notice.
+
+#. A full deprecation cycle, as explained above, must be made to offer
+   downstream consumers sufficient warning of the change.
+
+Note that the above process for ABI deprecation should not be undertaken
+lightly. ABI stability is extremely important for downstream consumers of the
+DPDK, especially when distributed in shared object form. Every effort should
+be made to preserve the ABI whenever possible. The ABI should only be changed
+for significant reasons, such as performance enhancements. ABI breakage due to
+changes such as reorganizing public structure fields for aesthetic or
+readability purposes should be avoided.
+
+.. note::
+
+   Updates to the minimum hardware requirements, which drop support for hardware
+   which was previously supported, should be treated as an ABI change, and
+   follow the relevant deprecation policy procedures as above: 3 acks and
+   announcement at least one release in advance.
+
+Examples of Deprecation Notices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+  to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+  in version 2.0. Backwards compatibility will be maintained for this function
+  until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+  performance reasons. Existing binary applications will have backwards
+  compatibility in release 2.0, while newly built binaries will need to
+  reference the new structure variant ``struct rte_foo2``. Compatibility will
+  be removed in release 2.2, and all applications will require updating and
+  rebuilding to the new structure at that time, which will be renamed to the
+  original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+  upcoming release 2.0 will not contain these changes, but release 2.1 will,
+  and no backwards compatibility is planned due to the extensive nature of
+  these changes. Binaries using this library built prior to version 2.1 will
+  require updating and recompilation.
+
+New API replacing previous one
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If a new API proposed functionally replaces an existing one, when the new API
+becomes non-experimental then the old one is marked with ``__rte_deprecated``.
+Deprecated APIs are removed completely just after the next LTS.
+
+Reminder that old API should follow deprecation process to be removed.
+
+
+Experimental APIs
+-----------------
+
+APIs marked as ``experimental`` are not considered part of the ABI and may
+change without warning at any time.  Since changes to APIs are most likely
+immediately after their introduction, as users begin to take advantage of
+those new APIs and start finding issues with them, new DPDK APIs will be
+automatically marked as ``experimental`` to allow for a period of stabilization
+before they become part of a tracked ABI.
+
+Note that marking an API as experimental is a multi step process.
+To mark an API as experimental, the symbols which are desired to be exported
+must be placed in an EXPERIMENTAL version block in the corresponding libraries'
+version map script.
+Secondly, the corresponding prototypes of those exported functions (in the
+development header files), must be marked with the ``__rte_experimental`` tag
+(see ``rte_compat.h``).
+The DPDK build makefiles perform a check to ensure that the map file and the
+C code reflect the same list of symbols.
+This check can be circumvented by defining ``ALLOW_EXPERIMENTAL_API``
+during compilation in the corresponding library Makefile.
+
+In addition to tagging the code with ``__rte_experimental``,
+the doxygen markup must also contain the EXPERIMENTAL string,
+and the MAINTAINERS file should note the EXPERIMENTAL libraries.
+
+For removing the experimental tag associated with an API, deprecation notice
+is not required. Though, an API should remain in experimental state for at least
+one release. Thereafter, normal process of posting patch for review to mailing
+list can be followed.
diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
new file mode 100644
index 0000000..53e6ac0
--- /dev/null
+++ b/doc/guides/contributing/abi_versioning.rst
@@ -0,0 +1,427 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
+.. library_versioning:
+
+Library versioning
+------------------
+
+Downstreams might want to provide different DPDK releases at the same time to
+support multiple consumers of DPDK linked against older and newer sonames.
+
+Also due to the interdependencies that DPDK libraries can have applications
+might end up with an executable space in which multiple versions of a library
+are mapped by ld.so.
+
+Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
+depending on LibA.
+
+.. note::
+
+    Application
+    \-> LibA.old
+    \-> LibB.new -> LibA.new
+
+That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
+If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
+library - versions defined in the libraries ``LIBABIVER``.
+An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
+``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
+
+
+ABI versioning
+--------------
+
+Versioning Macros
+~~~~~~~~~~~~~~~~~
+
+When a symbol is exported from a library to provide an API, it also provides a
+calling convention (ABI) that is embodied in its name, return type and
+arguments. Occasionally that function may need to change to accommodate new
+functionality or behavior. When that occurs, it is desirable to allow for
+backward compatibility for a time with older binaries that are dynamically
+linked to the DPDK.
+
+To support backward compatibility the ``rte_compat.h``
+header file provides macros to use when updating exported functions. These
+macros are used in conjunction with the ``rte_<library>_version.map`` file for
+a given library to allow multiple versions of a symbol to exist in a shared
+library so that older binaries need not be immediately recompiled.
+
+The macros exported are:
+
+* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
+  versioned symbol ``b@DPDK_n`` to the internal function ``b_e``.
+
+* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
+  the linker to bind references to symbol ``b`` to the internal symbol
+  ``b_e``.
+
+* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
+  fully qualified function ``p``, so that if a symbol becomes versioned, it
+  can still be mapped back to the public symbol name.
+
+Examples of ABI Macro use
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Updating a public API
+_____________________
+
+Assume we have a function as follows
+
+.. code-block:: c
+
+ /*
+  * Create an acl context object for apps to
+  * manipulate
+  */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param)
+ {
+        ...
+ }
+
+
+Assume that struct rte_acl_ctx is a private structure, and that a developer
+wishes to enhance the acl api so that a debugging flag can be enabled on a
+per-context basis.  This requires an addition to the structure (which, being
+private, is safe), but it also requires modifying the code as follows
+
+.. code-block:: c
+
+ /*
+  * Create an acl context object for apps to
+  * manipulate
+  */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param, int debug)
+ {
+        ...
+ }
+
+
+Note also that, being a public function, the header file prototype must also be
+changed, as must all the call sites, to reflect the new ABI footprint.  We will
+maintain previous ABI versions that are accessible only to previously compiled
+binaries
+
+The addition of a parameter to the function is ABI breaking as the function is
+public, and existing application may use it in its current form.  However, the
+compatibility macros in DPDK allow a developer to use symbol versioning so that
+multiple functions can be mapped to the same public symbol based on when an
+application was linked to it.  To see how this is done, we start with the
+requisite libraries version map file.  Initially the version map file for the
+acl library looks like this
+
+.. code-block:: none
+
+   DPDK_2.0 {
+        global:
+
+        rte_acl_add_rules;
+        rte_acl_build;
+        rte_acl_classify;
+        rte_acl_classify_alg;
+        rte_acl_classify_scalar;
+        rte_acl_create;
+        rte_acl_dump;
+        rte_acl_find_existing;
+        rte_acl_free;
+        rte_acl_ipv4vlan_add_rules;
+        rte_acl_ipv4vlan_build;
+        rte_acl_list_dump;
+        rte_acl_reset;
+        rte_acl_reset_rules;
+        rte_acl_set_ctx_classify;
+
+        local: *;
+   };
+
+This file needs to be modified as follows
+
+.. code-block:: none
+
+   DPDK_2.0 {
+        global:
+
+        rte_acl_add_rules;
+        rte_acl_build;
+        rte_acl_classify;
+        rte_acl_classify_alg;
+        rte_acl_classify_scalar;
+        rte_acl_create;
+        rte_acl_dump;
+        rte_acl_find_existing;
+        rte_acl_free;
+        rte_acl_ipv4vlan_add_rules;
+        rte_acl_ipv4vlan_build;
+        rte_acl_list_dump;
+        rte_acl_reset;
+        rte_acl_reset_rules;
+        rte_acl_set_ctx_classify;
+
+        local: *;
+   };
+
+   DPDK_2.1 {
+        global:
+        rte_acl_create;
+
+   } DPDK_2.0;
+
+The addition of the new block tells the linker that a new version node is
+available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
+symbols from the DPDK_2.0 node.  This list is directly translated into a list of
+exported symbols when DPDK is compiled as a shared library
+
+Next, we need to specify in the code which function map to the rte_acl_create
+symbol at which versions.  First, at the site of the initial symbol definition,
+we need to update the function so that it is uniquely named, and not in conflict
+with the public symbol name
+
+.. code-block:: c
+
+  struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param)
+ +rte_acl_create_v20(const struct rte_acl_param *param)
+ {
+        size_t sz;
+        struct rte_acl_ctx *ctx;
+        ...
+
+Note that the base name of the symbol was kept intact, as this is conducive to
+the macros used for versioning symbols.  That is our next step, mapping this new
+symbol name to the initial symbol name at version node 2.0.  Immediately after
+the function, we add this line of code
+
+.. code-block:: c
+
+   VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+Remembering to also add the rte_compat.h header to the requisite c file where
+these changes are being made.  The above macro instructs the linker to create a
+new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
+builds, but now points to the above newly named function.  We have now mapped
+the original rte_acl_create symbol to the original function (but with a new
+name)
+
+Next, we need to create the 2.1 version of the symbol.  We create a new function
+name, with a different suffix, and  implement it appropriately
+
+.. code-block:: c
+
+   struct rte_acl_ctx *
+   rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+   {
+        struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
+
+        ctx->debug = debug;
+
+        return ctx;
+   }
+
+This code serves as our new API call.  Its the same as our old call, but adds
+the new parameter in place.  Next we need to map this function to the symbol
+``rte_acl_create@DPDK_2.1``.  To do this, we modify the public prototype of the call
+in the header file, adding the macro there to inform all including applications,
+that on re-link, the default rte_acl_create symbol should point to this
+function.  Note that we could do this by simply naming the function above
+rte_acl_create, and the linker would chose the most recent version tag to apply
+in the version script, but we can also do this in the header file
+
+.. code-block:: c
+
+   struct rte_acl_ctx *
+   -rte_acl_create(const struct rte_acl_param *param);
+   +rte_acl_create(const struct rte_acl_param *param, int debug);
+   +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
+header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
+version node to it.  This method is more explicit and flexible than just
+re-implementing the exact symbol name, and allows for other features (such as
+linking to the old symbol version by default, when the new ABI is to be opt-in
+for a period.
+
+One last thing we need to do.  Note that we've taken what was a public symbol,
+and duplicated it into two uniquely and differently named symbols.  We've then
+mapped each of those back to the public symbol ``rte_acl_create`` with different
+version tags.  This only applies to dynamic linking, as static linking has no
+notion of versioning.  That leaves this code in a position of no longer having a
+symbol simply named ``rte_acl_create`` and a static build will fail on that
+missing symbol.
+
+To correct this, we can simply map a function of our choosing back to the public
+symbol in the static build with the ``MAP_STATIC_SYMBOL`` macro.  Generally the
+assumption is that the most recent version of the symbol is the one you want to
+map.  So, back in the C file where, immediately after ``rte_acl_create_v21`` is
+defined, we add this
+
+.. code-block:: c
+
+   struct rte_acl_ctx *
+   rte_acl_create_v21(const struct rte_acl_param *param, int debug)
+   {
+        ...
+   }
+   MAP_STATIC_SYMBOL(struct rte_acl_ctx *rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v21);
+
+That tells the compiler that, when building a static library, any calls to the
+symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
+
+That's it, on the next shared library rebuild, there will be two versions of
+rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
+and a new DPDK_2.1 version, used by future built applications.
+
+
+Deprecating part of a public API
+________________________________
+
+Lets assume that you've done the above update, and after a few releases have
+passed you decide you would like to retire the old version of the function.
+After having gone through the ABI deprecation announcement process, removal is
+easy.  Start by removing the symbol from the requisite version map file:
+
+.. code-block:: none
+
+   DPDK_2.0 {
+        global:
+
+        rte_acl_add_rules;
+        rte_acl_build;
+        rte_acl_classify;
+        rte_acl_classify_alg;
+        rte_acl_classify_scalar;
+        rte_acl_dump;
+ -      rte_acl_create
+        rte_acl_find_existing;
+        rte_acl_free;
+        rte_acl_ipv4vlan_add_rules;
+        rte_acl_ipv4vlan_build;
+        rte_acl_list_dump;
+        rte_acl_reset;
+        rte_acl_reset_rules;
+        rte_acl_set_ctx_classify;
+
+        local: *;
+   };
+
+   DPDK_2.1 {
+        global:
+        rte_acl_create;
+   } DPDK_2.0;
+
+
+Next remove the corresponding versioned export.
+
+.. code-block:: c
+
+ -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+
+Note that the internal function definition could also be removed, but its used
+in our example by the newer version _v21, so we leave it in place.  This is a
+coding style choice.
+
+Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
+indicate to applications doing dynamic linking that this is a later, and
+possibly incompatible library version:
+
+.. code-block:: c
+
+   -LIBABIVER := 1
+   +LIBABIVER := 2
+
+Deprecating an entire ABI version
+_________________________________
+
+While removing a symbol from and ABI may be useful, it is often more practical
+to remove an entire version node at once.  If a version node completely
+specifies an API, then removing part of it, typically makes it incomplete.  In
+those cases it is better to remove the entire node
+
+To do this, start by modifying the version map file, such that all symbols from
+the node to be removed are merged into the next node in the map
+
+In the case of our map above, it would transform to look as follows
+
+.. code-block:: none
+
+   DPDK_2.1 {
+        global:
+
+        rte_acl_add_rules;
+        rte_acl_build;
+        rte_acl_classify;
+        rte_acl_classify_alg;
+        rte_acl_classify_scalar;
+        rte_acl_dump;
+        rte_acl_create
+        rte_acl_find_existing;
+        rte_acl_free;
+        rte_acl_ipv4vlan_add_rules;
+        rte_acl_ipv4vlan_build;
+        rte_acl_list_dump;
+        rte_acl_reset;
+        rte_acl_reset_rules;
+        rte_acl_set_ctx_classify;
+
+        local: *;
+ };
+
+Then any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be
+updated to point to the new version node in any header files for all affected
+symbols.
+
+.. code-block:: c
+
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+Lastly, any VERSION_SYMBOL macros that point to the old version node should be
+removed, taking care to keep, where need old code in place to support newer
+versions of the symbol.
+
+
+Running the ABI Validator
+-------------------------
+
+The ``devtools`` directory in the DPDK source tree contains a utility program,
+``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
+Compliance Checker
+<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
+
+This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
+utilities which can be installed via a package manager. For example::
+
+   sudo yum install abi-compliance-checker
+   sudo yum install abi-dumper
+
+The syntax of the ``validate-abi.sh`` utility is::
+
+   ./devtools/validate-abi.sh <REV1> <REV2>
+
+Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
+https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
+on the local repo.
+
+For example::
+
+   # Check between the previous and latest commit:
+   ./devtools/validate-abi.sh HEAD~1 HEAD
+
+   # Check on a specific compilation target:
+   ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
+
+   # Check between two tags:
+   ./devtools/validate-abi.sh v2.0.0 v2.1.0
+
+   # Check between git master and local topic-branch "vhost-hacking":
+   ./devtools/validate-abi.sh master vhost-hacking
+
+After the validation script completes (it can take a while since it need to
+compile both tags) it will create compatibility reports in the
+``./abi-check/compat_report`` directory. Listed incompatibilities can be found
+as follows::
+
+  grep -lr Incompatible abi-check/compat_reports/
diff --git a/doc/guides/contributing/index.rst b/doc/guides/contributing/index.rst
index e2608d3..2fefd91 100644
--- a/doc/guides/contributing/index.rst
+++ b/doc/guides/contributing/index.rst
@@ -10,7 +10,8 @@ Contributor's Guidelines
 
     coding_style
     design
-    versioning
+    abi_policy
+    abi_versioning
     documentation
     patches
     vulnerability
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
deleted file mode 100644
index 3ab2c43..0000000
--- a/doc/guides/contributing/versioning.rst
+++ /dev/null
@@ -1,591 +0,0 @@
-..  SPDX-License-Identifier: BSD-3-Clause
-    Copyright 2018 The DPDK contributors
-
-DPDK ABI/API policy
-===================
-
-Description
------------
-
-This document details some methods for handling ABI management in the DPDK.
-
-General Guidelines
-------------------
-
-#. Whenever possible, ABI should be preserved
-#. ABI/API may be changed with a deprecation process
-#. The modification of symbols can generally be managed with versioning
-#. Libraries or APIs marked in ``experimental`` state may change without constraint
-#. New APIs will be marked as ``experimental`` for at least one release to allow
-   any issues found by users of the new API to be fixed quickly
-#. The addition of symbols is generally not problematic
-#. The removal of symbols generally is an ABI break and requires bumping of the
-   LIBABIVER macro
-#. Updates to the minimum hardware requirements, which drop support for hardware which
-   was previously supported, should be treated as an ABI change.
-
-What is an ABI
-~~~~~~~~~~~~~~
-
-An ABI (Application Binary Interface) is the set of runtime interfaces exposed
-by a library. It is similar to an API (Application Programming Interface) but
-is the result of compilation.  It is also effectively cloned when applications
-link to dynamic libraries.  That is to say when an application is compiled to
-link against dynamic libraries, it is assumed that the ABI remains constant
-between the time the application is compiled/linked, and the time that it runs.
-Therefore, in the case of dynamic linking, it is critical that an ABI is
-preserved, or (when modified), done in such a way that the application is unable
-to behave improperly or in an unexpected fashion.
-
-
-ABI/API Deprecation
--------------------
-
-The DPDK ABI policy
-~~~~~~~~~~~~~~~~~~~
-
-ABI versions are set at the time of major release labeling, and the ABI may
-change multiple times, without warning, between the last release label and the
-HEAD label of the git tree.
-
-ABI versions, once released, are available until such time as their
-deprecation has been noted in the Release Notes for at least one major release
-cycle. For example consider the case where the ABI for DPDK 2.0 has been
-shipped and then a decision is made to modify it during the development of
-DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
-release and the modification will be made available in the DPDK 2.2 release.
-
-ABI versions may be deprecated in whole or in part as needed by a given
-update.
-
-Some ABI changes may be too significant to reasonably maintain multiple
-versions. In those cases ABI's may be updated without backward compatibility
-being provided. The requirements for doing so are:
-
-#. At least 3 acknowledgments of the need to do so must be made on the
-   dpdk.org mailing list.
-
-   - The acknowledgment of the maintainer of the component is mandatory, or if
-     no maintainer is available for the component, the tree/sub-tree maintainer
-     for that component must acknowledge the ABI change instead.
-
-   - It is also recommended that acknowledgments from different "areas of
-     interest" be sought for each deprecation, for example: from NIC vendors,
-     CPU vendors, end-users, etc.
-
-#. The changes (including an alternative map file) can be included with
-   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
-   to provide more details about oncoming changes.
-   ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
-   More preferred way to provide this information is sending the feature
-   as a separate patch and reference it in deprecation notice.
-
-#. A full deprecation cycle, as explained above, must be made to offer
-   downstream consumers sufficient warning of the change.
-
-Note that the above process for ABI deprecation should not be undertaken
-lightly. ABI stability is extremely important for downstream consumers of the
-DPDK, especially when distributed in shared object form. Every effort should
-be made to preserve the ABI whenever possible. The ABI should only be changed
-for significant reasons, such as performance enhancements. ABI breakage due to
-changes such as reorganizing public structure fields for aesthetic or
-readability purposes should be avoided.
-
-.. note::
-
-   Updates to the minimum hardware requirements, which drop support for hardware
-   which was previously supported, should be treated as an ABI change, and
-   follow the relevant deprecation policy procedures as above: 3 acks and
-   announcement at least one release in advance.
-
-Examples of Deprecation Notices
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following are some examples of ABI deprecation notices which would be
-added to the Release Notes:
-
-* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
-  to be replaced with the inline function ``rte_foo()``.
-
-* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
-  in version 2.0. Backwards compatibility will be maintained for this function
-  until the release of version 2.1
-
-* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
-  performance reasons. Existing binary applications will have backwards
-  compatibility in release 2.0, while newly built binaries will need to
-  reference the new structure variant ``struct rte_foo2``. Compatibility will
-  be removed in release 2.2, and all applications will require updating and
-  rebuilding to the new structure at that time, which will be renamed to the
-  original ``struct rte_foo``.
-
-* Significant ABI changes are planned for the ``librte_dostuff`` library. The
-  upcoming release 2.0 will not contain these changes, but release 2.1 will,
-  and no backwards compatibility is planned due to the extensive nature of
-  these changes. Binaries using this library built prior to version 2.1 will
-  require updating and recompilation.
-
-New API replacing previous one
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If a new API proposed functionally replaces an existing one, when the new API
-becomes non-experimental then the old one is marked with ``__rte_deprecated``.
-Deprecated APIs are removed completely just after the next LTS.
-
-Reminder that old API should follow deprecation process to be removed.
-
-
-Experimental APIs
------------------
-
-APIs marked as ``experimental`` are not considered part of the ABI and may
-change without warning at any time.  Since changes to APIs are most likely
-immediately after their introduction, as users begin to take advantage of
-those new APIs and start finding issues with them, new DPDK APIs will be
-automatically marked as ``experimental`` to allow for a period of stabilization
-before they become part of a tracked ABI.
-
-Note that marking an API as experimental is a multi step process.
-To mark an API as experimental, the symbols which are desired to be exported
-must be placed in an EXPERIMENTAL version block in the corresponding libraries'
-version map script.
-Secondly, the corresponding prototypes of those exported functions (in the
-development header files), must be marked with the ``__rte_experimental`` tag
-(see ``rte_compat.h``).
-The DPDK build makefiles perform a check to ensure that the map file and the
-C code reflect the same list of symbols.
-This check can be circumvented by defining ``ALLOW_EXPERIMENTAL_API``
-during compilation in the corresponding library Makefile.
-
-In addition to tagging the code with ``__rte_experimental``,
-the doxygen markup must also contain the EXPERIMENTAL string,
-and the MAINTAINERS file should note the EXPERIMENTAL libraries.
-
-For removing the experimental tag associated with an API, deprecation notice
-is not required. Though, an API should remain in experimental state for at least
-one release. Thereafter, normal process of posting patch for review to mailing
-list can be followed.
-
-
-Library versioning
-------------------
-
-Downstreams might want to provide different DPDK releases at the same time to
-support multiple consumers of DPDK linked against older and newer sonames.
-
-Also due to the interdependencies that DPDK libraries can have applications
-might end up with an executable space in which multiple versions of a library
-are mapped by ld.so.
-
-Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
-depending on LibA.
-
-.. note::
-
-    Application
-    \-> LibA.old
-    \-> LibB.new -> LibA.new
-
-That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
-If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
-library - versions defined in the libraries ``LIBABIVER``.
-An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
-``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
-
-
-ABI versioning
---------------
-
-Versioning Macros
-~~~~~~~~~~~~~~~~~
-
-When a symbol is exported from a library to provide an API, it also provides a
-calling convention (ABI) that is embodied in its name, return type and
-arguments. Occasionally that function may need to change to accommodate new
-functionality or behavior. When that occurs, it is desirable to allow for
-backward compatibility for a time with older binaries that are dynamically
-linked to the DPDK.
-
-To support backward compatibility the ``rte_compat.h``
-header file provides macros to use when updating exported functions. These
-macros are used in conjunction with the ``rte_<library>_version.map`` file for
-a given library to allow multiple versions of a symbol to exist in a shared
-library so that older binaries need not be immediately recompiled.
-
-The macros exported are:
-
-* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
-  versioned symbol ``b@DPDK_n`` to the internal function ``b_e``.
-
-* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
-  the linker to bind references to symbol ``b`` to the internal symbol
-  ``b_e``.
-
-* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
-  fully qualified function ``p``, so that if a symbol becomes versioned, it
-  can still be mapped back to the public symbol name.
-
-Examples of ABI Macro use
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Updating a public API
-_____________________
-
-Assume we have a function as follows
-
-.. code-block:: c
-
- /*
-  * Create an acl context object for apps to
-  * manipulate
-  */
- struct rte_acl_ctx *
- rte_acl_create(const struct rte_acl_param *param)
- {
-        ...
- }
-
-
-Assume that struct rte_acl_ctx is a private structure, and that a developer
-wishes to enhance the acl api so that a debugging flag can be enabled on a
-per-context basis.  This requires an addition to the structure (which, being
-private, is safe), but it also requires modifying the code as follows
-
-.. code-block:: c
-
- /*
-  * Create an acl context object for apps to
-  * manipulate
-  */
- struct rte_acl_ctx *
- rte_acl_create(const struct rte_acl_param *param, int debug)
- {
-        ...
- }
-
-
-Note also that, being a public function, the header file prototype must also be
-changed, as must all the call sites, to reflect the new ABI footprint.  We will
-maintain previous ABI versions that are accessible only to previously compiled
-binaries
-
-The addition of a parameter to the function is ABI breaking as the function is
-public, and existing application may use it in its current form.  However, the
-compatibility macros in DPDK allow a developer to use symbol versioning so that
-multiple functions can be mapped to the same public symbol based on when an
-application was linked to it.  To see how this is done, we start with the
-requisite libraries version map file.  Initially the version map file for the
-acl library looks like this
-
-.. code-block:: none
-
-   DPDK_2.0 {
-        global:
-
-        rte_acl_add_rules;
-        rte_acl_build;
-        rte_acl_classify;
-        rte_acl_classify_alg;
-        rte_acl_classify_scalar;
-        rte_acl_create;
-        rte_acl_dump;
-        rte_acl_find_existing;
-        rte_acl_free;
-        rte_acl_ipv4vlan_add_rules;
-        rte_acl_ipv4vlan_build;
-        rte_acl_list_dump;
-        rte_acl_reset;
-        rte_acl_reset_rules;
-        rte_acl_set_ctx_classify;
-
-        local: *;
-   };
-
-This file needs to be modified as follows
-
-.. code-block:: none
-
-   DPDK_2.0 {
-        global:
-
-        rte_acl_add_rules;
-        rte_acl_build;
-        rte_acl_classify;
-        rte_acl_classify_alg;
-        rte_acl_classify_scalar;
-        rte_acl_create;
-        rte_acl_dump;
-        rte_acl_find_existing;
-        rte_acl_free;
-        rte_acl_ipv4vlan_add_rules;
-        rte_acl_ipv4vlan_build;
-        rte_acl_list_dump;
-        rte_acl_reset;
-        rte_acl_reset_rules;
-        rte_acl_set_ctx_classify;
-
-        local: *;
-   };
-
-   DPDK_2.1 {
-        global:
-        rte_acl_create;
-
-   } DPDK_2.0;
-
-The addition of the new block tells the linker that a new version node is
-available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
-symbols from the DPDK_2.0 node.  This list is directly translated into a list of
-exported symbols when DPDK is compiled as a shared library
-
-Next, we need to specify in the code which function map to the rte_acl_create
-symbol at which versions.  First, at the site of the initial symbol definition,
-we need to update the function so that it is uniquely named, and not in conflict
-with the public symbol name
-
-.. code-block:: c
-
-  struct rte_acl_ctx *
- -rte_acl_create(const struct rte_acl_param *param)
- +rte_acl_create_v20(const struct rte_acl_param *param)
- {
-        size_t sz;
-        struct rte_acl_ctx *ctx;
-        ...
-
-Note that the base name of the symbol was kept intact, as this is conducive to
-the macros used for versioning symbols.  That is our next step, mapping this new
-symbol name to the initial symbol name at version node 2.0.  Immediately after
-the function, we add this line of code
-
-.. code-block:: c
-
-   VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
-
-Remembering to also add the rte_compat.h header to the requisite c file where
-these changes are being made.  The above macro instructs the linker to create a
-new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
-builds, but now points to the above newly named function.  We have now mapped
-the original rte_acl_create symbol to the original function (but with a new
-name)
-
-Next, we need to create the 2.1 version of the symbol.  We create a new function
-name, with a different suffix, and  implement it appropriately
-
-.. code-block:: c
-
-   struct rte_acl_ctx *
-   rte_acl_create_v21(const struct rte_acl_param *param, int debug);
-   {
-        struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
-
-        ctx->debug = debug;
-
-        return ctx;
-   }
-
-This code serves as our new API call.  Its the same as our old call, but adds
-the new parameter in place.  Next we need to map this function to the symbol
-``rte_acl_create@DPDK_2.1``.  To do this, we modify the public prototype of the call
-in the header file, adding the macro there to inform all including applications,
-that on re-link, the default rte_acl_create symbol should point to this
-function.  Note that we could do this by simply naming the function above
-rte_acl_create, and the linker would chose the most recent version tag to apply
-in the version script, but we can also do this in the header file
-
-.. code-block:: c
-
-   struct rte_acl_ctx *
-   -rte_acl_create(const struct rte_acl_param *param);
-   +rte_acl_create(const struct rte_acl_param *param, int debug);
-   +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
-
-The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
-header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
-version node to it.  This method is more explicit and flexible than just
-re-implementing the exact symbol name, and allows for other features (such as
-linking to the old symbol version by default, when the new ABI is to be opt-in
-for a period.
-
-One last thing we need to do.  Note that we've taken what was a public symbol,
-and duplicated it into two uniquely and differently named symbols.  We've then
-mapped each of those back to the public symbol ``rte_acl_create`` with different
-version tags.  This only applies to dynamic linking, as static linking has no
-notion of versioning.  That leaves this code in a position of no longer having a
-symbol simply named ``rte_acl_create`` and a static build will fail on that
-missing symbol.
-
-To correct this, we can simply map a function of our choosing back to the public
-symbol in the static build with the ``MAP_STATIC_SYMBOL`` macro.  Generally the
-assumption is that the most recent version of the symbol is the one you want to
-map.  So, back in the C file where, immediately after ``rte_acl_create_v21`` is
-defined, we add this
-
-.. code-block:: c
-
-   struct rte_acl_ctx *
-   rte_acl_create_v21(const struct rte_acl_param *param, int debug)
-   {
-        ...
-   }
-   MAP_STATIC_SYMBOL(struct rte_acl_ctx *rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v21);
-
-That tells the compiler that, when building a static library, any calls to the
-symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
-
-That's it, on the next shared library rebuild, there will be two versions of
-rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
-and a new DPDK_2.1 version, used by future built applications.
-
-
-Deprecating part of a public API
-________________________________
-
-Lets assume that you've done the above update, and after a few releases have
-passed you decide you would like to retire the old version of the function.
-After having gone through the ABI deprecation announcement process, removal is
-easy.  Start by removing the symbol from the requisite version map file:
-
-.. code-block:: none
-
-   DPDK_2.0 {
-        global:
-
-        rte_acl_add_rules;
-        rte_acl_build;
-        rte_acl_classify;
-        rte_acl_classify_alg;
-        rte_acl_classify_scalar;
-        rte_acl_dump;
- -      rte_acl_create
-        rte_acl_find_existing;
-        rte_acl_free;
-        rte_acl_ipv4vlan_add_rules;
-        rte_acl_ipv4vlan_build;
-        rte_acl_list_dump;
-        rte_acl_reset;
-        rte_acl_reset_rules;
-        rte_acl_set_ctx_classify;
-
-        local: *;
-   };
-
-   DPDK_2.1 {
-        global:
-        rte_acl_create;
-   } DPDK_2.0;
-
-
-Next remove the corresponding versioned export.
-
-.. code-block:: c
-
- -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
-
-
-Note that the internal function definition could also be removed, but its used
-in our example by the newer version _v21, so we leave it in place.  This is a
-coding style choice.
-
-Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
-indicate to applications doing dynamic linking that this is a later, and
-possibly incompatible library version:
-
-.. code-block:: c
-
-   -LIBABIVER := 1
-   +LIBABIVER := 2
-
-Deprecating an entire ABI version
-_________________________________
-
-While removing a symbol from and ABI may be useful, it is often more practical
-to remove an entire version node at once.  If a version node completely
-specifies an API, then removing part of it, typically makes it incomplete.  In
-those cases it is better to remove the entire node
-
-To do this, start by modifying the version map file, such that all symbols from
-the node to be removed are merged into the next node in the map
-
-In the case of our map above, it would transform to look as follows
-
-.. code-block:: none
-
-   DPDK_2.1 {
-        global:
-
-        rte_acl_add_rules;
-        rte_acl_build;
-        rte_acl_classify;
-        rte_acl_classify_alg;
-        rte_acl_classify_scalar;
-        rte_acl_dump;
-        rte_acl_create
-        rte_acl_find_existing;
-        rte_acl_free;
-        rte_acl_ipv4vlan_add_rules;
-        rte_acl_ipv4vlan_build;
-        rte_acl_list_dump;
-        rte_acl_reset;
-        rte_acl_reset_rules;
-        rte_acl_set_ctx_classify;
-
-        local: *;
- };
-
-Then any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be
-updated to point to the new version node in any header files for all affected
-symbols.
-
-.. code-block:: c
-
- -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
- +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
-
-Lastly, any VERSION_SYMBOL macros that point to the old version node should be
-removed, taking care to keep, where need old code in place to support newer
-versions of the symbol.
-
-
-Running the ABI Validator
--------------------------
-
-The ``devtools`` directory in the DPDK source tree contains a utility program,
-``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
-Compliance Checker
-<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
-
-This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
-utilities which can be installed via a package manager. For example::
-
-   sudo yum install abi-compliance-checker
-   sudo yum install abi-dumper
-
-The syntax of the ``validate-abi.sh`` utility is::
-
-   ./devtools/validate-abi.sh <REV1> <REV2>
-
-Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
-https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
-on the local repo.
-
-For example::
-
-   # Check between the previous and latest commit:
-   ./devtools/validate-abi.sh HEAD~1 HEAD
-
-   # Check on a specific compilation target:
-   ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
-
-   # Check between two tags:
-   ./devtools/validate-abi.sh v2.0.0 v2.1.0
-
-   # Check between git master and local topic-branch "vhost-hacking":
-   ./devtools/validate-abi.sh master vhost-hacking
-
-After the validation script completes (it can take a while since it need to
-compile both tags) it will create compatibility reports in the
-``./abi-check/compat_report`` directory. Listed incompatibilities can be found
-as follows::
-
-  grep -lr Incompatible abi-check/compat_reports/
-- 
2.7.4


^ permalink raw reply	[relevance 13%]

* [dpdk-dev] [PATCH v3 3/4] doc: updates to versioning guide for abi versions
  2019-08-15 10:23 11% [dpdk-dev] [PATCH v3 0/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
  2019-08-15 10:23 13% ` [dpdk-dev] [PATCH v3 1/4] doc: separate versioning.rst into version and policy Ray Kinsella
  2019-08-15 10:23 31% ` [dpdk-dev] [PATCH v3 2/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
@ 2019-08-15 10:23 30% ` Ray Kinsella
  2019-08-15 10:23 13% ` [dpdk-dev] [PATCH v3 4/4] doc: add maintainer for abi policy Ray Kinsella
  3 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-15 10:23 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, john.mcnamara, marko.kovacevic, hemant.agrawal

Updates to the ABI versioning guide, to account for the changes to the DPDK
ABI/API policy. Fixes for references to abi versioning and policy guides.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 doc/guides/contributing/abi_versioning.rst | 248 +++++++++++++++++++----------
 doc/guides/contributing/patches.rst        |   6 +-
 doc/guides/rel_notes/deprecation.rst       |   2 +-
 3 files changed, 172 insertions(+), 84 deletions(-)

diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
index 53e6ac0..76c63c8 100644
--- a/doc/guides/contributing/abi_versioning.rst
+++ b/doc/guides/contributing/abi_versioning.rst
@@ -1,44 +1,134 @@
 ..  SPDX-License-Identifier: BSD-3-Clause
     Copyright 2018 The DPDK contributors
 
-.. library_versioning:
+.. _abi_versioning:
 
-Library versioning
+ABI Versioning
+==============
+
+This document details the mechanics of ABI version management in DPDK.
+
+.. _what_is_soname:
+
+What is a library's soname?
+---------------------------
+
+System libraries usually adopt the familiar major and minor version naming
+convention, where major versions (e.g. ``librte_eal 20.x, 21.x``) are presumed
+to be ABI incompatible with each other and minor versions (e.g. ``librte_eal
+20.1, 20.2``) are presumed to be ABI compatible. A library's `soname
+<https://en.wikipedia.org/wiki/Soname>`_. is typically used to provide backward
+compatibility information about a given library, describing the lowest common
+denominator ABI supported by the library. The soname or logical name for the
+library, is typically comprised of the library's name and major version e.g.
+``librte_eal.so.20``.
+
+During an application's build process, a library's soname is noted as a runtime
+dependency of the application. This information is then used by the `dynamic
+linker <https://en.wikipedia.org/wiki/Dynamic_linker>`_ when resolving the
+applications dependencies at runtime, to load a library supporting the correct
+ABI version. The library loaded at runtime therefore, may be a minor revision
+supporting the same major ABI version (e.g. ``librte_eal.20.2``), as the library
+used to link the application (e.g ``librte_eal.20.0``).
+
+.. _major_abi_versions:
+
+Major ABI versions
 ------------------
 
-Downstreams might want to provide different DPDK releases at the same time to
-support multiple consumers of DPDK linked against older and newer sonames.
+An ABI version change to a given library, especially in core libraries such as
+``librte_mbuf``, may cause an implicit ripple effect on the ABI of it's
+consuming libraries, causing ABI breakages. There may however be no explicit
+reason to bump a dependent library's ABI version, as there may have been no
+obvious change to the dependent library's API, even though the library's ABI
+compatibility will have been broken.
+
+This interdependence of DPDK libraries, means that ABI versioning of libraries
+is more manageable at a project level, with all project libraries sharing a
+**single ABI version**. In addition, the need to maintain a stable ABI for some
+number of releases as described in the section :ref:`abi_policy`, means
+that ABI version increments need to carefully planned and managed at a project
+level.
+
+Major ABI versions are therefore declared typically aligned with an LTS release
+and is then supported some number of subsequent releases, shared across all
+libraries. This means that a single project level ABI version, reflected in all
+individual library's soname, library filenames and associated version maps
+persists over multiple releases.
+
+.. code-block:: none
+
+ $ head ./lib/librte_acl/rte_acl_version.map
+ DPDK_20 {
+        global:
+ ...
 
-Also due to the interdependencies that DPDK libraries can have applications
-might end up with an executable space in which multiple versions of a library
-are mapped by ld.so.
+ $ head ./lib/librte_eal/rte_eal_version.map
+ DPDK_20 {
+        global:
+ ...
 
-Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
-depending on LibA.
+When an ABI change is made between major ABI versions to a given library, a new
+section is added to that library's version map describing the impending new ABI
+version, as described in the section :ref:`example_abi_macro_usage`. The
+library's soname and filename however do not change, e.g. ``libacl.so.20``, as
+ABI compatibility with the last major ABI version continues to be preserved for
+that library.
 
-.. note::
+.. code-block:: none
 
-    Application
-    \-> LibA.old
-    \-> LibB.new -> LibA.new
+ $ head ./lib/librte_acl/rte_acl_version.map
+ DPDK_20 {
+        global:
+ ...
 
-That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
-If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
-library - versions defined in the libraries ``LIBABIVER``.
-An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
-``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
+ DPDK_21 {
+        global:
+
+ } DPDK_20;
+ ...
 
+ $ head ./lib/librte_eal/rte_eal_version.map
+ DPDK_20 {
+        global:
+ ...
+
+However when a new ABI version is declared, for example DPDK ``21``, old
+depreciated functions may be safely removed at this point and the entire old
+major ABI version removed, see the section :ref:`deprecating_entire_abi` on
+how this may be done.
+
+.. code-block:: none
+
+ $ head ./lib/librte_acl/rte_acl_version.map
+ DPDK_21 {
+        global:
+ ...
+
+ $ head ./lib/librte_eal/rte_eal_version.map
+ DPDK_21 {
+        global:
+ ...
+
+At the same time, the major ABI version is changed atomically across all
+libraries by incrementing the major version in individual library's soname, e.g.
+``libacl.so.21``. This is done by bumping the LIBABIVER number in the libraries
+Makefile to indicate to dynamic linking applications that this is a later, and
+possibly incompatible library version:
+
+.. code-block:: c
+
+   -LIBABIVER := 20
+   +LIBABIVER := 21
 
-ABI versioning
---------------
 
 Versioning Macros
-~~~~~~~~~~~~~~~~~
+-----------------
 
 When a symbol is exported from a library to provide an API, it also provides a
 calling convention (ABI) that is embodied in its name, return type and
 arguments. Occasionally that function may need to change to accommodate new
-functionality or behavior. When that occurs, it is desirable to allow for
+functionality or behavior. When that occurs, it is may be required to allow for
 backward compatibility for a time with older binaries that are dynamically
 linked to the DPDK.
 
@@ -61,8 +151,10 @@ The macros exported are:
   fully qualified function ``p``, so that if a symbol becomes versioned, it
   can still be mapped back to the public symbol name.
 
+.. _example_abi_macro_usage:
+
 Examples of ABI Macro use
-^^^^^^^^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Updating a public API
 _____________________
@@ -106,16 +198,16 @@ maintain previous ABI versions that are accessible only to previously compiled
 binaries
 
 The addition of a parameter to the function is ABI breaking as the function is
-public, and existing application may use it in its current form.  However, the
+public, and existing application may use it in its current form. However, the
 compatibility macros in DPDK allow a developer to use symbol versioning so that
 multiple functions can be mapped to the same public symbol based on when an
-application was linked to it.  To see how this is done, we start with the
-requisite libraries version map file.  Initially the version map file for the
-acl library looks like this
+application was linked to it. To see how this is done, we start with the
+requisite libraries version map file. Initially the version map file for the acl
+library looks like this
 
 .. code-block:: none
 
-   DPDK_2.0 {
+   DPDK_20 {
         global:
 
         rte_acl_add_rules;
@@ -141,7 +233,7 @@ This file needs to be modified as follows
 
 .. code-block:: none
 
-   DPDK_2.0 {
+   DPDK_20 {
         global:
 
         rte_acl_add_rules;
@@ -163,16 +255,16 @@ This file needs to be modified as follows
         local: *;
    };
 
-   DPDK_2.1 {
+   DPDK_21 {
         global:
         rte_acl_create;
 
-   } DPDK_2.0;
+   } DPDK_20;
 
 The addition of the new block tells the linker that a new version node is
-available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
-symbols from the DPDK_2.0 node.  This list is directly translated into a list of
-exported symbols when DPDK is compiled as a shared library
+available (DPDK_21), which contains the symbol rte_acl_create, and inherits
+the symbols from the DPDK_20 node. This list is directly translated into a
+list of exported symbols when DPDK is compiled as a shared library
 
 Next, we need to specify in the code which function map to the rte_acl_create
 symbol at which versions.  First, at the site of the initial symbol definition,
@@ -191,22 +283,22 @@ with the public symbol name
 
 Note that the base name of the symbol was kept intact, as this is conducive to
 the macros used for versioning symbols.  That is our next step, mapping this new
-symbol name to the initial symbol name at version node 2.0.  Immediately after
+symbol name to the initial symbol name at version node 20.  Immediately after
 the function, we add this line of code
 
 .. code-block:: c
 
-   VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+   VERSION_SYMBOL(rte_acl_create, _v20, 20);
 
 Remembering to also add the rte_compat.h header to the requisite c file where
-these changes are being made.  The above macro instructs the linker to create a
-new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
-builds, but now points to the above newly named function.  We have now mapped
-the original rte_acl_create symbol to the original function (but with a new
-name)
+these changes are being made. The above macro instructs the linker to create a
+new symbol ``rte_acl_create@DPDK_20``, which matches the symbol created in
+older builds, but now points to the above newly named function. We have now
+mapped the original rte_acl_create symbol to the original function (but with a
+new name)
 
-Next, we need to create the 2.1 version of the symbol.  We create a new function
-name, with a different suffix, and  implement it appropriately
+Next, we need to create the 21 version of the symbol. We create a new function
+name, with a different suffix, and implement it appropriately
 
 .. code-block:: c
 
@@ -220,12 +312,12 @@ name, with a different suffix, and  implement it appropriately
         return ctx;
    }
 
-This code serves as our new API call.  Its the same as our old call, but adds
-the new parameter in place.  Next we need to map this function to the symbol
-``rte_acl_create@DPDK_2.1``.  To do this, we modify the public prototype of the call
-in the header file, adding the macro there to inform all including applications,
-that on re-link, the default rte_acl_create symbol should point to this
-function.  Note that we could do this by simply naming the function above
+This code serves as our new API call. Its the same as our old call, but adds the
+new parameter in place. Next we need to map this function to the symbol
+``rte_acl_create@DPDK_21``. To do this, we modify the public prototype of the
+call in the header file, adding the macro there to inform all including
+applications, that on re-link, the default rte_acl_create symbol should point to
+this function. Note that we could do this by simply naming the function above
 rte_acl_create, and the linker would chose the most recent version tag to apply
 in the version script, but we can also do this in the header file
 
@@ -233,11 +325,11 @@ in the version script, but we can also do this in the header file
 
    struct rte_acl_ctx *
    -rte_acl_create(const struct rte_acl_param *param);
-   +rte_acl_create(const struct rte_acl_param *param, int debug);
-   +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+   +rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+   +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21);
 
 The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
-header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
+header, to link to the rte_acl_create_v21 function and apply the DPDK_21
 version node to it.  This method is more explicit and flexible than just
 re-implementing the exact symbol name, and allows for other features (such as
 linking to the old symbol version by default, when the new ABI is to be opt-in
@@ -257,6 +349,7 @@ assumption is that the most recent version of the symbol is the one you want to
 map.  So, back in the C file where, immediately after ``rte_acl_create_v21`` is
 defined, we add this
 
+
 .. code-block:: c
 
    struct rte_acl_ctx *
@@ -270,21 +363,22 @@ That tells the compiler that, when building a static library, any calls to the
 symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
 
 That's it, on the next shared library rebuild, there will be two versions of
-rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
-and a new DPDK_2.1 version, used by future built applications.
+rte_acl_create, an old DPDK_20 version, used by previously built applications,
+and a new DPDK_21 version, used by future built applications.
 
 
 Deprecating part of a public API
 ________________________________
 
-Lets assume that you've done the above update, and after a few releases have
-passed you decide you would like to retire the old version of the function.
-After having gone through the ABI deprecation announcement process, removal is
-easy.  Start by removing the symbol from the requisite version map file:
+Lets assume that you've done the above update, and in preparation for the next
+major ABI version you decide you would like to retire the old version of the
+function. After having gone through the ABI deprecation announcement process,
+removal is easy. Start by removing the symbol from the requisite version map
+file:
 
 .. code-block:: none
 
-   DPDK_2.0 {
+   DPDK_20 {
         global:
 
         rte_acl_add_rules;
@@ -306,48 +400,42 @@ easy.  Start by removing the symbol from the requisite version map file:
         local: *;
    };
 
-   DPDK_2.1 {
+   DPDK_21 {
         global:
         rte_acl_create;
-   } DPDK_2.0;
+   } DPDK_20;
 
 
 Next remove the corresponding versioned export.
 
 .. code-block:: c
 
- -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+ -VERSION_SYMBOL(rte_acl_create, _v20, 20);
 
 
 Note that the internal function definition could also be removed, but its used
-in our example by the newer version _v21, so we leave it in place.  This is a
-coding style choice.
-
-Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
-indicate to applications doing dynamic linking that this is a later, and
-possibly incompatible library version:
-
-.. code-block:: c
+in our example by the newer version v21, so we leave it in place and declare it
+as static. This is a coding style choice.
 
-   -LIBABIVER := 1
-   +LIBABIVER := 2
+.. _deprecating_entire_abi:
 
 Deprecating an entire ABI version
 _________________________________
 
-While removing a symbol from and ABI may be useful, it is often more practical
-to remove an entire version node at once.  If a version node completely
-specifies an API, then removing part of it, typically makes it incomplete.  In
-those cases it is better to remove the entire node
+While removing a symbol from an ABI may be useful, it is more practical to
+remove an entire version node at once, as is typically done at the declaration
+of a major ABI version. If a version node completely specifies an API, then
+removing part of it, typically makes it incomplete. In those cases it is better
+to remove the entire node.
 
 To do this, start by modifying the version map file, such that all symbols from
-the node to be removed are merged into the next node in the map
+the node to be removed are merged into the next node in the map.
 
 In the case of our map above, it would transform to look as follows
 
 .. code-block:: none
 
-   DPDK_2.1 {
+   DPDK_21 {
         global:
 
         rte_acl_add_rules;
@@ -375,8 +463,8 @@ symbols.
 
 .. code-block:: c
 
- -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
- +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 20);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21);
 
 Lastly, any VERSION_SYMBOL macros that point to the old version node should be
 removed, taking care to keep, where need old code in place to support newer
diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst
index 9e1013b..d63c9f5 100644
--- a/doc/guides/contributing/patches.rst
+++ b/doc/guides/contributing/patches.rst
@@ -156,9 +156,9 @@ Make your planned changes in the cloned ``dpdk`` repo. Here are some guidelines
 
   * For other PMDs and more info, refer to the ``MAINTAINERS`` file.
 
-* New external functions should be added to the local ``version.map`` file.
-  See the :doc:`Guidelines for ABI policy and versioning </contributing/versioning>`.
-  New external functions should also be added in alphabetical order.
+* New external functions should be added to the local ``version.map`` file. See
+  the :ref:`ABI policy <abi_policy>` and :ref:`ABI versioning <abi_versioning>`
+  guides. New external functions should also be added in alphabetical order.
 
 * Important changes will require an addition to the release notes in ``doc/guides/rel_notes/``.
   See the :ref:`Release Notes section of the Documentation Guidelines <doc_guidelines>` for details.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 0ee8533..2e163a5 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -4,7 +4,7 @@
 ABI and API Deprecation
 =======================
 
-See the :doc:`guidelines document for details of the ABI policy </contributing/versioning>`.
+See the :ref:`guidelines document for details of the ABI policy <abi_policy>`.
 API and ABI deprecation notices are to be posted here.
 
 
-- 
2.7.4


^ permalink raw reply	[relevance 30%]

* [dpdk-dev] [PATCH v3 4/4] doc: add maintainer for abi policy
  2019-08-15 10:23 11% [dpdk-dev] [PATCH v3 0/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
                   ` (2 preceding siblings ...)
  2019-08-15 10:23 30% ` [dpdk-dev] [PATCH v3 3/4] doc: updates to versioning guide for " Ray Kinsella
@ 2019-08-15 10:23 13% ` Ray Kinsella
  3 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-15 10:23 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, john.mcnamara, marko.kovacevic, hemant.agrawal

Add an entry to the maintainer file for the abi policy.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 MAINTAINERS | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4100260..a36afc1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -81,6 +81,10 @@ M: Marko Kovacevic <marko.kovacevic@intel.com>
 F: README
 F: doc/
 
+ABI Policy
+M: Ray Kinsella <mdr@ashroe.eu>
+F: doc/guides/contributing/abi_*.rst
+
 Developers and Maintainers Tools
 M: Thomas Monjalon <thomas@monjalon.net>
 F: MAINTAINERS
-- 
2.7.4


^ permalink raw reply	[relevance 13%]

* [dpdk-dev] [PATCH v3 2/4] doc: changes to abi policy introducing major abi versions
  2019-08-15 10:23 11% [dpdk-dev] [PATCH v3 0/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
  2019-08-15 10:23 13% ` [dpdk-dev] [PATCH v3 1/4] doc: separate versioning.rst into version and policy Ray Kinsella
@ 2019-08-15 10:23 31% ` Ray Kinsella
  2019-08-30 16:20 10%   ` Kevin Traynor
  2019-08-15 10:23 30% ` [dpdk-dev] [PATCH v3 3/4] doc: updates to versioning guide for " Ray Kinsella
  2019-08-15 10:23 13% ` [dpdk-dev] [PATCH v3 4/4] doc: add maintainer for abi policy Ray Kinsella
  3 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2019-08-15 10:23 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, john.mcnamara, marko.kovacevic, hemant.agrawal

This policy change introduces major ABI versions, these are
declared every year, typically aligned with the LTS release
and are supported by subsequent releases in the following year.
This change is intended to improve ABI stabilty for those projects
consuming DPDK.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 doc/guides/contributing/abi_policy.rst | 308 ++++++++++++++++++++++++---------
 doc/guides/contributing/stable.rst     |  38 ++--
 2 files changed, 245 insertions(+), 101 deletions(-)

diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
index 55bacb4..6190bdc 100644
--- a/doc/guides/contributing/abi_policy.rst
+++ b/doc/guides/contributing/abi_policy.rst
@@ -1,33 +1,46 @@
 ..  SPDX-License-Identifier: BSD-3-Clause
-    Copyright 2018 The DPDK contributors
+    Copyright 2019 The DPDK contributors
 
-.. abi_api_policy:
+.. _abi_policy:
 
-DPDK ABI/API policy
-===================
+ABI Policy
+==========
 
 Description
 -----------
 
-This document details some methods for handling ABI management in the DPDK.
+This document details the management policy that ensures the long-term stability
+of the DPDK ABI and API.
 
 General Guidelines
 ------------------
 
-#. Whenever possible, ABI should be preserved
-#. ABI/API may be changed with a deprecation process
-#. The modification of symbols can generally be managed with versioning
-#. Libraries or APIs marked in ``experimental`` state may change without constraint
-#. New APIs will be marked as ``experimental`` for at least one release to allow
-   any issues found by users of the new API to be fixed quickly
-#. The addition of symbols is generally not problematic
-#. The removal of symbols generally is an ABI break and requires bumping of the
-   LIBABIVER macro
-#. Updates to the minimum hardware requirements, which drop support for hardware which
-   was previously supported, should be treated as an ABI change.
-
-What is an ABI
-~~~~~~~~~~~~~~
+#. Major ABI versions are declared every **year** and are then supported for one
+   year, typically aligned with the :ref:`LTS release <stable_lts_releases>`.
+#. The ABI version is managed at a project level in DPDK, with the ABI version
+   reflected in all :ref:`library's soname <what_is_soname>`.
+#. The ABI should be preserved and not changed lightly. ABI changes must follow
+   the outlined :ref:`deprecation process <abi_changes>`.
+#. The addition of symbols is generally not problematic. The modification of
+   symbols is managed with :ref:`ABI Versioning <abi_versioning>`.
+#. The removal of symbols is considered an :ref:`ABI breakage <abi_breakages>`,
+   once approved these will form part of the next ABI version.
+#. Libraries or APIs marked as :ref:`Experimental <experimental_apis>` are not
+   considered part of an ABI version and may change without constraint.
+#. Updates to the :ref:`minimum hardware requirements <hw_rqmts>`, which drop
+   support for hardware which was previously supported, should be treated as an
+   ABI change.
+
+.. note::
+
+   In 2019, the DPDK community stated it's intention to move to ABI stable
+   releases, over a number of release cycles. Beginning with maintaining ABI
+   stability through one year of DPDK releases starting from DPDK 19.11. This
+   policy will be reviewed in 2020, with intention of lengthening the stability
+   period.
+
+What is an ABI?
+~~~~~~~~~~~~~~~
 
 An ABI (Application Binary Interface) is the set of runtime interfaces exposed
 by a library. It is similar to an API (Application Programming Interface) but
@@ -39,30 +52,67 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
 preserved, or (when modified), done in such a way that the application is unable
 to behave improperly or in an unexpected fashion.
 
+What is an ABI version?
+~~~~~~~~~~~~~~~~~~~~~~~
 
-ABI/API Deprecation
--------------------
+An ABI version is an instance of a library's ABI at a specific release. Certain
+releases are considered by the community to be milestone releases, the yearly
+LTS for example. Supporting those milestone release's ABI for some number of
+subsequent releases is desirable to facilitate application upgrade. Those ABI
+version's aligned with milestones release are therefore called 'ABI major
+versions' and are supported for some number of releases.
+
+More details on major ABI version can be found in the :ref:`ABI versioning
+<major_abi_versions>` guide.
 
 The DPDK ABI policy
-~~~~~~~~~~~~~~~~~~~
+-------------------
+
+A major ABI version is declared every year, aligned with that year's LTS
+release, e.g. v19.11. This ABI version is then supported for one year by all
+subsequent releases within that time period, until the next LTS release, e.g.
+v20.11.
+
+At the declaration of a major ABI version, major version numbers encoded in
+libraries soname's are bumped to indicate the new version, with the minor
+version reset to ``0``. An example would be ``librte_eal.so.20.3`` would become
+``librte_eal.so.21.0``.
+
+The ABI may then change multiple times, without warning, between the last major
+ABI version increment and the HEAD label of the git tree, with the condition
+that ABI compatibility with the major ABI version is preserved and therefore
+soname's do not change.
+
+Minor versions are incremented to indicate the release of a new ABI compatible
+DPDK release, typically the DPDK quarterly releases. An example of this, might
+be that ``librte_eal.so.20.1`` would indicate the first ABI compatible DPDK
+release, following the declaration of the new major ABI version ``20``.
+
+ABI versions, are supported by each release until such time as the next major
+ABI version is declared. At that time, the deprecation of the previous major ABI
+version will be noted in the Release Notes with guidance on individual symbol
+depreciation and upgrade notes provided.
 
-ABI versions are set at the time of major release labeling, and the ABI may
-change multiple times, without warning, between the last release label and the
-HEAD label of the git tree.
+.. _abi_changes:
 
-ABI versions, once released, are available until such time as their
-deprecation has been noted in the Release Notes for at least one major release
-cycle. For example consider the case where the ABI for DPDK 2.0 has been
-shipped and then a decision is made to modify it during the development of
-DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
-release and the modification will be made available in the DPDK 2.2 release.
+ABI Changes
+~~~~~~~~~~~
 
-ABI versions may be deprecated in whole or in part as needed by a given
-update.
+The ABI may still change after the declaration of a major ABI version, that is
+new APIs may be still added or existing APIs may be modified.
 
-Some ABI changes may be too significant to reasonably maintain multiple
-versions. In those cases ABI's may be updated without backward compatibility
-being provided. The requirements for doing so are:
+.. Warning::
+
+   Note that, the process for ABI deprecation should not be undertaken lightly.
+   ABI stability is extremely important for downstream consumers of the DPDK,
+   especially when distributed in shared object form. Every effort should be
+   made to preserve the ABI whenever possible. The ABI should only be changed
+   for significant reasons, such as performance enhancements. ABI breakage due
+   to changes such as reorganizing public structure fields for aesthetic or
+   readability purposes should be avoided.
+
+
+The requirements for changing the ABI are:
 
 #. At least 3 acknowledgments of the need to do so must be made on the
    dpdk.org mailing list.
@@ -71,34 +121,119 @@ being provided. The requirements for doing so are:
      no maintainer is available for the component, the tree/sub-tree maintainer
      for that component must acknowledge the ABI change instead.
 
+   - The acknowledgment of a member of the technical board, as a delegate of the
+     `technical board <https://core.dpdk.org/techboard/>`_ acknowledging the
+     need for the ABI change, is also mandatory.
+
    - It is also recommended that acknowledgments from different "areas of
      interest" be sought for each deprecation, for example: from NIC vendors,
      CPU vendors, end-users, etc.
 
-#. The changes (including an alternative map file) can be included with
-   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
-   to provide more details about oncoming changes.
-   ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
-   More preferred way to provide this information is sending the feature
-   as a separate patch and reference it in deprecation notice.
+#. Backward compatibly with the major ABI version must be maintained through
+   :ref:`abi_versioning`, with :ref:`forward-only <forward-only>` compatibility
+   offered for any ABI changes that are indicated to be part of the next ABI
+   version.
 
-#. A full deprecation cycle, as explained above, must be made to offer
-   downstream consumers sufficient warning of the change.
+   - In situations were backward compatibility is not possible, read the
+     section on :ref:`abi_breakages`.
 
-Note that the above process for ABI deprecation should not be undertaken
-lightly. ABI stability is extremely important for downstream consumers of the
-DPDK, especially when distributed in shared object form. Every effort should
-be made to preserve the ABI whenever possible. The ABI should only be changed
-for significant reasons, such as performance enhancements. ABI breakage due to
-changes such as reorganizing public structure fields for aesthetic or
-readability purposes should be avoided.
+   - No backward or forward compatibility is offered for API changes marked as
+     ``experimental``, as described in the section on :ref:`Experimental APIs
+     and Libraries <experimental_apis>`.
 
-.. note::
+#. If a newly proposed API functionally replaces an existing one, when the new
+   API becomes non-experimental, then the old one is marked with
+   ``__rte_deprecated``.
+
+    - The depreciated API should follow the notification process to be removed,
+      see  :ref:`deprecation_notices`.
+
+    - At the declaration of the next major ABI version, those ABI changes then
+      become a formal part of the new ABI and the requirement to preserve ABI
+      compatibility with the last major ABI version is then dropped.
+
+    - The responsibility for removing redundant ABI compatibility code rests
+      with the original contributor of the ABI changes, failing that, then with
+      the contributor's company and then finally with the maintainer.
+
+.. _forward-only:
+
+.. Note::
+
+   Note that forward-only compatibility is offered for those changes made
+   between major ABI versions. As a library's soname can only describe
+   compatibility with the last major ABI version, until the next major ABI
+   version is declared, these changes therefore cannot be resolved as a runtime
+   dependency through the soname. Therefore any application wishing to make use
+   of these ABI changes can only ensure that it's runtime dependencies are met
+   through Operating System package versioning.
+
+.. _hw_rqmts:
+
+.. Note::
 
    Updates to the minimum hardware requirements, which drop support for hardware
    which was previously supported, should be treated as an ABI change, and
-   follow the relevant deprecation policy procedures as above: 3 acks and
-   announcement at least one release in advance.
+   follow the relevant deprecation policy procedures as above: 3 acks, technical
+   board approval and announcement at least one release in advance.
+
+.. _abi_breakages:
+
+ABI Breakages
+~~~~~~~~~~~~~
+
+For those ABI changes that are too significant to reasonably maintain multiple
+symbol versions, there is an amended process. In these cases, ABIs may be
+updated without the requirement of backward compatibility being provided. These
+changes must follow the `same process :ref:`described above <abi_changes>` as non-breaking
+changes, however with the following additional requirements:
+
+#. ABI breaking changes (including an alternative map file) can be included with
+   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option, to provide
+   more details about oncoming changes. ``RTE_NEXT_ABI`` wrapper will be removed
+   at the declaration of the next major ABI version.
+
+#. Once approved, and after the depreciation notice has been observed these
+   changes will form part of the next declared major ABI version.
+
+Examples of ABI Changes
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The following are examples of allowable ABI changes occurring between
+declarations of major ABI versions.
+
+* DPDK 19.11 release, defines the function ``rte_foo()``, and ``rte_foo()``
+  as part of the major ABI version ``20``.
+
+* DPDK 20.02 release defines a new function ``rte_foo(uint8_t bar)``, and
+  this is not a problem as long as the symbol ``rte_foo@DPDK20`` is
+  preserved through :ref:`abi_versioning`.
+
+  - The new function may be marked with the ``__rte_experimental`` tag for a
+    number of releases, as described in the section :ref:`experimental_apis`.
+
+  - Once ``rte_foo(uint8_t bar)`` becomes non-experimental ``rte_foo()`` is then
+    declared as ``__rte_depreciated``, with an associated deprecation notice
+    provided.
+
+* DPDK 19.11 is not re-released to include ``rte_foo(uint8_t bar)``, the new
+  version of ``rte_foo`` only exists from DPDK 20.02 onwards as described in the
+  :ref:`note on forward-only compatibility<forward-only>`.
+
+* DPDK 20.02 release defines the experimental function ``__rte_experimental
+  rte_baz()``. This function may or may not exist in the DPDK 20.05 release.
+
+* An application ``dPacket`` wishes to use ``rte_foo(uint8_t bar)``, before the
+  declaration of the DPDK ``21`` major API version. The application can only
+  ensure it's runtime dependencies are met by specifying ``DPDK (>= 20.2)`` as
+  an explicit package dependency, as the soname only may only indicate the
+  supported major ABI version.
+
+* At the release of DPDK 20.11, the function ``rte_foo(uint8_t bar)`` becomes
+  formally part of then new major ABI version DPDK 21.0 and ``rte_foo()`` may be
+  removed.
+
+.. _deprecation_notices:
 
 Examples of Deprecation Notices
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -106,46 +241,42 @@ Examples of Deprecation Notices
 The following are some examples of ABI deprecation notices which would be
 added to the Release Notes:
 
-* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
-  to be replaced with the inline function ``rte_foo()``.
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with ABI version
+  21, to be replaced with the inline function ``rte_foo()``.
 
 * The function ``rte_mbuf_grok()`` has been updated to include a new parameter
-  in version 2.0. Backwards compatibility will be maintained for this function
-  until the release of version 2.1
+  in version 20.2. Backwards compatibility will be maintained for this function
+  until the release of the new DPDK major ABI version 21, in DPDK version
+  20.11.
 
-* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+* The members of ``struct rte_foo`` have been reorganized in DPDK 20.02 for
   performance reasons. Existing binary applications will have backwards
-  compatibility in release 2.0, while newly built binaries will need to
-  reference the new structure variant ``struct rte_foo2``. Compatibility will
-  be removed in release 2.2, and all applications will require updating and
+  compatibility in release 20.02, while newly built binaries will need to
+  reference the new structure variant ``struct rte_foo2``. Compatibility will be
+  removed in release 20.11, and all applications will require updating and
   rebuilding to the new structure at that time, which will be renamed to the
   original ``struct rte_foo``.
 
 * Significant ABI changes are planned for the ``librte_dostuff`` library. The
-  upcoming release 2.0 will not contain these changes, but release 2.1 will,
+  upcoming release 20.02 will not contain these changes, but release 20.11 will,
   and no backwards compatibility is planned due to the extensive nature of
-  these changes. Binaries using this library built prior to version 2.1 will
+  these changes. Binaries using this library built prior to ABI version 21 will
   require updating and recompilation.
 
-New API replacing previous one
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If a new API proposed functionally replaces an existing one, when the new API
-becomes non-experimental then the old one is marked with ``__rte_deprecated``.
-Deprecated APIs are removed completely just after the next LTS.
-
-Reminder that old API should follow deprecation process to be removed.
+.. _experimental_apis:
 
+Experimental
+------------
 
-Experimental APIs
------------------
+APIs
+~~~~
 
-APIs marked as ``experimental`` are not considered part of the ABI and may
-change without warning at any time.  Since changes to APIs are most likely
-immediately after their introduction, as users begin to take advantage of
-those new APIs and start finding issues with them, new DPDK APIs will be
-automatically marked as ``experimental`` to allow for a period of stabilization
-before they become part of a tracked ABI.
+APIs marked as ``experimental`` are not considered part of an ABI version and
+may change without warning at any time. Since changes to APIs are most likely
+immediately after their introduction, as users begin to take advantage of those
+new APIs and start finding issues with them, new DPDK APIs will be automatically
+marked as ``experimental`` to allow for a period of stabilization before they
+become part of a tracked ABI version.
 
 Note that marking an API as experimental is a multi step process.
 To mark an API as experimental, the symbols which are desired to be exported
@@ -163,7 +294,16 @@ In addition to tagging the code with ``__rte_experimental``,
 the doxygen markup must also contain the EXPERIMENTAL string,
 and the MAINTAINERS file should note the EXPERIMENTAL libraries.
 
-For removing the experimental tag associated with an API, deprecation notice
-is not required. Though, an API should remain in experimental state for at least
-one release. Thereafter, normal process of posting patch for review to mailing
-list can be followed.
+For removing the experimental tag associated with an API, deprecation notice is
+not required. Though, an API should remain in experimental state for at least
+one release. Thereafter, the normal process of posting patch for review to
+mailing list can be followed.
+
+Libraries
+~~~~~~~~~
+
+Libraries marked as ``experimental`` are entirely not considered part of an ABI
+version, and may change without warning at any time. Experimental libraries
+always have a major version of ``0`` to indicate they exist outside of
+:ref:`abi_versioning` , with the minor version incremented with each ABI change
+to library.
diff --git a/doc/guides/contributing/stable.rst b/doc/guides/contributing/stable.rst
index 6a5eee9..d95c200 100644
--- a/doc/guides/contributing/stable.rst
+++ b/doc/guides/contributing/stable.rst
@@ -1,7 +1,7 @@
 ..  SPDX-License-Identifier: BSD-3-Clause
     Copyright 2018 The DPDK contributors
 
-.. stable_lts_releases:
+.. _stable_lts_releases:
 
 DPDK Stable Releases and Long Term Support
 ==========================================
@@ -53,6 +53,9 @@ year's November (X.11) release will be maintained as an LTS for 2 years.
 After the X.11 release, an LTS branch will be created for it at
 http://git.dpdk.org/dpdk-stable where bugfixes will be backported to.
 
+A LTS release may align with the declaration of a new major ABI version,
+please read the :ref:`abi_policy` for more information.
+
 It is anticipated that there will be at least 4 releases per year of the LTS
 or approximately 1 every 3 months. However, the cadence can be shorter or
 longer depending on the number and criticality of the backported
@@ -68,10 +71,13 @@ point the LTS branch will no longer be maintained with no further releases.
 What changes should be backported
 ---------------------------------
 
-Backporting should be limited to bug fixes. All patches accepted on the master
-branch with a Fixes: tag should be backported to the relevant stable/LTS
-branches, unless the submitter indicates otherwise. If there are exceptions,
-they will be discussed on the mailing lists.
+Backporting is a naturally conservative activity, and therefore should only
+include bug fixes and support for new hardware, were adding support does not
+necessitate DPDK ABI/API changes.
+
+All patches accepted on the master branch with a Fixes: tag should be backported
+to the relevant stable/LTS branches, unless the submitter indicates otherwise.
+If there are exceptions, they will be discussed on the mailing lists.
 
 Fixes suitable for backport should have a ``Cc: stable@dpdk.org`` tag in the
 commit message body as follows::
@@ -86,13 +92,18 @@ commit message body as follows::
      Signed-off-by: Alex Smith <alex.smith@example.com>
 
 
-Fixes not suitable for backport should not include the ``Cc: stable@dpdk.org`` tag.
+Fixes not suitable for backport should not include the ``Cc: stable@dpdk.org``
+tag.
 
-Features should not be backported to stable releases. It may be acceptable, in
-limited cases, to back port features for the LTS release where:
+New features, with the exception of new hardware support, should not be
+backported to stable releases. In the case of new hardware support or any other
+exceptional circumstances limited backporting maybe permitted to the LTS release
+where:
 
-* There is a justifiable use case (for example a new PMD).
-* The change is non-invasive.
+* There is a justifiable use case, for example the change is required to support
+  a new platform or device (for example a new PMD).
+* The change is ABI/API preserving, it does not present an obvious "new feature"
+  to end consumer.
 * The work of preparing the backport is done by the proposer.
 * There is support within the community.
 
@@ -119,10 +130,3 @@ A Stable Release will be released by:
   list.
 
 Stable releases are available on the `dpdk.org download page <http://core.dpdk.org/download/>`_.
-
-
-ABI
----
-
-The Stable Release should not be seen as a way of breaking or circumventing
-the DPDK ABI policy.
-- 
2.7.4


^ permalink raw reply	[relevance 31%]

* [dpdk-dev] [PATCH v3 0/4] doc: changes to abi policy introducing major abi versions
@ 2019-08-15 10:23 11% Ray Kinsella
  2019-08-15 10:23 13% ` [dpdk-dev] [PATCH v3 1/4] doc: separate versioning.rst into version and policy Ray Kinsella
                   ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From: Ray Kinsella @ 2019-08-15 10:23 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, john.mcnamara, marko.kovacevic, hemant.agrawal

TL;DR abbreviation:
A major ABI version that all DPDK releases during a one year period
support. ABI versioning is managed at a project-level, in place of library-level
management. ABI changes to add new features are permitted, as long as ABI
compatibility with the major ABI version is maintained.

Detail:
This patch introduces major ABI versions, supported for one year and released
aligned with the LTS release. This ABI version is then supported by all
subsequent releases within that one year period. The intention is that the one
year support period, will then be reviewed after the initial year with the
intention of lengthing the support period for the next ABI version.

ABI changes that preserve ABI compatibility with the major ABI version are
permitted in subsequent releases. ABI changes, follow similar approval rules as
before with the additional gate of now requiring technical board approval. The
merging and release of ABI breaking changes would now be pushed to the
declaration of the next major ABI version.

This change encourages developers to maintain ABI compatibility with the major
ABI version, by promoting a permissive culture around those changes that
preserve ABI compatibility. This approach begins to align DPDK with those
projects that declare major ABI versions (e.g. version 2.x, 3.x) and support
those versions for some period, typically two years or more.

To provide an example of how this might work in practice:

 * DPDK v20 is declared as the supported ABI version for one year, aligned with
   the DPDK v19.11 (LTS) release. All library sonames are updated to reflect the
   new ABI version, e.g. librte_eal.so.20, librte_acl.so.20...
 * DPDK v20.02 .. v20.08 releases are ABI compatible with the DPDK v20 ABI. ABI
   changes are permitted from DPDK v20.02 onwards, with the condition that ABI
   compatibility with DPDK v20 is preserved.
 * DPDK v21 is declared as the new supported ABI version for two years, aligned
   with the DPDK v20.11 (LTS) release. The DPDK v20 ABI is now depreciated,
   library sonames are updated to v21 and ABI compatibility breaking changes may
   be introduced.

Ray Kinsella (4):
  doc: separate versioning.rst into version and policy
  doc: changes to abi policy introducing major abi versions
  doc: updates to versioning guide for abi versions
  doc: add maintainer for abi policy

 MAINTAINERS                                |   4 +
 doc/guides/contributing/abi_policy.rst     | 309 +++++++++++++++
 doc/guides/contributing/abi_versioning.rst | 515 +++++++++++++++++++++++++
 doc/guides/contributing/index.rst          |   3 +-
 doc/guides/contributing/patches.rst        |   6 +-
 doc/guides/contributing/stable.rst         |  38 +-
 doc/guides/contributing/versioning.rst     | 591 -----------------------------
 doc/guides/rel_notes/deprecation.rst       |   2 +-
 8 files changed, 855 insertions(+), 613 deletions(-)
 create mode 100644 doc/guides/contributing/abi_policy.rst
 create mode 100644 doc/guides/contributing/abi_versioning.rst
 delete mode 100644 doc/guides/contributing/versioning.rst

-- 
2.7.4


^ permalink raw reply	[relevance 11%]

* Re: [dpdk-dev] [PATCH v2] ethdev: add more protocol support in flow API
  @ 2019-08-14  9:08  4%   ` Adrien Mazarguil
  2019-08-19 11:53  0%     ` Zhang, Qi Z
  0 siblings, 1 reply; 200+ results
From: Adrien Mazarguil @ 2019-08-14  9:08 UTC (permalink / raw)
  To: Wang Ying A; +Cc: qi.z.zhang, xiaolong.ye, qiming.yang, dev

Hi Wang Ying,

On Wed, Aug 14, 2019 at 11:24:30AM +0800, Wang Ying A wrote:
> Add new protocol header match support as below
> 
> RTE_FLOW_ITEM_TYPE_GTP_PSC
> 	- matches a GTP PDU extension header (type is 0x85:
> 	PDU Session Container)
> RTE_FLOW_ITEM_TYPE_PPPOES
> 	- matches a PPPoE Session header.
> RTE_FLOW_ITEM_TYPE_PPPOED
> 	- matches a PPPoE Discovery stage header.
> 
> Signed-off-by: Wang Ying A <ying.a.wang@intel.com>

OK, please split this patch, one for GTP and the other for PPPoE to make
title less vague than "add more protocol support".

For PPPoE, the distinction between session and discovery is not a bad idea
but since discovery packets typically have a different format (tags in place
of protocol), I'm not sure they should share a common structure.

How about a single "PPPOE" item without proto_id to cover both session and
discovery, then later add separate tag items on a needed basis for each
possible/optional tag (e.g. PPPOE_TAG_SERVICE_NAME)? Likewise proto_id would
be provided through a separate optional item if relevant (PPPOE_PROTO_ID).
Such an approach is already used for IPV6 and IPV6_EXT.

Another benefit is that applications could match PPPoE regardless of session
or discovery when they do not care, while PPPOED/PPPOES make that
distinction mandatory.

Also by inserting new entries in the middle of the pattern items list, this
patch breaks ABI. I think it's not on purpose, so please move them to the
end (not grouping them with existing GTP stuff is fine, ABI compat is more
important.) This must be reflected in rte_flow.h, rte_flow.c, testpmd and
documentation.

More nits below.

> ---
> ---
> v2: Remove Gerrit Change-Id's.
> ---
>  app/test-pmd/cmdline_flow.c                 | 80 +++++++++++++++++++++++++++++
>  doc/guides/prog_guide/rte_flow.rst          | 25 +++++++++
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 ++++
>  lib/librte_ethdev/rte_flow.c                |  3 ++
>  lib/librte_ethdev/rte_flow.h                | 71 +++++++++++++++++++++++++
>  5 files changed, 189 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
[...]
> +	[ITEM_PPPOES] = {
> +		.name = "pppoes",
> +		.help = "match PPPoE Session header",

Session => session

> +		.priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
> +		.next = NEXT(item_pppoe),
> +		.call = parse_vc,
> +	},
> +	[ITEM_PPPOED] = {
> +		.name = "pppoed",
> +		.help = "match PPPoE Discovery stage header",

Discovery => discovery

> +		.priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
> +		.next = NEXT(item_pppoe),
> +		.call = parse_vc,
> +	},
> +	[ITEM_PPPOE_SEID] = {
> +		.name = "seid",
> +		.help = "Session identifier",

Session => session

[...]
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index 821b524b3..d09c42071 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1055,6 +1055,31 @@ flow rules.
>  - ``teid``: tunnel endpoint identifier.
>  - Default ``mask`` matches teid only.
>  
> +Item: ``GTP_PSC``
> +^^^^^^^^^^^^^^^^^^^^^^^

Too many "^^^"'s.

[...]
> +Item: ``PPPOES``, ``PPPOED``
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Matches a PPPOE header.

PPPOE => PPPoE

> +
> +Note: PPPOES and PPPOED use the same structure. PPPOES and PPPOED item

item => items (or better, "pattern items")

> +are defined for a user-friendly API when creating PPPOE-Session and
> +PPPOE-Discovery flow rules.

Super nit: use "PPPoE" when mentioning the protocol itself and "PPPOE" when
mentioning the pattern item.

> +
> +- ``v_t_flags``: version (4b), type (4b).

Why "flags"? I don't see any so you could name it "version_type" (same in
documentation).

> +- ``code``: Message type.

Message => message

> +- ``session_id``: Session identifier.

Session => session

> +- ``length``: Payload length.

Payload => payload

> +- ``proto_id``: PPP Protocol identifier.

Protocol => protocol

> +- Default ``mask`` matches session_id,proto_id.

Missing space between session_id and proto_id.

> +
>  Item: ``ESP``
>  ^^^^^^^^^^^^^
>  
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 313e0707e..0da36d5f1 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3904,6 +3904,16 @@ This section lists supported pattern items and their attributes, if any.
>  
>    - ``teid {unsigned}``: tunnel endpoint identifier.
>  
> +- ``gtp_psc``: match GTPv1 entension header (type is 0x85).
> +
> +  - ``pdu_type {unsigned}``: PDU type (0 or 1).
> +  - ``qfi {unsigned}``: QoS flow identifier.
> +
> +- ``pppoes``, ``pppoed``: match PPPOE header.

PPPOE => PPPoE

[...]
> diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
> index b66bf1495..ad5e46190 100644
> --- a/lib/librte_ethdev/rte_flow.h
> +++ b/lib/librte_ethdev/rte_flow.h
> @@ -328,6 +328,34 @@ enum rte_flow_item_type {
>  	 */
>  	RTE_FLOW_ITEM_TYPE_GTPU,
>  
> +	/**
> +	 * Matches a GTP PDU extension header (type is 0x85:
> +	 * PDU Session Container).

Session Container => session container

> +	 *
> +	 * Configure flow for GTP packets with extension header type 0x85.
> +	 *
> +	 * See struct rte_flow_item_gtp_psc.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_GTP_PSC,
> +
> +	/**
> +	 * Matches a PPPOE header.
> +	 *
> +	 * Configure flow for PPPoE Session packets.

Session => session

> +	 *
> +	 * See struct rte_flow_item_pppoe.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PPPOES,
> +
> +	/**
> +	 * Matches a PPPOE header.
> +	 *
> +	 * Configure flow for PPPoE Discovery stage packets.

Discovery => discovery

> +	 *
> +	 * See struct rte_flow_item_pppoe.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PPPOED,
> +
>  	/**
>  	 * Matches a ESP header.
>  	 *
> @@ -922,6 +950,49 @@ static const struct rte_flow_item_gtp rte_flow_item_gtp_mask = {
>  };
>  #endif
>  
> +/**
> + * RTE_FLOW_ITEM_TYPE_GTP_PSC.
> + *
> + * Matches a GTP-extension header
> + * (type is 0x85: PDU Session Container).

Session Container => session container

(crusade against superfluous caps!)

[...]
> +/**
> + * RTE_FLOW_ITEM_TYPE_PPPOE.
> + *
> + * Matches a PPPOE header.
> + */
> +struct rte_flow_item_pppoe {
> +	/**
> +	 * Version (4b), type (4b).
> +	 */
> +	uint8_t v_t_flags;

v_t_flags => version_type

> +	uint8_t code; /**< Message type. */
> +	rte_be16_t session_id; /**< Session identifier. */
> +	rte_be16_t length; /**< Payload length. */
> +	rte_be16_t proto_id; /**< PPP Protocol identifier. */

As discussed, I suggest dropping proto_id to make this a generic match for
PPPoE.

> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_PPPOE. */
> +#ifndef __cplusplus
> +static const struct rte_flow_item_pppoe rte_flow_item_pppoe_mask = {
> +	.session_id = RTE_BE16(0xffff),
> +	.proto_id = RTE_BE16(0xffff),
> +};

I think the default for PPPoE should be an empty mask that simply says
"match PPPoE" since session_id only becomes known after negotiation and
proto_id shouldn't be part of this object.

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v9 1/3] eal/arm64: add 128-bit atomic compare exchange
  2019-07-23  7:05  2%   ` [dpdk-dev] [PATCH v8 " jerinj
@ 2019-08-14  8:27  2%     ` Phil Yang
  0 siblings, 0 replies; 200+ results
From: Phil Yang @ 2019-08-14  8:27 UTC (permalink / raw)
  To: thomas, jerinj, gage.eads, dev
  Cc: hemant.agrawal, Honnappa.Nagarahalli, gavin.hu, nd

Add 128-bit atomic compare exchange on aarch64.

Suggested-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
---

v9:
Updated 19.11 release note.

v8:
Fixed "WARNING:LONG_LINE: line over 80 characters" warnings with latest kernel
checkpatch.pl

v7:
1. Adjust code comment.

v6:
1. Put the RTE_ARM_FEATURE_ATOMICS flag into EAL group. (Jerin Jocob)
2. Keep rte_stack_lf_stubs.h doing nothing. (Gage Eads)
3. Fixed 32 bit build issue.

v5:
1. Enable RTE_ARM_FEATURE_ATOMICS on octeontx2 in default. (Jerin Jocob)
2. Record the reason of introducing "rte_stack_lf_stubs.h" in git
commit.
(Jerin, Jocob)
3. Fixed a conditional MACRO error in rte_atomic128_cmp_exchange. (Jerin
Jocob)

v4:
1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions.
(Jerin Jocob)
2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin
Jocob)
3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage
Eads/Jerin Jocob)

v3:
1. Avoid duplication code with macro. (Jerin Jocob)
2. Make invalid memory order to strongest barrier. (Jerin Jocob)
3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
4. Fix 32-bit x86 builds issue. (Gage Eads)
5. Correct documentation issues in UT. (Gage Eads)

v2:
Initial version.

 config/arm/meson.build                             |   2 +
 config/common_base                                 |   3 +
 config/defconfig_arm64-octeontx2-linuxapp-gcc      |   1 +
 config/defconfig_arm64-thunderx2-linuxapp-gcc      |   1 +
 .../common/include/arch/arm/rte_atomic_64.h        | 163 +++++++++++++++++++++
 .../common/include/arch/x86/rte_atomic_64.h        |  12 --
 lib/librte_eal/common/include/generic/rte_atomic.h |  17 ++-
 7 files changed, 186 insertions(+), 13 deletions(-)

diff --git a/config/arm/meson.build b/config/arm/meson.build
index 979018e..9f28271 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -71,11 +71,13 @@ flags_thunderx2_extra = [
 	['RTE_CACHE_LINE_SIZE', 64],
 	['RTE_MAX_NUMA_NODES', 2],
 	['RTE_MAX_LCORE', 256],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_USE_C11_MEM_MODEL', true]]
 flags_octeontx2_extra = [
 	['RTE_MACHINE', '"octeontx2"'],
 	['RTE_MAX_NUMA_NODES', 1],
 	['RTE_MAX_LCORE', 24],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_EAL_IGB_UIO', false],
 	['RTE_USE_C11_MEM_MODEL', true]]
 
diff --git a/config/common_base b/config/common_base
index 8ef75c2..2054480 100644
--- a/config/common_base
+++ b/config/common_base
@@ -82,6 +82,9 @@ CONFIG_RTE_MAX_LCORE=128
 CONFIG_RTE_MAX_NUMA_NODES=8
 CONFIG_RTE_MAX_HEAPS=32
 CONFIG_RTE_MAX_MEMSEG_LISTS=64
+
+# Use ARM LSE ATOMIC instructions
+CONFIG_RTE_ARM_FEATURE_ATOMICS=n
 # each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
 # or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
 CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
diff --git a/config/defconfig_arm64-octeontx2-linuxapp-gcc b/config/defconfig_arm64-octeontx2-linuxapp-gcc
index f20da24..7687dbe 100644
--- a/config/defconfig_arm64-octeontx2-linuxapp-gcc
+++ b/config/defconfig_arm64-octeontx2-linuxapp-gcc
@@ -9,6 +9,7 @@ CONFIG_RTE_MACHINE="octeontx2"
 CONFIG_RTE_CACHE_LINE_SIZE=128
 CONFIG_RTE_MAX_NUMA_NODES=1
 CONFIG_RTE_MAX_LCORE=24
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
 
 # Doesn't support NUMA
 CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
index cc5c64b..af4a89c 100644
--- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
+++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
@@ -9,3 +9,4 @@ CONFIG_RTE_MACHINE="thunderx2"
 CONFIG_RTE_CACHE_LINE_SIZE=64
 CONFIG_RTE_MAX_NUMA_NODES=2
 CONFIG_RTE_MAX_LCORE=256
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 97060e4..14d869b 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2015 Cavium, Inc
+ * Copyright(c) 2019 Arm Limited
  */
 
 #ifndef _RTE_ATOMIC_ARM64_H_
@@ -14,6 +15,9 @@ extern "C" {
 #endif
 
 #include "generic/rte_atomic.h"
+#include <rte_branch_prediction.h>
+#include <rte_compat.h>
+#include <rte_debug.h>
 
 #define dsb(opt) asm volatile("dsb " #opt : : : "memory")
 #define dmb(opt) asm volatile("dmb " #opt : : : "memory")
@@ -40,6 +44,165 @@ extern "C" {
 
 #define rte_cio_rmb() dmb(oshld)
 
+/*------------------------ 128 bit atomic operations -------------------------*/
+
+#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
+#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
+					  (mo) == __ATOMIC_SEQ_CST)
+
+#define __MO_LOAD(mo)  (__HAS_ACQ((mo)) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED)
+#define __MO_STORE(mo) (__HAS_RLS((mo)) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
+static __rte_noinline rte_int128_t                                          \
+cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
+		rte_int128_t updated)                                       \
+{                                                                           \
+	/* caspX instructions register pair must start from even-numbered
+	 * register at operand 1.
+	 * So, specify registers for local variables here.
+	 */                                                                 \
+	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];            \
+	register uint64_t x1 __asm("x1") = (uint64_t)old.val[1];            \
+	register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0];        \
+	register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1];        \
+	asm volatile(                                                       \
+		op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]"   \
+		: [old0] "+r" (x0),                                         \
+		[old1] "+r" (x1)                                            \
+		: [upd0] "r" (x2),                                          \
+		[upd1] "r" (x3),                                            \
+		[dst] "r" (dst)                                             \
+		: "memory");                                                \
+	old.val[0] = x0;                                                    \
+	old.val[1] = x1;                                                    \
+	return old;                                                         \
+}
+
+__ATOMIC128_CAS_OP(__rte_cas_relaxed, "casp")
+__ATOMIC128_CAS_OP(__rte_cas_acquire, "caspa")
+__ATOMIC128_CAS_OP(__rte_cas_release, "caspl")
+__ATOMIC128_CAS_OP(__rte_cas_acq_rel, "caspal")
+#else
+#define __ATOMIC128_LDX_OP(ldx_op_name, op_string)                          \
+static inline rte_int128_t                                                  \
+ldx_op_name(const rte_int128_t *src)                                        \
+{                                                                           \
+	rte_int128_t ret;                                                   \
+	asm volatile(                                                       \
+			op_string " %0, %1, %2"                             \
+			: "=&r" (ret.val[0]),                               \
+			  "=&r" (ret.val[1])                                \
+			: "Q" (src->val[0])                                 \
+			: "memory");                                        \
+	return ret;                                                         \
+}
+
+__ATOMIC128_LDX_OP(__rte_ldx_relaxed, "ldxp")
+__ATOMIC128_LDX_OP(__rte_ldx_acquire, "ldaxp")
+
+#define __ATOMIC128_STX_OP(stx_op_name, op_string)                          \
+static inline uint32_t                                                      \
+stx_op_name(rte_int128_t *dst, const rte_int128_t src)                      \
+{                                                                           \
+	uint32_t ret;                                                       \
+	asm volatile(                                                       \
+			op_string " %w0, %1, %2, %3"                        \
+			: "=&r" (ret)                                       \
+			: "r" (src.val[0]),                                 \
+			  "r" (src.val[1]),                                 \
+			  "Q" (dst->val[0])                                 \
+			: "memory");                                        \
+	/* Return 0 on success, 1 on failure */                             \
+	return ret;                                                         \
+}
+
+__ATOMIC128_STX_OP(__rte_stx_relaxed, "stxp")
+__ATOMIC128_STX_OP(__rte_stx_release, "stlxp")
+#endif
+
+static inline int __rte_experimental
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+				rte_int128_t *exp,
+				const rte_int128_t *src,
+				unsigned int weak,
+				int success,
+				int failure)
+{
+	/* Always do strong CAS */
+	RTE_SET_USED(weak);
+	/* Ignore memory ordering for failure, memory order for
+	 * success must be stronger or equal
+	 */
+	RTE_SET_USED(failure);
+	/* Find invalid memory order */
+	RTE_ASSERT(success == __ATOMIC_RELAXED
+			|| success == __ATOMIC_ACQUIRE
+			|| success == __ATOMIC_RELEASE
+			|| success == __ATOMIC_ACQ_REL
+			|| success == __ATOMIC_SEQ_CST);
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+	rte_int128_t expected = *exp;
+	rte_int128_t desired = *src;
+	rte_int128_t old;
+
+	if (success == __ATOMIC_RELAXED)
+		old = __rte_cas_relaxed(dst, expected, desired);
+	else if (success == __ATOMIC_ACQUIRE)
+		old = __rte_cas_acquire(dst, expected, desired);
+	else if (success == __ATOMIC_RELEASE)
+		old = __rte_cas_release(dst, expected, desired);
+	else
+		old = __rte_cas_acq_rel(dst, expected, desired);
+#else
+	int ldx_mo = __MO_LOAD(success);
+	int stx_mo = __MO_STORE(success);
+	uint32_t ret = 1;
+	register rte_int128_t expected = *exp;
+	register rte_int128_t desired = *src;
+	register rte_int128_t old;
+
+	/* ldx128 can not guarantee atomic,
+	 * Must write back src or old to verify atomicity of ldx128;
+	 */
+	do {
+		if (ldx_mo == __ATOMIC_RELAXED)
+			old = __rte_ldx_relaxed(dst);
+		else
+			old = __rte_ldx_acquire(dst);
+
+		if (likely(old.int128 == expected.int128)) {
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, desired);
+			else
+				ret = __rte_stx_release(dst, desired);
+		} else {
+			/* In the failure case (since 'weak' is ignored and only
+			 * weak == 0 is implemented), expected should contain
+			 * the atomically read value of dst. This means, 'old'
+			 * needs to be stored back to ensure it was read
+			 * atomically.
+			 */
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, old);
+			else
+				ret = __rte_stx_release(dst, old);
+		}
+	} while (unlikely(ret));
+#endif
+
+	/* Unconditionally updating expected removes
+	 * an 'if' statement.
+	 * expected should already be in register if
+	 * not in the cache.
+	 */
+	*exp = old;
+
+	return (old.int128 == expected.int128);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index 1335d92..cfe7067 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -183,18 +183,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
-/**
- * 128-bit integer structure.
- */
-RTE_STD_C11
-typedef struct {
-	RTE_STD_C11
-	union {
-		uint64_t val[2];
-		__extension__ __int128 int128;
-	};
-} __rte_aligned(16) rte_int128_t;
-
 __rte_experimental
 static inline int
 rte_atomic128_cmp_exchange(rte_int128_t *dst,
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 24ff7dc..e6ab15a 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
+/**
+ * 128-bit integer structure.
+ */
+RTE_STD_C11
+typedef struct {
+	RTE_STD_C11
+	union {
+		uint64_t val[2];
+#ifdef RTE_ARCH_64
+		__extension__ __int128 int128;
+#endif
+	};
+} __rte_aligned(16) rte_int128_t;
+
 #ifdef __DOXYGEN__
 
 /**
@@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
  *     *exp = *dst
  * @endcode
  *
- * @note This function is currently only available for the x86-64 platform.
+ * @note This function is currently available for the x86-64 and aarch64
+ * platforms.
  *
  * @note The success and failure arguments must be one of the __ATOMIC_* values
  * defined in the C++11 standard. For details on their behavior, refer to the
-- 
2.7.4


^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v2] version: 19.11-rc0
  2019-08-12 11:43  6% [dpdk-dev] [PATCH] version: 19.11-rc0 David Marchand
@ 2019-08-13 12:18  6% ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-08-13 12:18 UTC (permalink / raw)
  To: dev; +Cc: thomas

Start a new release cycle with empty release notes.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
Changelog since v1:
- added missing reference in index,
- bumped the libraries version to 19.08,
- included isonum,

---
 VERSION                                |   2 +-
 doc/guides/rel_notes/index.rst         |   1 +
 doc/guides/rel_notes/release_19_11.rst | 216 +++++++++++++++++++++++++++++++++
 3 files changed, 218 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/rel_notes/release_19_11.rst

diff --git a/VERSION b/VERSION
index 909cfd6..fff18fc 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-19.08.0
+19.11.0-rc0
diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index adfaf12..26f4a97 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -8,6 +8,7 @@ Release Notes
     :maxdepth: 1
     :numbered:
 
+    release_19_11
     release_19_08
     release_19_05
     release_19_02
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
new file mode 100644
index 0000000..8490d89
--- /dev/null
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -0,0 +1,216 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2019 The DPDK contributors
+
+.. include:: <isonum.txt>
+
+DPDK Release 19.11
+==================
+
+.. **Read this first.**
+
+   The text in the sections below explains how to update the release notes.
+
+   Use proper spelling, capitalization and punctuation in all sections.
+
+   Variable and config names should be quoted as fixed width text:
+   ``LIKE_THIS``.
+
+   Build the docs and view the output file to ensure the changes are correct::
+
+      make doc-guides-html
+
+      xdg-open build/doc/html/guides/rel_notes/release_19_11.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release.
+   Sample format:
+
+   * **Add a title in the past tense with a full stop.**
+
+     Add a short 1-2 sentence description in the past tense.
+     The description should be enough to allow someone scanning
+     the release notes to understand the new feature.
+
+     If the feature adds a lot of sub-features you can use a bullet list
+     like this:
+
+     * Added feature foo to do something.
+     * Enhanced feature bar to do something else.
+
+     Refer to the previous release notes for examples.
+
+     Suggested order in release notes items:
+     * Core libs (EAL, mempool, ring, mbuf, buses)
+     * Device abstraction libs and PMDs
+       - ethdev (lib, PMDs)
+       - cryptodev (lib, PMDs)
+       - eventdev (lib, PMDs)
+       - etc
+     * Other libs
+     * Apps, Examples, Tools (if significant)
+
+     This section is a comment. Do not overwrite or remove it.
+     Also, make sure to start the actual text at the margin.
+     =========================================================
+
+
+Removed Items
+-------------
+
+.. This section should contain removed items in this release. Sample format:
+
+   * Add a short 1-2 sentence description of the removed item
+     in the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+   * sample: Add a short 1-2 sentence description of the API change
+     which was announced in the previous releases and made in this release.
+     Start with a scope label like "ethdev:".
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+   * sample: Add a short 1-2 sentence description of the ABI change
+     which was announced in the previous releases and made in this release.
+     Start with a scope label like "ethdev:".
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Shared Library Versions
+-----------------------
+
+.. Update any library version updated in this release
+   and prepend with a ``+`` sign, like this:
+
+     libfoo.so.1
+   + libupdated.so.2
+     libbar.so.1
+
+   This section is a comment. Do not overwrite or remove it.
+   =========================================================
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     librte_acl.so.2
+     librte_bbdev.so.1
+     librte_bitratestats.so.2
+     librte_bpf.so.1
+     librte_bus_dpaa.so.2
+     librte_bus_fslmc.so.2
+     librte_bus_ifpga.so.2
+     librte_bus_pci.so.2
+     librte_bus_vdev.so.2
+     librte_bus_vmbus.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.2
+     librte_compressdev.so.1
+     librte_cryptodev.so.8
+     librte_distributor.so.1
+     librte_eal.so.11
+     librte_efd.so.1
+     librte_ethdev.so.12
+     librte_eventdev.so.7
+     librte_flow_classify.so.1
+     librte_gro.so.1
+     librte_gso.so.1
+     librte_hash.so.2
+     librte_ip_frag.so.1
+     librte_ipsec.so.1
+     librte_jobstats.so.1
+     librte_kni.so.2
+     librte_kvargs.so.1
+     librte_latencystats.so.1
+     librte_lpm.so.2
+     librte_mbuf.so.5
+     librte_member.so.1
+     librte_mempool.so.5
+     librte_meter.so.3
+     librte_metrics.so.1
+     librte_net.so.1
+     librte_pci.so.1
+     librte_pdump.so.3
+     librte_pipeline.so.3
+     librte_pmd_bnxt.so.2
+     librte_pmd_bond.so.2
+     librte_pmd_i40e.so.2
+     librte_pmd_ixgbe.so.2
+     librte_pmd_dpaa2_qdma.so.1
+     librte_pmd_ring.so.2
+     librte_pmd_softnic.so.1
+     librte_pmd_vhost.so.2
+     librte_port.so.3
+     librte_power.so.1
+     librte_rawdev.so.1
+     librte_rcu.so.1
+     librte_reorder.so.1
+     librte_ring.so.2
+     librte_sched.so.3
+     librte_security.so.2
+     librte_stack.so.1
+     librte_table.so.3
+     librte_timer.so.1
+     librte_vhost.so.4
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+   * **Add title in present tense with full stop.**
+
+     Add a short 1-2 sentence description of the known issue
+     in the present tense. Add information on any known workarounds.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested
+   with this release.
+
+   The format is:
+
+   * <vendor> platform with <vendor> <type of devices> combinations
+
+     * List of CPU
+     * List of OS
+     * List of devices
+     * Other relevant details...
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
-- 
1.8.3.1


^ permalink raw reply	[relevance 6%]

* [dpdk-dev] [RFC v2 0/3] show the Rx/Tx burst description field
@ 2019-08-13  3:06  3% Haiyue Wang
  0 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2019-08-13  3:06 UTC (permalink / raw)
  To: dev; +Cc: Haiyue Wang

v1: ABI breaking
http://mails.dpdk.org/archives/dev/2019-August/140916.html
      https://patchwork.dpdk.org/patch/57624/
      https://patchwork.dpdk.org/patch/57625/
      https://patchwork.dpdk.org/patch/57626/

v2: add a simple trace API to export string type information, if the
return value > 0, then valid information is generated.

testpmd> show rxq info 0 0

********************* Infos for port 0 , RX queue 0  *********************
Mempool: mbuf_pool_socket_0
RX prefetch threshold: 0
RX host threshold: 0
RX writeback threshold: 0
RX free threshold: 32
RX drop packets: off
RX deferred start: off
RX scattered packets: on
Number of RXDs: 1024
Burst description: AVX2 Vector Scattered Rx

testpmd> show txq info 0 0

********************* Infos for port 0 , TX queue 0  *********************
TX prefetch threshold: 32
TX host threshold: 0
TX writeback threshold: 0
TX RS threshold: 32
TX free threshold: 32
TX deferred start: off
Number of TXDs: 1024
Burst description: AVX2 Vector Tx

Haiyue Wang (3):
  ethdev: add the API for getting trace information
  testpmd: show the Rx/Tx burst description
  net/ice: support the Rx/Tx burst description trace

 app/test-pmd/config.c               | 12 +++++++++
 drivers/net/ice/ice_ethdev.c        | 26 +++++++++++++++++++
 drivers/net/ice/ice_rxtx.c          | 52 +++++++++++++++++++++++++++++++++++++
 drivers/net/ice/ice_rxtx.h          |  4 +++
 lib/librte_ethdev/rte_ethdev.c      | 18 +++++++++++++
 lib/librte_ethdev/rte_ethdev.h      |  9 +++++++
 lib/librte_ethdev/rte_ethdev_core.h |  4 +++
 7 files changed, 125 insertions(+)

-- 
2.7.4


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
  2019-08-12 17:28  0%           ` Stephen Hemminger
@ 2019-08-12 17:36  0%             ` Wang, Haiyue
  0 siblings, 0 replies; 200+ results
From: Wang, Haiyue @ 2019-08-12 17:36 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Marchand, dev

> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, August 13, 2019 01:29
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: David Marchand <david.marchand@redhat.com>; dev <dev@dpdk.org>
> Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> 
> On Mon, 12 Aug 2019 16:00:27 +0000
> "Wang, Haiyue" <haiyue.wang@intel.com> wrote:
> 
> > > -----Original Message-----
> > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > Sent: Monday, August 12, 2019 23:54
> > > To: Wang, Haiyue <haiyue.wang@intel.com>
> > > Cc: David Marchand <david.marchand@redhat.com>; dev <dev@dpdk.org>
> > > Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> > >
> > > On Mon, 12 Aug 2019 15:42:45 +0000
> > > "Wang, Haiyue" <haiyue.wang@intel.com> wrote:
> > >
> > > > > -----Original Message-----
> > > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > > Sent: Monday, August 12, 2019 23:38
> > > > > To: David Marchand <david.marchand@redhat.com>
> > > > > Cc: Wang, Haiyue <haiyue.wang@intel.com>; dev <dev@dpdk.org>
> > > > > Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> > > > >
> > > > > On Mon, 12 Aug 2019 16:27:11 +0200
> > > > > David Marchand <david.marchand@redhat.com> wrote:
> > > > >
> > > > > > On Mon, Aug 12, 2019 at 4:20 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> > > > > > >
> > > > > > > Since some PMDs have multi-path for Rx/Tx, FD.io VPP will tell you in
> > > > > > > the Debug CLI what rx/tx function is being used:
> > > > > > >         #show hardware-interface
> > > > > > >
> > > > > > >          tx burst function: ice_xmit_pkts
> > > > > > >          rx burst function: ice_recv_scattered_pkts
> > > > > > >
> > > > > > > But if the tx/rx is static, then 'dladdr' will return nil:
> > > > > > >
> > > > > > >          tx burst function: (nil) │······················
> > > > > > >          rx burst function: (nil) │······················
> > > > > > >
> > > > > > > For making things consistent and gracefull, we introduce an new string
> > > > > > > field to describe the Rx/Tx burst information. This is vendor-neutral,
> > > > > > > it is used to identify the Rx/Tx burst selection if the PMD has more
> > > > > > > than one.
> > > > > > >
> > > > > > > If a PMD supports this, then rxqinfo/txqinfo->burst_info[0] != '\0'.
> > > > > >
> > > > > > The rx/tx handlers are the same for all queues of a ethdev port.
> > > > > > What is the added value to put this in a per queue api ?
> > > > >
> > > > > With some symbol table lookup tools it is possible to do introspection
> > > > > to find the symbol from the function pointer. Without breaking API/ABI.
> > > >
> > > > Sounds cool, any link can be reached ?
> > > >
> > > > VPP uses as below, but will fail for static function.
> > > >
> > > > static const char *
> > > > ptr2sname (void *p)
> > > > {
> > > >   Dl_info info = { 0 };
> > > >
> > > >   if (dladdr (p, &info) == 0)
> > > >     return 0;
> > > >
> > > >   return info.dli_sname;
> > > > }
> > >
> > > You need to link with -g and not strip the binary.
> >
> > You mean gdb debug mode, I guess they will not accept this also. ;-)
> 
> There other ways to mark symbol as non-debug but -g is easiest.
> One way is to not mark the function as static.
> Other ways are to achieve the same think like __attribute((visibility())
> and linker scripts etc.
> 
> Remember this is VPP you are talking about and it doesn't use standard
> DPDK make and flags.
> 

Yes, this calling is a little geek style, so we are trying to scratch
some code to make thing graceful, at least, this makes sense if multiple
rx /tx paths are provided.

Thanks for your quick feedback, we will try to find other possible design.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
  2019-08-12 16:00  0%         ` Wang, Haiyue
@ 2019-08-12 17:28  0%           ` Stephen Hemminger
  2019-08-12 17:36  0%             ` Wang, Haiyue
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-08-12 17:28 UTC (permalink / raw)
  To: Wang, Haiyue; +Cc: David Marchand, dev

On Mon, 12 Aug 2019 16:00:27 +0000
"Wang, Haiyue" <haiyue.wang@intel.com> wrote:

> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Monday, August 12, 2019 23:54
> > To: Wang, Haiyue <haiyue.wang@intel.com>
> > Cc: David Marchand <david.marchand@redhat.com>; dev <dev@dpdk.org>
> > Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> > 
> > On Mon, 12 Aug 2019 15:42:45 +0000
> > "Wang, Haiyue" <haiyue.wang@intel.com> wrote:
> >   
> > > > -----Original Message-----
> > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > Sent: Monday, August 12, 2019 23:38
> > > > To: David Marchand <david.marchand@redhat.com>
> > > > Cc: Wang, Haiyue <haiyue.wang@intel.com>; dev <dev@dpdk.org>
> > > > Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> > > >
> > > > On Mon, 12 Aug 2019 16:27:11 +0200
> > > > David Marchand <david.marchand@redhat.com> wrote:
> > > >  
> > > > > On Mon, Aug 12, 2019 at 4:20 PM Haiyue Wang <haiyue.wang@intel.com> wrote:  
> > > > > >
> > > > > > Since some PMDs have multi-path for Rx/Tx, FD.io VPP will tell you in
> > > > > > the Debug CLI what rx/tx function is being used:
> > > > > >         #show hardware-interface
> > > > > >
> > > > > >          tx burst function: ice_xmit_pkts
> > > > > >          rx burst function: ice_recv_scattered_pkts
> > > > > >
> > > > > > But if the tx/rx is static, then 'dladdr' will return nil:
> > > > > >
> > > > > >          tx burst function: (nil) │······················
> > > > > >          rx burst function: (nil) │······················
> > > > > >
> > > > > > For making things consistent and gracefull, we introduce an new string
> > > > > > field to describe the Rx/Tx burst information. This is vendor-neutral,
> > > > > > it is used to identify the Rx/Tx burst selection if the PMD has more
> > > > > > than one.
> > > > > >
> > > > > > If a PMD supports this, then rxqinfo/txqinfo->burst_info[0] != '\0'.  
> > > > >
> > > > > The rx/tx handlers are the same for all queues of a ethdev port.
> > > > > What is the added value to put this in a per queue api ?  
> > > >
> > > > With some symbol table lookup tools it is possible to do introspection
> > > > to find the symbol from the function pointer. Without breaking API/ABI.  
> > >
> > > Sounds cool, any link can be reached ?
> > >
> > > VPP uses as below, but will fail for static function.
> > >
> > > static const char *
> > > ptr2sname (void *p)
> > > {
> > >   Dl_info info = { 0 };
> > >
> > >   if (dladdr (p, &info) == 0)
> > >     return 0;
> > >
> > >   return info.dli_sname;
> > > }  
> > 
> > You need to link with -g and not strip the binary.  
> 
> You mean gdb debug mode, I guess they will not accept this also. ;-)

There other ways to mark symbol as non-debug but -g is easiest.
One way is to not mark the function as static.
Other ways are to achieve the same think like __attribute((visibility())
and linker scripts etc.

Remember this is VPP you are talking about and it doesn't use standard
DPDK make and flags.



^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
  2019-08-12 15:54  0%       ` Stephen Hemminger
@ 2019-08-12 16:00  0%         ` Wang, Haiyue
  2019-08-12 17:28  0%           ` Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2019-08-12 16:00 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Marchand, dev

> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Monday, August 12, 2019 23:54
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: David Marchand <david.marchand@redhat.com>; dev <dev@dpdk.org>
> Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> 
> On Mon, 12 Aug 2019 15:42:45 +0000
> "Wang, Haiyue" <haiyue.wang@intel.com> wrote:
> 
> > > -----Original Message-----
> > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > Sent: Monday, August 12, 2019 23:38
> > > To: David Marchand <david.marchand@redhat.com>
> > > Cc: Wang, Haiyue <haiyue.wang@intel.com>; dev <dev@dpdk.org>
> > > Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> > >
> > > On Mon, 12 Aug 2019 16:27:11 +0200
> > > David Marchand <david.marchand@redhat.com> wrote:
> > >
> > > > On Mon, Aug 12, 2019 at 4:20 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> > > > >
> > > > > Since some PMDs have multi-path for Rx/Tx, FD.io VPP will tell you in
> > > > > the Debug CLI what rx/tx function is being used:
> > > > >         #show hardware-interface
> > > > >
> > > > >          tx burst function: ice_xmit_pkts
> > > > >          rx burst function: ice_recv_scattered_pkts
> > > > >
> > > > > But if the tx/rx is static, then 'dladdr' will return nil:
> > > > >
> > > > >          tx burst function: (nil) │······················
> > > > >          rx burst function: (nil) │······················
> > > > >
> > > > > For making things consistent and gracefull, we introduce an new string
> > > > > field to describe the Rx/Tx burst information. This is vendor-neutral,
> > > > > it is used to identify the Rx/Tx burst selection if the PMD has more
> > > > > than one.
> > > > >
> > > > > If a PMD supports this, then rxqinfo/txqinfo->burst_info[0] != '\0'.
> > > >
> > > > The rx/tx handlers are the same for all queues of a ethdev port.
> > > > What is the added value to put this in a per queue api ?
> > >
> > > With some symbol table lookup tools it is possible to do introspection
> > > to find the symbol from the function pointer. Without breaking API/ABI.
> >
> > Sounds cool, any link can be reached ?
> >
> > VPP uses as below, but will fail for static function.
> >
> > static const char *
> > ptr2sname (void *p)
> > {
> >   Dl_info info = { 0 };
> >
> >   if (dladdr (p, &info) == 0)
> >     return 0;
> >
> >   return info.dli_sname;
> > }
> 
> You need to link with -g and not strip the binary.

You mean gdb debug mode, I guess they will not accept this also. ;-)

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
  2019-08-12 15:42  0%     ` Wang, Haiyue
@ 2019-08-12 15:54  0%       ` Stephen Hemminger
  2019-08-12 16:00  0%         ` Wang, Haiyue
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-08-12 15:54 UTC (permalink / raw)
  To: Wang, Haiyue; +Cc: David Marchand, dev

On Mon, 12 Aug 2019 15:42:45 +0000
"Wang, Haiyue" <haiyue.wang@intel.com> wrote:

> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Monday, August 12, 2019 23:38
> > To: David Marchand <david.marchand@redhat.com>
> > Cc: Wang, Haiyue <haiyue.wang@intel.com>; dev <dev@dpdk.org>
> > Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> > 
> > On Mon, 12 Aug 2019 16:27:11 +0200
> > David Marchand <david.marchand@redhat.com> wrote:
> >   
> > > On Mon, Aug 12, 2019 at 4:20 PM Haiyue Wang <haiyue.wang@intel.com> wrote:  
> > > >
> > > > Since some PMDs have multi-path for Rx/Tx, FD.io VPP will tell you in
> > > > the Debug CLI what rx/tx function is being used:
> > > >         #show hardware-interface
> > > >
> > > >          tx burst function: ice_xmit_pkts
> > > >          rx burst function: ice_recv_scattered_pkts
> > > >
> > > > But if the tx/rx is static, then 'dladdr' will return nil:
> > > >
> > > >          tx burst function: (nil) │······················
> > > >          rx burst function: (nil) │······················
> > > >
> > > > For making things consistent and gracefull, we introduce an new string
> > > > field to describe the Rx/Tx burst information. This is vendor-neutral,
> > > > it is used to identify the Rx/Tx burst selection if the PMD has more
> > > > than one.
> > > >
> > > > If a PMD supports this, then rxqinfo/txqinfo->burst_info[0] != '\0'.  
> > >
> > > The rx/tx handlers are the same for all queues of a ethdev port.
> > > What is the added value to put this in a per queue api ?  
> > 
> > With some symbol table lookup tools it is possible to do introspection
> > to find the symbol from the function pointer. Without breaking API/ABI.  
> 
> Sounds cool, any link can be reached ?
> 
> VPP uses as below, but will fail for static function.
> 
> static const char *
> ptr2sname (void *p)
> {
>   Dl_info info = { 0 };
> 
>   if (dladdr (p, &info) == 0)
>     return 0;
> 
>   return info.dli_sname;
> }

You need to link with -g and not strip the binary.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
  2019-08-12 15:38  3%   ` Stephen Hemminger
@ 2019-08-12 15:42  0%     ` Wang, Haiyue
  2019-08-12 15:54  0%       ` Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2019-08-12 15:42 UTC (permalink / raw)
  To: Stephen Hemminger, David Marchand; +Cc: dev

> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Monday, August 12, 2019 23:38
> To: David Marchand <david.marchand@redhat.com>
> Cc: Wang, Haiyue <haiyue.wang@intel.com>; dev <dev@dpdk.org>
> Subject: Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
> 
> On Mon, 12 Aug 2019 16:27:11 +0200
> David Marchand <david.marchand@redhat.com> wrote:
> 
> > On Mon, Aug 12, 2019 at 4:20 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> > >
> > > Since some PMDs have multi-path for Rx/Tx, FD.io VPP will tell you in
> > > the Debug CLI what rx/tx function is being used:
> > >         #show hardware-interface
> > >
> > >          tx burst function: ice_xmit_pkts
> > >          rx burst function: ice_recv_scattered_pkts
> > >
> > > But if the tx/rx is static, then 'dladdr' will return nil:
> > >
> > >          tx burst function: (nil) │······················
> > >          rx burst function: (nil) │······················
> > >
> > > For making things consistent and gracefull, we introduce an new string
> > > field to describe the Rx/Tx burst information. This is vendor-neutral,
> > > it is used to identify the Rx/Tx burst selection if the PMD has more
> > > than one.
> > >
> > > If a PMD supports this, then rxqinfo/txqinfo->burst_info[0] != '\0'.
> >
> > The rx/tx handlers are the same for all queues of a ethdev port.
> > What is the added value to put this in a per queue api ?
> 
> With some symbol table lookup tools it is possible to do introspection
> to find the symbol from the function pointer. Without breaking API/ABI.

Sounds cool, any link can be reached ?

VPP uses as below, but will fail for static function.

static const char *
ptr2sname (void *p)
{
  Dl_info info = { 0 };

  if (dladdr (p, &info) == 0)
    return 0;

  return info.dli_sname;
}

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field
  @ 2019-08-12 15:38  3%   ` Stephen Hemminger
  2019-08-12 15:42  0%     ` Wang, Haiyue
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-08-12 15:38 UTC (permalink / raw)
  To: David Marchand; +Cc: Haiyue Wang, dev

On Mon, 12 Aug 2019 16:27:11 +0200
David Marchand <david.marchand@redhat.com> wrote:

> On Mon, Aug 12, 2019 at 4:20 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> >
> > Since some PMDs have multi-path for Rx/Tx, FD.io VPP will tell you in
> > the Debug CLI what rx/tx function is being used:
> >         #show hardware-interface
> >
> >          tx burst function: ice_xmit_pkts
> >          rx burst function: ice_recv_scattered_pkts
> >
> > But if the tx/rx is static, then 'dladdr' will return nil:
> >
> >          tx burst function: (nil) │······················
> >          rx burst function: (nil) │······················
> >
> > For making things consistent and gracefull, we introduce an new string
> > field to describe the Rx/Tx burst information. This is vendor-neutral,
> > it is used to identify the Rx/Tx burst selection if the PMD has more
> > than one.
> >
> > If a PMD supports this, then rxqinfo/txqinfo->burst_info[0] != '\0'.  
> 
> The rx/tx handlers are the same for all queues of a ethdev port.
> What is the added value to put this in a per queue api ?

With some symbol table lookup tools it is possible to do introspection
to find the symbol from the function pointer. Without breaking API/ABI.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC v1 1/3] ethdev: add the Rx/Tx burst description field in queue information
  @ 2019-08-12 15:37  3%   ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-08-12 15:37 UTC (permalink / raw)
  To: Haiyue Wang; +Cc: dev

On Mon, 12 Aug 2019 22:15:03 +0800
Haiyue Wang <haiyue.wang@intel.com> wrote:

> Since each PMD has different Rx/Tx burst capabilities such as Vector,
> Scattered, Bulk etc, adding the Rx/Tx burst description field in queue
> information to provide apps current configuration of PMD Rx/Tx burst.
> 
> This is a self-description for each PMD in its own format.
> 
> Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>

I can see why it might help with diagnosing issues on VPP,
but it would have bigger impacts for other users of DPDK.

Think of a better way that doesn't break ABI.
This is not enough value to make the DPDK more unstable.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH] version: 19.11-rc0
@ 2019-08-12 11:43  6% David Marchand
  2019-08-13 12:18  6% ` [dpdk-dev] [PATCH v2] " David Marchand
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2019-08-12 11:43 UTC (permalink / raw)
  To: dev; +Cc: thomas

Start a new release cycle with empty release notes.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 VERSION                                |   2 +-
 doc/guides/rel_notes/release_19_11.rst | 214 +++++++++++++++++++++++++++++++++
 2 files changed, 215 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/rel_notes/release_19_11.rst

diff --git a/VERSION b/VERSION
index 909cfd6..fff18fc 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-19.08.0
+19.11.0-rc0
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
new file mode 100644
index 0000000..0bfbf19
--- /dev/null
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -0,0 +1,214 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2019 The DPDK contributors
+
+DPDK Release 19.11
+==================
+
+.. **Read this first.**
+
+   The text in the sections below explains how to update the release notes.
+
+   Use proper spelling, capitalization and punctuation in all sections.
+
+   Variable and config names should be quoted as fixed width text:
+   ``LIKE_THIS``.
+
+   Build the docs and view the output file to ensure the changes are correct::
+
+      make doc-guides-html
+
+      xdg-open build/doc/html/guides/rel_notes/release_19_11.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release.
+   Sample format:
+
+   * **Add a title in the past tense with a full stop.**
+
+     Add a short 1-2 sentence description in the past tense.
+     The description should be enough to allow someone scanning
+     the release notes to understand the new feature.
+
+     If the feature adds a lot of sub-features you can use a bullet list
+     like this:
+
+     * Added feature foo to do something.
+     * Enhanced feature bar to do something else.
+
+     Refer to the previous release notes for examples.
+
+     Suggested order in release notes items:
+     * Core libs (EAL, mempool, ring, mbuf, buses)
+     * Device abstraction libs and PMDs
+       - ethdev (lib, PMDs)
+       - cryptodev (lib, PMDs)
+       - eventdev (lib, PMDs)
+       - etc
+     * Other libs
+     * Apps, Examples, Tools (if significant)
+
+     This section is a comment. Do not overwrite or remove it.
+     Also, make sure to start the actual text at the margin.
+     =========================================================
+
+
+Removed Items
+-------------
+
+.. This section should contain removed items in this release. Sample format:
+
+   * Add a short 1-2 sentence description of the removed item
+     in the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+   * sample: Add a short 1-2 sentence description of the API change
+     which was announced in the previous releases and made in this release.
+     Start with a scope label like "ethdev:".
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+   * sample: Add a short 1-2 sentence description of the ABI change
+     which was announced in the previous releases and made in this release.
+     Start with a scope label like "ethdev:".
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Shared Library Versions
+-----------------------
+
+.. Update any library version updated in this release
+   and prepend with a ``+`` sign, like this:
+
+     libfoo.so.1
+   + libupdated.so.2
+     libbar.so.1
+
+   This section is a comment. Do not overwrite or remove it.
+   =========================================================
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     librte_acl.so.2
+     librte_bbdev.so.1
+     librte_bitratestats.so.2
+     librte_bpf.so.1
+     librte_bus_dpaa.so.2
+     librte_bus_fslmc.so.2
+     librte_bus_ifpga.so.2
+     librte_bus_pci.so.2
+     librte_bus_vdev.so.2
+     librte_bus_vmbus.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.2
+     librte_compressdev.so.1
+     librte_cryptodev.so.7
+     librte_distributor.so.1
+     librte_eal.so.10
+     librte_efd.so.1
+     librte_ethdev.so.12
+     librte_eventdev.so.6
+     librte_flow_classify.so.1
+     librte_gro.so.1
+     librte_gso.so.1
+     librte_hash.so.2
+     librte_ip_frag.so.1
+     librte_ipsec.so.1
+     librte_jobstats.so.1
+     librte_kni.so.2
+     librte_kvargs.so.1
+     librte_latencystats.so.1
+     librte_lpm.so.2
+     librte_mbuf.so.5
+     librte_member.so.1
+     librte_mempool.so.5
+     librte_meter.so.3
+     librte_metrics.so.1
+     librte_net.so.1
+     librte_pci.so.1
+     librte_pdump.so.3
+     librte_pipeline.so.3
+     librte_pmd_bnxt.so.2
+     librte_pmd_bond.so.2
+     librte_pmd_i40e.so.2
+     librte_pmd_ixgbe.so.2
+     librte_pmd_dpaa2_qdma.so.1
+     librte_pmd_ring.so.2
+     librte_pmd_softnic.so.1
+     librte_pmd_vhost.so.2
+     librte_port.so.3
+     librte_power.so.1
+     librte_rawdev.so.1
+     librte_rcu.so.1
+     librte_reorder.so.1
+     librte_ring.so.2
+     librte_sched.so.2
+     librte_security.so.2
+     librte_stack.so.1
+     librte_table.so.3
+     librte_timer.so.1
+     librte_vhost.so.4
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+   * **Add title in present tense with full stop.**
+
+     Add a short 1-2 sentence description of the known issue
+     in the present tense. Add information on any known workarounds.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested
+   with this release.
+
+   The format is:
+
+   * <vendor> platform with <vendor> <type of devices> combinations
+
+     * List of CPU
+     * List of OS
+     * List of devices
+     * Other relevant details...
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
-- 
1.8.3.1


^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH] eal: change max hugepage sizes to 4
  2019-08-12  9:49  0%         ` David Marchand
  2019-08-12 10:01  0%           ` Thomas Monjalon
@ 2019-08-12 10:38  0%           ` Burakov, Anatoly
  1 sibling, 0 replies; 200+ results
From: Burakov, Anatoly @ 2019-08-12 10:38 UTC (permalink / raw)
  To: David Marchand
  Cc: Thomas Monjalon, Hemant Agrawal, Gagandeep Singh, dev,
	Olivier Matz, Andrew Rybchenko, Nipun Gupta,
	Honnappa Nagarahalli, Steve Capper, Jerin Jacob Kollanukkaran,
	Bruce Richardson, Gavin Hu, Ananyev, Konstantin,
	David Christensen

On 12-Aug-19 10:49 AM, David Marchand wrote:
> On Mon, Aug 12, 2019 at 11:43 AM Burakov, Anatoly
> <anatoly.burakov@intel.com> wrote:
>> On 08-Aug-19 8:31 AM, Thomas Monjalon wrote:
>>> I would suggest to restrict the change to Arm only with an ifdef,
>>> in order to limit the risk for this release.
>>> We can think about a dynamic hugepage scan in the next release.
>>>
>>
>> I don't see how this is necessary. The 3 is an arbitrary number here,
>> and the ABI isn't broken as this is an internal structure. We could
>> increase it to 16 for all i care, and it wouldn't make any difference to
>> the rest of the code - we never populate more than we can find anyway.
> 
> I agree on the principle.
> But at the time this popped up, we were really close to the release.
> It seemed a way to mitigate any unforeseen issue by limiting to the
> platform that was affected.
> 

Fair enough. A follow up is needed so. Frankly, i don't see the need to 
complicate things with "dynamic" stuff here - a static array of 8 or 16 
page sizes should be enough for everyone (TM).

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] eal: change max hugepage sizes to 4
  2019-08-12  9:49  0%         ` David Marchand
@ 2019-08-12 10:01  0%           ` Thomas Monjalon
  2019-08-12 10:38  0%           ` Burakov, Anatoly
  1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-08-12 10:01 UTC (permalink / raw)
  To: Burakov, Anatoly
  Cc: David Marchand, Hemant Agrawal, Gagandeep Singh, dev,
	Olivier Matz, Andrew Rybchenko, Nipun Gupta,
	Honnappa Nagarahalli, Steve Capper, Jerin Jacob Kollanukkaran,
	Bruce Richardson, Gavin Hu, Ananyev, Konstantin,
	David Christensen

12/08/2019 11:49, David Marchand:
> On Mon, Aug 12, 2019 at 11:43 AM Burakov, Anatoly
> <anatoly.burakov@intel.com> wrote:
> > On 08-Aug-19 8:31 AM, Thomas Monjalon wrote:
> > > I would suggest to restrict the change to Arm only with an ifdef,
> > > in order to limit the risk for this release.
> > > We can think about a dynamic hugepage scan in the next release.
> >
> > I don't see how this is necessary. The 3 is an arbitrary number here,
> > and the ABI isn't broken as this is an internal structure. We could
> > increase it to 16 for all i care, and it wouldn't make any difference to
> > the rest of the code - we never populate more than we can find anyway.
> 
> I agree on the principle.
> But at the time this popped up, we were really close to the release.
> It seemed a way to mitigate any unforeseen issue by limiting to the
> platform that was affected.

Exactly, we were extra cautious.

Please increase the value for everybody, thanks.



^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] eal: change max hugepage sizes to 4
  2019-08-12  9:43  3%       ` Burakov, Anatoly
@ 2019-08-12  9:49  0%         ` David Marchand
  2019-08-12 10:01  0%           ` Thomas Monjalon
  2019-08-12 10:38  0%           ` Burakov, Anatoly
  0 siblings, 2 replies; 200+ results
From: David Marchand @ 2019-08-12  9:49 UTC (permalink / raw)
  To: Burakov, Anatoly
  Cc: Thomas Monjalon, Hemant Agrawal, Gagandeep Singh, dev,
	Olivier Matz, Andrew Rybchenko, Nipun Gupta,
	Honnappa Nagarahalli, Steve Capper, Jerin Jacob Kollanukkaran,
	Bruce Richardson, Gavin Hu, Ananyev, Konstantin,
	David Christensen

On Mon, Aug 12, 2019 at 11:43 AM Burakov, Anatoly
<anatoly.burakov@intel.com> wrote:
> On 08-Aug-19 8:31 AM, Thomas Monjalon wrote:
> > I would suggest to restrict the change to Arm only with an ifdef,
> > in order to limit the risk for this release.
> > We can think about a dynamic hugepage scan in the next release.
> >
>
> I don't see how this is necessary. The 3 is an arbitrary number here,
> and the ABI isn't broken as this is an internal structure. We could
> increase it to 16 for all i care, and it wouldn't make any difference to
> the rest of the code - we never populate more than we can find anyway.

I agree on the principle.
But at the time this popped up, we were really close to the release.
It seemed a way to mitigate any unforeseen issue by limiting to the
platform that was affected.


-- 
David Marchand

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] eal: change max hugepage sizes to 4
  @ 2019-08-12  9:43  3%       ` Burakov, Anatoly
  2019-08-12  9:49  0%         ` David Marchand
  0 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2019-08-12  9:43 UTC (permalink / raw)
  To: Thomas Monjalon, Hemant Agrawal, Gagandeep Singh
  Cc: dev, David Marchand, Olivier Matz, Andrew Rybchenko, Nipun Gupta,
	honnappa.nagarahalli, Steve Capper, jerinj, bruce.richardson,
	gavin.hu, konstantin.ananyev, drc

On 08-Aug-19 8:31 AM, Thomas Monjalon wrote:
> 07/08/2019 15:28, Hemant Agrawal:
>> HI Thomas,
>>
>>>>> DPDK currently is supporting maximum 3 hugepage, sizes whereas
>>>>> system can support more than this e.g.
>>>>> 64K, 2M, 32M and 1G.
>>>>
>>>> You can mention ARM platform here, and that this issue starts with
>>>> kernel 5.2 (and I would try to mention this in the title as well).
>>>> This is better than an annotation that will be lost.
>>>>
>>>>
>>>>> Having these four hugepage sizes available to use by DPDK, which is
>>>>> valid in case of '--in-memory' EAL option or using 4 separate mount
>>>>> points for each hugepage size;
>>>>> hugepage_info_init() API reports an error.
>>>>
>>>> Can you describe what is the impact from a user point of view rather
>>>> than mentioning this internal function?
>>>
>>> Yes please, we need to understand how much it is critical.
>>> Should we Cc stable@dpdk.org for backport?
>>> Should it be merged at the last minute in 19.08?
>>
>> VPP usages in-memory option. So, VPP on ARM with kernel 5.2 wont' work without this patch.
> 
> Do you want to send a v2 with a better explanation?
> 
> I would suggest to restrict the change to Arm only with an ifdef,
> in order to limit the risk for this release.
> We can think about a dynamic hugepage scan in the next release.
> 

I don't see how this is necessary. The 3 is an arbitrary number here, 
and the ABI isn't broken as this is an internal structure. We could 
increase it to 16 for all i care, and it wouldn't make any difference to 
the rest of the code - we never populate more than we can find anyway.

-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 1/2] doc: announce ethdev ABI change for LRO fields
  2019-08-06 15:27  4% ` Andrew Rybchenko
@ 2019-08-10 21:40  4%   ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-08-10 21:40 UTC (permalink / raw)
  To: Matan Azrad
  Cc: dev, Andrew Rybchenko, Ferruh Yigit, Konstantin Ananyev, Olivier Matz

06/08/2019 17:27, Andrew Rybchenko:
> On 8/6/19 5:56 PM, Matan Azrad wrote:
> > It may be needed by the user to limit the LRO session packet size.
> > In order to allow the above limitation, a new Rx configuration may be
> > added for the maximum LRO session size.
> > 
> > A new capability may be added too to expose the maximum LRO session size
> > supported by the port.
> > 
> > Signed-off-by: Matan Azrad <matan@mellanox.com>
> > ---
> > +* ethdev: new 32-bit fields may be added for maximum LRO session size, in
> > +  struct ``rte_eth_dev_info`` for the port capability and in struct
> > +  ``rte_eth_rxmode`` for the port configuration.
> 
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> 
> I don't know examples when the information is required, but can imagine.

Acked-by: Thomas Monjalon <thomas@monjalon.net>

We have only 2 acks but as they are simple new fields,
better to announce their addition in advance and allow for more
discussion during 19.11 release cycle.

Applied (only patch 1 of 2)



^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [patch v5] doc: announce API change in ethdev offload flags
  @ 2019-08-10 21:10  3%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-08-10 21:10 UTC (permalink / raw)
  To: pbhagavatula
  Cc: dev, Ananyev, Konstantin, jerinj, stephen, arybchenko,
	hemant.agrawal, Yigit, Ferruh, Richardson, Bruce, Neil Horman,
	Mcnamara, John, Kovacevic, Marko

> > Add new offload flags ``DEV_RX_OFFLOAD_RSS_HASH`` and
> > ``DEV_RX_OFFLOAD_FLOW_MARK``.
> > Add new function ``rte_eth_dev_set_supported_ptypes`` to allow application
> > to set specific ptypes to be updated in ``rte_mbuf::packet_type``
> > 
> > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> > Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > Acked-by: Jerin Jacob <jerinj@marvell.com>
> > Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

We'll probably have to discuss more the details of these new APIs,
but the overall idea looks good.
I am not sure there is any API or ABI breakage here,
so the announce may not be required.

Anyway applied, thanks.



^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for RSS hash funtion
  2019-08-06 14:45  4%   ` Ananyev, Konstantin
@ 2019-08-10 20:39  4%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-08-10 20:39 UTC (permalink / raw)
  To: Su, Simei
  Cc: dev, Ananyev, Konstantin, Zhang, Qi Z, Wu, Jingjing, Xing,
	Beilei, Yang, Qiming, orika, adrien.mazarguil, arybchenko, Yigit,
	Ferruh

06/08/2019 16:45, Ananyev, Konstantin:
> From: Thomas Monjalon
> > 04/07/2019 06:43, simei:
> > > From: Simei Su <simei.su@intel.com>
> > >
> > > Add new field SYMMETRIC_TOEPLITZ in rte_eth_hash_function. This
> > > can support symmetric hash function by rte_flow RSS action.
> > >
> > > Signed-off-by: Simei Su <simei.su@intel.com>
> > > ---
> > > +* ethdev: New member in ``rte_eth_hash_funtion`` to support symmetric hash funtion.
> > 
> > That's unfortunate there is a typo in the name of the enum you want to change.
> > 
> > Do you have any reference to the algo you want to support? A paper maybe?
> 
> If I am not mistaken that's just an intent to enable symmetric RSS hash-function via standard RSS  rte_flow API -
> feature already available with i40e and newest Intel HW.
> (AFAIK on i40e right now it could be configured via RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT).
> If so, then I think the author may need to mention what PMDs will support that feature in 19.11.

Without any more comment, this patch cannot be accepted in 19.08.



^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2] doc: announce lcore_config symbol removal
  2019-07-31 11:06  5% [dpdk-dev] [PATCH] doc: announce lcore_config symbol removal David Marchand
  2019-07-31 13:48  0% ` Stephen Hemminger
@ 2019-08-08  9:31  5% ` David Marchand
  1 sibling, 0 replies; 200+ results
From: David Marchand @ 2019-08-08  9:31 UTC (permalink / raw)
  To: dev; +Cc: thomas, stephen, bruce.richardson, jerinj, arybchenko

New accessors have been introduced to provide the hidden information.
This symbol can now be kept internal.

Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
Changelog since v1:
- added acks,
- fixed little typo,

---
 doc/guides/rel_notes/deprecation.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 70fef52..ee15ab6 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -23,6 +23,10 @@ Deprecation Notices
 * eal: The function ``rte_eal_remote_launch`` will return new error codes
   after read or write error on the pipe, instead of calling ``rte_panic``.
 
+* eal: The ``lcore_config`` struct and global symbol will be made private to
+  remove it from the externally visible ABI and allow it to be updated in the
+  future.
+
 * eal: both declaring and identifying devices will be streamlined in v18.11.
   New functions will appear to query a specific port from buses, classes of
   device and device drivers. Device declaration will be made coherent with the
-- 
1.8.3.1


^ permalink raw reply	[relevance 5%]

* [dpdk-dev] 19.11 Intel Roadmap
@ 2019-08-08  8:12  4% O'Driscoll, Tim
  0 siblings, 0 replies; 200+ results
From: O'Driscoll, Tim @ 2019-08-08  8:12 UTC (permalink / raw)
  To: dev

These are the features that we plan to submit for the 19.11 release:

Intel(r) Ethernet 810 Series Network Adapter Enhancements: Support for loading of device-specific Dynamic Device Personalization (DDP) profiles to support new protocols, rte_flow/flow director/switch filter updates to support DDP profiles, AVX2 versions of the ICE and IAVF PMDs to improve performance, multi-process support, RSS support via rte_flow, support for high/low priority flows via rte_flow, flexible descriptor support per Rx queue.

IPsec Enhancements: The rte_security API will be updated to support inline crypto statistics. A security association database will be added to the IPsec library. A new rte_security type (RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO) will be added to improve performance for IPsec with software crypto. The IPsec Security Gateway sample app will be updated to demonstrate the IPSec library's ability to support multiple IPsec sessions for the same SA (inline-crypto session plus lookaside-none).

Compression Enhancements: Intel(r) QuickAssist Technology support for stateful decompression, enhancements to the performance test tool including the ability to use external mbufs, and removal of the Experimental label from the compressdev API.

Crypto Enhancements: Increased Intel(r) QuickAssist Technology support for asymmetric (RSA) and symmetric (single-pass GCM) crypto operations, modifications to the cryptodev API to support sessionless asymmetric crypto.

Hierarchical QoS Scheduler Enhancements: The pipe (subscriber) configuration will be made more flexible by moving configuration data from the port to the sub-port level. Enhancements will also be made to provide better support for over-subscription, allowing unused bandwidth for a pipe to be redistributed to other pipes in the same sub-port.

ABI Stability: Agree and document new ABI stability policy. Implement code changes (hiding of internal structures etc.) to make ABI easier to maintain.

Virtio packed ring (introduced in Virtio 1.1 spec) performance optimisations.

Support graceful shutdown for the Intel(r) FPGA Programmable Acceleration Card N3000. The server will be able to gracefully shutdown and reload the card after certain errors (e.g. FPGA Die Temperature higher than Temperature Threshold or FPGA AUX Voltage lower than Voltage Threshold).

Extend Rawdev NTB PMD: The rawdev PMD for Non-Transparent Bridging will be extended to add a FIFO ring for Rx/Tx.

A sample application will be added for the Intel(r) QuickData Technology PMD (drivers/raw/ioat).

Intel PMDs will be updated to support RTE_ETH_DEV_CLOSE_REMOVE.

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
  2019-08-07 15:22  0%   ` Stephen Hemminger
@ 2019-08-07 15:44  0%     ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-08-07 15:44 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Jerin Jacob Kollanukkaran, Pavan Nikhilesh Bhagavatula,
	Hemant Agrawal, dev

On 8/7/19 6:22 PM, Stephen Hemminger wrote:
> On Wed, 7 Aug 2019 11:32:35 +0300
> Andrew Rybchenko <arybchenko@solarflare.com> wrote:
> 
>> On 8/7/19 5:04 AM, Jerin Jacob Kollanukkaran wrote:
>>>> -----Original Message-----
>>>> From: Stephen Hemminger <stephen@networkplumber.org>
>>>> Sent: Wednesday, August 7, 2019 4:45 AM
>>>> To: Andrew Rybchenko <arybchenko@solarflare.com>
>>>> Cc: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Hemant
>>>> Agrawal <hemant.agrawal@nxp.com>; Jerin Jacob Kollanukkaran
>>>> <jerinj@marvell.com>; dev@dpdk.org
>>>> Subject: [EXT] Re: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
>>>>
>>>> On Tue, 6 Aug 2019 12:06:35 +0300
>>>> Andrew Rybchenko <arybchenko@solarflare.com> wrote:
>>>>   
>>>>> On 8/6/19 11:47 AM, Pavan Nikhilesh Bhagavatula wrote:
>>>>>>> -----Original Message-----
>>>>>>> From: Hemant Agrawal <hemant.agrawal@nxp.com>
>>>>>>> Sent: Tuesday, August 6, 2019 1:49 PM
>>>>>>> To: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Jerin
>>>>>>> Jacob Kollanukkaran <jerinj@marvell.com>
>>>>>>> Cc: dev@dpdk.org
>>>>>>> Subject: RE: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
>>>>>>>> Add PTYPE to DEV_RX_OFFLOAD_* flags.
>>>>>>>>
>>>>>>>> Currently, most of the NICs already support PTYPE parsing and
>>>>>>>> update
>>>>>>> the
>>>>>>>> mbuf->packet_type through an internal lookup table, but there is
>>>>>>>> mbuf->no
>>>>>>> way to
>>>>>>>> disable the lookup if the application is not intrested in ptypes
>>>>>>> returned by
>>>>>>>> `rte_eth_dev_get_supported_ptypes`.
>>>>>>>>   
>>>>>>> [Hemant]  it will also mean introducing another check in datapath,
>>>>>>> if the application has asked for PTYPE offload - copy the results
>>>>>>> to mbuf-
>>>>>>>> packet_type otherwise don't do it.
>>>>>> I think that having the check would give better performance than
>>>>>> loading ptype table to L1 doing  a lookup and copying it to mbuf when the
>>>> application doesn't need it.
>>>>> Anyway, if PMD decides that it is better to always provide packet type
>>>>> information - there is no harm. Basically if the offload is not
>>>>> requested it makes packet_type undefined in mbuf.
>>>>>   
>>>>>>> Your second patch is incomplete in the sense that it only adds the
>>>>>>> capability. But it does not disable the lookups?
>>>>>> It is upto the maintainer of the PMD to disable the lookup in data
>>>>>> path. If there is a scope of optimization then they could do it. There is no
>>>> harm in exposing  PTYPE even RX_OFFLOAD_PTYPE is not enabled.
>>>>>> I was hesitant to touch data path as it would be impossible to verify
>>>> performance effect on all NICs.
>>>>> I think it is the right way to approach it especially taking
>>>>> transition into account.
>>>>>   
>>>> With hardline API policy, this has to fail on compile for old applications.
>>
>> Stephen, could you explain a bit more why.
> 
> Existing releases packets will be received with ptype for hardware that
> supports it. We should not require users to change their application to
> continue to get mbufs with ptype.  If your change would break that, and
> require application to change; then your change should break the API in
> a hard way that causes compile rather than runtime failure.

Many thanks, I got it.

> The best solution would be to just keep old applications running and compiling
> without breaking anything. That means ptype should still be received.
> 
> If (as an optimization) you want to allow application to turn of getting
> ptype; then that would be a useful. Probably best done at the port level
> as part of configuration.

I see, but it contradicts to the existing practice that offloads should
be disabled by default and a way to enable should be provided.
May be techboard should discuss it and make a decision (covering RSS
hash information and Rx mark mentioned in my review notes).

>>> Not specific to this API change. That's is the propriety any new symbol addition
>>> to the code base.
>>>
>>> Planning to make this API change available fromv19.11 LTS.
>>
>> The only way to to require applications to enable PTYPE offload to get
>> ptypes in mbuf since 19.11 LTS is to have deprecation notice in 19.08.
>>
>>>> You can't magically assume that applications using ptype will set new feature.
>>> When OFFLOAD flags got introduced, we decided to disable all offloads by default.
>>> So, need to add positive logic here to enable offload instead of enable something by
>>> Default and disable if required to get have synergy with other offloads.
>>>
>>> Will update the release note as usual to document the change.
>>> Since there is NO ABI change, IMO, we don't need deprecation notice.
>>
>> Sorry, but it is a behaviour change. Before an application does not need
>> to enable ptype offload, but now it is required. It means that application
>> will be broken and, therefore, it requires deprecation notice.
> 
> The DPDK development community has to make not breaking applications
> a higher priority than adding marginal enhancements

Fair, but where is marginal enhancements boundary?

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
  2019-08-07  8:32  0% ` Andrew Rybchenko
@ 2019-08-07 15:22  0%   ` Stephen Hemminger
  2019-08-07 15:44  0%     ` Andrew Rybchenko
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-08-07 15:22 UTC (permalink / raw)
  To: Andrew Rybchenko
  Cc: Jerin Jacob Kollanukkaran, Pavan Nikhilesh Bhagavatula,
	Hemant Agrawal, dev

On Wed, 7 Aug 2019 11:32:35 +0300
Andrew Rybchenko <arybchenko@solarflare.com> wrote:

> On 8/7/19 5:04 AM, Jerin Jacob Kollanukkaran wrote:
> >> -----Original Message-----
> >> From: Stephen Hemminger <stephen@networkplumber.org>
> >> Sent: Wednesday, August 7, 2019 4:45 AM
> >> To: Andrew Rybchenko <arybchenko@solarflare.com>
> >> Cc: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Hemant
> >> Agrawal <hemant.agrawal@nxp.com>; Jerin Jacob Kollanukkaran
> >> <jerinj@marvell.com>; dev@dpdk.org
> >> Subject: [EXT] Re: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
> >>
> >> On Tue, 6 Aug 2019 12:06:35 +0300
> >> Andrew Rybchenko <arybchenko@solarflare.com> wrote:
> >>  
> >>> On 8/6/19 11:47 AM, Pavan Nikhilesh Bhagavatula wrote:  
> >>>>> -----Original Message-----
> >>>>> From: Hemant Agrawal <hemant.agrawal@nxp.com>
> >>>>> Sent: Tuesday, August 6, 2019 1:49 PM
> >>>>> To: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Jerin
> >>>>> Jacob Kollanukkaran <jerinj@marvell.com>
> >>>>> Cc: dev@dpdk.org
> >>>>> Subject: RE: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload  
> >>>>>> Add PTYPE to DEV_RX_OFFLOAD_* flags.
> >>>>>>
> >>>>>> Currently, most of the NICs already support PTYPE parsing and
> >>>>>> update  
> >>>>> the  
> >>>>>> mbuf->packet_type through an internal lookup table, but there is
> >>>>>> mbuf->no  
> >>>>> way to  
> >>>>>> disable the lookup if the application is not intrested in ptypes  
> >>>>> returned by  
> >>>>>> `rte_eth_dev_get_supported_ptypes`.
> >>>>>>  
> >>>>> [Hemant]  it will also mean introducing another check in datapath,
> >>>>> if the application has asked for PTYPE offload - copy the results
> >>>>> to mbuf-  
> >>>>>> packet_type otherwise don't do it.  
> >>>> I think that having the check would give better performance than
> >>>> loading ptype table to L1 doing  a lookup and copying it to mbuf when the  
> >> application doesn't need it.  
> >>> Anyway, if PMD decides that it is better to always provide packet type
> >>> information - there is no harm. Basically if the offload is not
> >>> requested it makes packet_type undefined in mbuf.
> >>>  
> >>>>> Your second patch is incomplete in the sense that it only adds the
> >>>>> capability. But it does not disable the lookups?  
> >>>> It is upto the maintainer of the PMD to disable the lookup in data
> >>>> path. If there is a scope of optimization then they could do it. There is no  
> >> harm in exposing  PTYPE even RX_OFFLOAD_PTYPE is not enabled.  
> >>>> I was hesitant to touch data path as it would be impossible to verify  
> >> performance effect on all NICs.  
> >>> I think it is the right way to approach it especially taking
> >>> transition into account.
> >>>  
> >> With hardline API policy, this has to fail on compile for old applications.  
> 
> Stephen, could you explain a bit more why.

Existing releases packets will be received with ptype for hardware that
supports it. We should not require users to change their application to
continue to get mbufs with ptype.  If your change would break that, and
require application to change; then your change should break the API in
a hard way that causes compile rather than runtime failure.

The best solution would be to just keep old applications running and compiling
without breaking anything. That means ptype should still be received.

If (as an optimization) you want to allow application to turn of getting
ptype; then that would be a useful. Probably best done at the port level
as part of configuration.

> 
> > Not specific to this API change. That's is the propriety any new symbol addition
> > to the code base.
> >
> > Planning to make this API change available fromv19.11 LTS.  
> 
> The only way to to require applications to enable PTYPE offload to get
> ptypes in mbuf since 19.11 LTS is to have deprecation notice in 19.08.
> 
> >> You can't magically assume that applications using ptype will set new feature.  
> > When OFFLOAD flags got introduced, we decided to disable all offloads by default.
> > So, need to add positive logic here to enable offload instead of enable something by
> > Default and disable if required to get have synergy with other offloads.
> >
> > Will update the release note as usual to document the change.
> > Since there is NO ABI change, IMO, we don't need deprecation notice.  
> 
> Sorry, but it is a behaviour change. Before an application does not need
> to enable ptype offload, but now it is required. It means that application
> will be broken and, therefore, it requires deprecation notice.

The DPDK development community has to make not breaking applications
a higher priority than adding marginal enhancements


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
  2019-08-07  2:04  3% [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload Jerin Jacob Kollanukkaran
@ 2019-08-07  8:32  0% ` Andrew Rybchenko
  2019-08-07 15:22  0%   ` Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-08-07  8:32 UTC (permalink / raw)
  To: Jerin Jacob Kollanukkaran, Stephen Hemminger
  Cc: Pavan Nikhilesh Bhagavatula, Hemant Agrawal, dev

On 8/7/19 5:04 AM, Jerin Jacob Kollanukkaran wrote:
>> -----Original Message-----
>> From: Stephen Hemminger <stephen@networkplumber.org>
>> Sent: Wednesday, August 7, 2019 4:45 AM
>> To: Andrew Rybchenko <arybchenko@solarflare.com>
>> Cc: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Hemant
>> Agrawal <hemant.agrawal@nxp.com>; Jerin Jacob Kollanukkaran
>> <jerinj@marvell.com>; dev@dpdk.org
>> Subject: [EXT] Re: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
>>
>> On Tue, 6 Aug 2019 12:06:35 +0300
>> Andrew Rybchenko <arybchenko@solarflare.com> wrote:
>>
>>> On 8/6/19 11:47 AM, Pavan Nikhilesh Bhagavatula wrote:
>>>>> -----Original Message-----
>>>>> From: Hemant Agrawal <hemant.agrawal@nxp.com>
>>>>> Sent: Tuesday, August 6, 2019 1:49 PM
>>>>> To: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Jerin
>>>>> Jacob Kollanukkaran <jerinj@marvell.com>
>>>>> Cc: dev@dpdk.org
>>>>> Subject: RE: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
>>>>>> Add PTYPE to DEV_RX_OFFLOAD_* flags.
>>>>>>
>>>>>> Currently, most of the NICs already support PTYPE parsing and
>>>>>> update
>>>>> the
>>>>>> mbuf->packet_type through an internal lookup table, but there is
>>>>>> mbuf->no
>>>>> way to
>>>>>> disable the lookup if the application is not intrested in ptypes
>>>>> returned by
>>>>>> `rte_eth_dev_get_supported_ptypes`.
>>>>>>
>>>>> [Hemant]  it will also mean introducing another check in datapath,
>>>>> if the application has asked for PTYPE offload - copy the results
>>>>> to mbuf-
>>>>>> packet_type otherwise don't do it.
>>>> I think that having the check would give better performance than
>>>> loading ptype table to L1 doing  a lookup and copying it to mbuf when the
>> application doesn't need it.
>>> Anyway, if PMD decides that it is better to always provide packet type
>>> information - there is no harm. Basically if the offload is not
>>> requested it makes packet_type undefined in mbuf.
>>>
>>>>> Your second patch is incomplete in the sense that it only adds the
>>>>> capability. But it does not disable the lookups?
>>>> It is upto the maintainer of the PMD to disable the lookup in data
>>>> path. If there is a scope of optimization then they could do it. There is no
>> harm in exposing  PTYPE even RX_OFFLOAD_PTYPE is not enabled.
>>>> I was hesitant to touch data path as it would be impossible to verify
>> performance effect on all NICs.
>>> I think it is the right way to approach it especially taking
>>> transition into account.
>>>
>> With hardline API policy, this has to fail on compile for old applications.

Stephen, could you explain a bit more why.

> Not specific to this API change. That's is the propriety any new symbol addition
> to the code base.
>
> Planning to make this API change available fromv19.11 LTS.

The only way to to require applications to enable PTYPE offload to get
ptypes in mbuf since 19.11 LTS is to have deprecation notice in 19.08.

>> You can't magically assume that applications using ptype will set new feature.
> When OFFLOAD flags got introduced, we decided to disable all offloads by default.
> So, need to add positive logic here to enable offload instead of enable something by
> Default and disable if required to get have synergy with other offloads.
>
> Will update the release note as usual to document the change.
> Since there is NO ABI change, IMO, we don't need deprecation notice.

Sorry, but it is a behaviour change. Before an application does not need
to enable ptype offload, but now it is required. It means that application
will be broken and, therefore, it requires deprecation notice.


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
@ 2019-08-07  2:04  3% Jerin Jacob Kollanukkaran
  2019-08-07  8:32  0% ` Andrew Rybchenko
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-08-07  2:04 UTC (permalink / raw)
  To: Stephen Hemminger, Andrew Rybchenko
  Cc: Pavan Nikhilesh Bhagavatula, Hemant Agrawal, dev

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Wednesday, August 7, 2019 4:45 AM
> To: Andrew Rybchenko <arybchenko@solarflare.com>
> Cc: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Hemant
> Agrawal <hemant.agrawal@nxp.com>; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; dev@dpdk.org
> Subject: [EXT] Re: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
> 
> On Tue, 6 Aug 2019 12:06:35 +0300
> Andrew Rybchenko <arybchenko@solarflare.com> wrote:
> 
> > On 8/6/19 11:47 AM, Pavan Nikhilesh Bhagavatula wrote:
> > >
> > >> -----Original Message-----
> > >> From: Hemant Agrawal <hemant.agrawal@nxp.com>
> > >> Sent: Tuesday, August 6, 2019 1:49 PM
> > >> To: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Jerin
> > >> Jacob Kollanukkaran <jerinj@marvell.com>
> > >> Cc: dev@dpdk.org
> > >> Subject: RE: [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload
> > >>> Add PTYPE to DEV_RX_OFFLOAD_* flags.
> > >>>
> > >>> Currently, most of the NICs already support PTYPE parsing and
> > >>> update
> > >> the
> > >>> mbuf->packet_type through an internal lookup table, but there is
> > >>> mbuf->no
> > >> way to
> > >>> disable the lookup if the application is not intrested in ptypes
> > >> returned by
> > >>> `rte_eth_dev_get_supported_ptypes`.
> > >>>
> > >> [Hemant]  it will also mean introducing another check in datapath,
> > >> if the application has asked for PTYPE offload - copy the results
> > >> to mbuf-
> > >>> packet_type otherwise don't do it.
> > > I think that having the check would give better performance than
> > > loading ptype table to L1 doing  a lookup and copying it to mbuf when the
> application doesn't need it.
> >
> > Anyway, if PMD decides that it is better to always provide packet type
> > information - there is no harm. Basically if the offload is not
> > requested it makes packet_type undefined in mbuf.
> >
> > >> Your second patch is incomplete in the sense that it only adds the
> > >> capability. But it does not disable the lookups?
> > > It is upto the maintainer of the PMD to disable the lookup in data
> > > path. If there is a scope of optimization then they could do it. There is no
> harm in exposing  PTYPE even RX_OFFLOAD_PTYPE is not enabled.
> > > I was hesitant to touch data path as it would be impossible to verify
> performance effect on all NICs.
> >
> > I think it is the right way to approach it especially taking
> > transition into account.
> >
> 
> With hardline API policy, this has to fail on compile for old applications.

Not specific to this API change. That's is the propriety any new symbol addition
to the code base.

Planning to make this API change available from v19.11 LTS.

> You can't magically assume that applications using ptype will set new feature.

When OFFLOAD flags got introduced, we decided to disable all offloads by default.
So, need to add positive logic here to enable offload instead of enable something by
Default and disable if required to get have synergy with other offloads.

Will update the release note as usual to document the change. 
Since there is NO ABI change, IMO, we don't need deprecation notice.





^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH 1/2] doc: announce ethdev ABI change for LRO fields
  2019-08-06 14:56  4% [dpdk-dev] [PATCH 1/2] doc: announce ethdev ABI change for LRO fields Matan Azrad
@ 2019-08-06 15:27  4% ` Andrew Rybchenko
  2019-08-10 21:40  4%   ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-08-06 15:27 UTC (permalink / raw)
  To: Matan Azrad, dev
  Cc: Thomas Monjalon, Ferruh Yigit, Konstantin Ananyev, Olivier Matz

On 8/6/19 5:56 PM, Matan Azrad wrote:
> It may be needed by the user to limit the LRO session packet size.
> In order to allow the above limitation, a new Rx configuration may be
> added for the maximum LRO session size.
> 
> A new capability may be added too to expose the maximum LRO session size
> supported by the port.
> 
> Signed-off-by: Matan Azrad <matan@mellanox.com>
> ---
>   doc/guides/rel_notes/deprecation.rst | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 37b8592..c0cd9bc 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -59,6 +59,10 @@ Deprecation Notices
>     Target release for removal of the legacy API will be defined once most
>     PMDs have switched to rte_flow.
>   
> +* ethdev: new 32-bit fields may be added for maximum LRO session size, in
> +  struct ``rte_eth_dev_info`` for the port capability and in struct
> +  ``rte_eth_rxmode`` for the port configuration.
> +
>   * cryptodev: support for using IV with all sizes is added, J0 still can
>     be used but only when IV length in following structs ``rte_crypto_auth_xform``,
>     ``rte_crypto_aead_xform`` is set to zero. When IV length is greater or equal
> 


Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>

I don't know examples when the information is required, but can imagine.

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH 1/2] doc: announce ethdev ABI change for LRO fields
@ 2019-08-06 14:56  4% Matan Azrad
  2019-08-06 15:27  4% ` Andrew Rybchenko
  0 siblings, 1 reply; 200+ results
From: Matan Azrad @ 2019-08-06 14:56 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko,
	Konstantin Ananyev, Olivier Matz

It may be needed by the user to limit the LRO session packet size.
In order to allow the above limitation, a new Rx configuration may be
added for the maximum LRO session size.

A new capability may be added too to expose the maximum LRO session size
supported by the port.

Signed-off-by: Matan Azrad <matan@mellanox.com>
---
 doc/guides/rel_notes/deprecation.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 37b8592..c0cd9bc 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -59,6 +59,10 @@ Deprecation Notices
   Target release for removal of the legacy API will be defined once most
   PMDs have switched to rte_flow.
 
+* ethdev: new 32-bit fields may be added for maximum LRO session size, in
+  struct ``rte_eth_dev_info`` for the port capability and in struct
+  ``rte_eth_rxmode`` for the port configuration.
+  
 * cryptodev: support for using IV with all sizes is added, J0 still can
   be used but only when IV length in following structs ``rte_crypto_auth_xform``,
   ``rte_crypto_aead_xform`` is set to zero. When IV length is greater or equal
-- 
1.8.3.1


^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for RSS hash funtion
  2019-08-06 11:34  4% ` Thomas Monjalon
@ 2019-08-06 14:45  4%   ` Ananyev, Konstantin
  2019-08-10 20:39  4%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-08-06 14:45 UTC (permalink / raw)
  To: Thomas Monjalon, Su, Simei
  Cc: dev, Zhang, Qi Z, Wu,  Jingjing, Xing, Beilei, Yang, Qiming,
	orika, adrien.mazarguil, arybchenko, Yigit, Ferruh



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Tuesday, August 6, 2019 12:35 PM
> To: Su, Simei <simei.su@intel.com>
> Cc: dev@dpdk.org; Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang,
> Qiming <qiming.yang@intel.com>; orika@mellanox.com; adrien.mazarguil@6wind.com; arybchenko@solarflare.com; Yigit, Ferruh
> <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH] doc: announce ABI change for RSS hash funtion
> 
> 04/07/2019 06:43, simei:
> > From: Simei Su <simei.su@intel.com>
> >
> > Add new field SYMMETRIC_TOEPLITZ in rte_eth_hash_function. This
> > can support symmetric hash function by rte_flow RSS action.
> >
> > Signed-off-by: Simei Su <simei.su@intel.com>
> > ---
> > +* ethdev: New member in ``rte_eth_hash_funtion`` to support symmetric hash funtion.
> 
> That's unfortunate there is a typo in the name of the enum you want to change.
> 
> Do you have any reference to the algo you want to support? A paper maybe?

If I am not mistaken that's just an intent to enable symmetric RSS hash-function via standard RSS  rte_flow API -
feature already available with i40e and newest Intel HW.
(AFAIK on i40e right now it could be configured via RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT).
If so, then I think the author may need to mention what PMDs will support that feature in 19.11.
Konstantin 

> 
> 


^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2 0/10] dpdk: introduce __rte_internal tag
  2019-08-06 10:03  0%   ` Thomas Monjalon
@ 2019-08-06 12:21  0%     ` Neil Horman
  0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2019-08-06 12:21 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Jerin Jacob Kollanukkaran, Bruce Richardson

On Tue, Aug 06, 2019 at 12:03:38PM +0200, Thomas Monjalon wrote:
> I think it would be good to rebase and send at the beginning of the 19.11 cycle.
> Thank you
> 
I'm on PTO for the next 10 days or so, but yes, I'll take care of that asap.  

Thanks
Neil

> 13/06/2019 16:23, Neil Horman:
> > Hey-
> >         Based on our recent conversations regarding the use of symbols only
> > meant for internal dpdk consumption (between dpdk libraries), this is an idea
> > that I've come up with that I'd like to get some feedback on
> > 
> > Summary:
> > 1) We have symbols in the DPDK that are meant to be used between DPDK libraries,
> > but not by applications linking to them
> > 2) We would like to document those symbols in the code, so as to note them
> > clearly as for being meant for internal use only
> > 3) Linker symbol visibility is a very coarse grained tool, and so there is no
> > good way in a single library to mark items as being meant for use only by other
> > DPDK libraries, at least not without some extensive runtime checking
> > 
> > 
> > Proposal:
> > I'm proposing that we introduce the __rte_internal tag.  From a coding
> > standpoint it works a great deal like the __rte_experimental tag in that it
> > expempts the tagged symbol from ABI constraints (as the only users should be
> > represented in the DPDK build environment).  Additionally, the __rte_internal
> > macro resolves differently based on the definition of the BUILDING_RTE_SDK flag
> > (working under the assumption that said flag should only ever be set if we are
> > actually building DPDK libraries which will make use of internal calls).  If the
> > BUILDING_RTE_SDK flag is set __rte_internal resolves to __attribute__((section
> > "text.internal)), placing it in a special text section which is then used to
> > validate that the the symbol appears in the INTERNAL section of the
> > corresponding library version map).  If BUILDING_RTE_SDK is not set, then
> > __rte_internal resolves to __attribute__((error("..."))), which causes any
> > caller of the tagged function to throw an error at compile time, indicating that
> > the symbol is not available for external use.
> > 
> > This isn't a perfect solution, as applications can still hack around it of
> > course, but I think it hits some of the high points, restricting symbol access
> > for any library that prototypes its public and private symbols in the same
> > header file, excluding the internal symbols from ABI constraints, and clearly
> > documenting those symbols which we wish to limit to internal usage.
> 
> 
> 
> 
> 

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte flow RSS action
  2019-08-06 11:31  4% ` Thomas Monjalon
  2019-08-06 11:38  4%   ` Zhang, Qi Z
@ 2019-08-06 11:40  4%   ` Zhang, Qi Z
  1 sibling, 0 replies; 200+ results
From: Zhang, Qi Z @ 2019-08-06 11:40 UTC (permalink / raw)
  To: Thomas Monjalon, Su, Simei
  Cc: dev, Wu, Jingjing, Xing, Beilei, Yang, Qiming, adrien.mazarguil, orika



> -----Original Message-----
> From: Zhang, Qi Z
> Sent: Tuesday, August 6, 2019 7:39 PM
> To: 'Thomas Monjalon' <thomas@monjalon.net>; Su, Simei
> <simei.su@intel.com>
> Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Yang, Qiming <qiming.yang@intel.com>;
> adrien.mazarguil@6wind.com; orika@mellanox.com
> Subject: RE: [dpdk-dev] [PATCH] doc: announce ABI change for rte flow RSS
> action
> 
> 
> 
> > -----Original Message-----
> > From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > Sent: Tuesday, August 6, 2019 7:31 PM
> > To: Su, Simei <simei.su@intel.com>
> > Cc: dev@dpdk.org; Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang,
> > Qiming <qiming.yang@intel.com>; adrien.mazarguil@6wind.com;
> > orika@mellanox.com
> > Subject: Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte flow
> > RSS action
> >
> > 04/07/2019 06:46, simei:
> > > From: Simei Su <simei.su@intel.com>
> > >
> > > Add new structure inputset in rte_flow_action_rss. This can support
> > > input set configuration by rte_flow RSS action.
> > >
> > > Signed-off-by: Simei Su <simei.su@intel.com>
> > > ---
> > > +* ethdev: New member in ``rte_flow_action_rss`` to support input
> > > +set change
> > > +  by rte_flow RSS action. It ignores spec and focuses on mask only.
> >
> > There is no comment on this proposal.
> > I think it is missing some explanations about its usage.
> > Would you like to explain an use case and the rte_flow command?
> >
> 
> This has been replaced by
> http://patches.dpdk.org/patch/56064/

Sorry, the latest RFC should be http://patchwork.dpdk.org/patch/57346/

> 
> We don't need it now, I have updated patch status on patchwork.
> 
> Thanks
> Qi
> 


^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte flow RSS action
  2019-08-06 11:31  4% ` Thomas Monjalon
@ 2019-08-06 11:38  4%   ` Zhang, Qi Z
  2019-08-06 11:40  4%   ` Zhang, Qi Z
  1 sibling, 0 replies; 200+ results
From: Zhang, Qi Z @ 2019-08-06 11:38 UTC (permalink / raw)
  To: Thomas Monjalon, Su, Simei
  Cc: dev, Wu, Jingjing, Xing, Beilei, Yang, Qiming, adrien.mazarguil, orika



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Tuesday, August 6, 2019 7:31 PM
> To: Su, Simei <simei.su@intel.com>
> Cc: dev@dpdk.org; Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>; adrien.mazarguil@6wind.com;
> orika@mellanox.com
> Subject: Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte flow RSS
> action
> 
> 04/07/2019 06:46, simei:
> > From: Simei Su <simei.su@intel.com>
> >
> > Add new structure inputset in rte_flow_action_rss. This can support
> > input set configuration by rte_flow RSS action.
> >
> > Signed-off-by: Simei Su <simei.su@intel.com>
> > ---
> > +* ethdev: New member in ``rte_flow_action_rss`` to support input set
> > +change
> > +  by rte_flow RSS action. It ignores spec and focuses on mask only.
> 
> There is no comment on this proposal.
> I think it is missing some explanations about its usage.
> Would you like to explain an use case and the rte_flow command?
> 

This has been replaced by
http://patches.dpdk.org/patch/56064/

We don't need it now, I have updated patch status on patchwork.

Thanks
Qi



^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for RSS hash funtion
  @ 2019-08-06 11:34  4% ` Thomas Monjalon
  2019-08-06 14:45  4%   ` Ananyev, Konstantin
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-08-06 11:34 UTC (permalink / raw)
  To: simei
  Cc: dev, qi.z.zhang, jingjing.wu, beilei.xing, qiming.yang, orika,
	adrien.mazarguil, arybchenko, ferruh.yigit

04/07/2019 06:43, simei:
> From: Simei Su <simei.su@intel.com>
> 
> Add new field SYMMETRIC_TOEPLITZ in rte_eth_hash_function. This
> can support symmetric hash function by rte_flow RSS action.
> 
> Signed-off-by: Simei Su <simei.su@intel.com>
> ---
> +* ethdev: New member in ``rte_eth_hash_funtion`` to support symmetric hash funtion.

That's unfortunate there is a typo in the name of the enum you want to change.

Do you have any reference to the algo you want to support? A paper maybe?




^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] doc: announce ABI change for rte flow RSS action
  @ 2019-08-06 11:31  4% ` Thomas Monjalon
  2019-08-06 11:38  4%   ` Zhang, Qi Z
  2019-08-06 11:40  4%   ` Zhang, Qi Z
  0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2019-08-06 11:31 UTC (permalink / raw)
  To: simei
  Cc: dev, qi.z.zhang, jingjing.wu, beilei.xing, qiming.yang,
	adrien.mazarguil, orika

04/07/2019 06:46, simei:
> From: Simei Su <simei.su@intel.com>
> 
> Add new structure inputset in rte_flow_action_rss. This
> can support input set configuration by rte_flow RSS action.
> 
> Signed-off-by: Simei Su <simei.su@intel.com>
> ---
> +* ethdev: New member in ``rte_flow_action_rss`` to support input set change
> +  by rte_flow RSS action. It ignores spec and focuses on mask only.

There is no comment on this proposal.
I think it is missing some explanations about its usage.
Would you like to explain an use case and the rte_flow command?



^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH v2 0/10] dpdk: introduce __rte_internal tag
  @ 2019-08-06 10:03  0%   ` Thomas Monjalon
  2019-08-06 12:21  0%     ` Neil Horman
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-08-06 10:03 UTC (permalink / raw)
  To: Neil Horman; +Cc: dev, Jerin Jacob Kollanukkaran, Bruce Richardson

I think it would be good to rebase and send at the beginning of the 19.11 cycle.
Thank you

13/06/2019 16:23, Neil Horman:
> Hey-
>         Based on our recent conversations regarding the use of symbols only
> meant for internal dpdk consumption (between dpdk libraries), this is an idea
> that I've come up with that I'd like to get some feedback on
> 
> Summary:
> 1) We have symbols in the DPDK that are meant to be used between DPDK libraries,
> but not by applications linking to them
> 2) We would like to document those symbols in the code, so as to note them
> clearly as for being meant for internal use only
> 3) Linker symbol visibility is a very coarse grained tool, and so there is no
> good way in a single library to mark items as being meant for use only by other
> DPDK libraries, at least not without some extensive runtime checking
> 
> 
> Proposal:
> I'm proposing that we introduce the __rte_internal tag.  From a coding
> standpoint it works a great deal like the __rte_experimental tag in that it
> expempts the tagged symbol from ABI constraints (as the only users should be
> represented in the DPDK build environment).  Additionally, the __rte_internal
> macro resolves differently based on the definition of the BUILDING_RTE_SDK flag
> (working under the assumption that said flag should only ever be set if we are
> actually building DPDK libraries which will make use of internal calls).  If the
> BUILDING_RTE_SDK flag is set __rte_internal resolves to __attribute__((section
> "text.internal)), placing it in a special text section which is then used to
> validate that the the symbol appears in the INTERNAL section of the
> corresponding library version map).  If BUILDING_RTE_SDK is not set, then
> __rte_internal resolves to __attribute__((error("..."))), which causes any
> caller of the tagged function to throw an error at compile time, indicating that
> the symbol is not available for external use.
> 
> This isn't a perfect solution, as applications can still hack around it of
> course, but I think it hits some of the high points, restricting symbol access
> for any library that prototypes its public and private symbols in the same
> header file, excluding the internal symbols from ABI constraints, and clearly
> documenting those symbols which we wish to limit to internal usage.





^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] doc: remove major in designation of normal releases
@ 2019-08-05 12:30 11% Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-08-05 12:30 UTC (permalink / raw)
  To: John McNamara, Marko Kovacevic; +Cc: dev, orika

The word "major" was used to differentiate with release candidates
or stable maintenance releases.
However the word "major" can be understood as "LTS",
so it is less confusing to avoid this word.

Reported-by: Ori Kam <orika@mellanox.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 doc/guides/contributing/documentation.rst | 2 +-
 doc/guides/contributing/stable.rst        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/guides/contributing/documentation.rst b/doc/guides/contributing/documentation.rst
index 27e4b13be..550d8dec2 100644
--- a/doc/guides/contributing/documentation.rst
+++ b/doc/guides/contributing/documentation.rst
@@ -62,7 +62,7 @@ added to by the developer.
 
   The Release Notes document which features have been added in the current and previous releases of DPDK and highlight
   any known issues.
-  The Releases Notes also contain notifications of features that will change ABI compatibility in the next major release.
+  The Releases Notes also contain notifications of features that will change ABI compatibility in the next release.
 
   Developers should include updates to the Release Notes with patch sets that relate to any of the following sections:
 
diff --git a/doc/guides/contributing/stable.rst b/doc/guides/contributing/stable.rst
index 6a5eee9bd..24b9e8b7d 100644
--- a/doc/guides/contributing/stable.rst
+++ b/doc/guides/contributing/stable.rst
@@ -25,7 +25,7 @@ Release to indicate longer term support.
 Stable Releases
 ---------------
 
-Any major release of DPDK can be designated as a Stable Release if a
+Any release of DPDK can be designated as a Stable Release if a
 maintainer volunteers to maintain it and there is a commitment from major
 contributors to validate it before releases. If a release is to be designated
 as a Stable Release, it should be done by 1 month after the master release.
-- 
2.21.0


^ permalink raw reply	[relevance 11%]

* [dpdk-dev] [PATCH v2 3/3] doc: updates to versioning guide for abi versions
  2019-08-02 15:38 11% [dpdk-dev] [PATCH v2 0/3] doc: changes to abi policy introducing major abi versions Ray Kinsella
  2019-08-02 15:38 13% ` [dpdk-dev] [PATCH v2 1/3] doc: separate versioning.rst into version and policy Ray Kinsella
  2019-08-02 15:38 32% ` [dpdk-dev] [PATCH v2 2/3] doc: changes to abi policy introducing major abi versions Ray Kinsella
@ 2019-08-02 15:38 28% ` Ray Kinsella
  2 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-02 15:38 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, hemant.agrawal

Updates to the ABI versioning guide, to account for the changes to the DPDK
ABI/API policy.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 doc/guides/contributing/abi_versioning.rst | 240 +++++++++++++++++++----------
 1 file changed, 159 insertions(+), 81 deletions(-)

diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
index 53e6ac0..38f5ec3 100644
--- a/doc/guides/contributing/abi_versioning.rst
+++ b/doc/guides/contributing/abi_versioning.rst
@@ -1,44 +1,128 @@
 ..  SPDX-License-Identifier: BSD-3-Clause
     Copyright 2018 The DPDK contributors
 
-.. library_versioning:
-
-Library versioning
+DPDK ABI Versioning
+===================
+
+This document details the mechanics of ABI version management in DPDK.
+
+What is a library's soname?
+---------------------------
+
+System libraries usually adopt the familiar major and minor version naming
+convention, where major versions (e.g. ``librte_eal 20.x, 21.x``) are presumed
+to be ABI incompatible with each other and minor versions (e.g. ``librte_eal
+20.1, 20.2``) are presumed to be ABI compatible. A library's `soname
+<https://en.wikipedia.org/wiki/Soname>`_. is typically used to provide backward
+compatibility information about a given library, describing the lowest common
+denominator ABI supported by the library. The soname or logical name for the
+library, is typically comprised of the library's name and major version e.g.
+``librte_eal.so.20``.
+
+During an application's build process, a library's soname is noted as a runtime
+dependency of the application. This information is then used by the `dynamic
+linker <https://en.wikipedia.org/wiki/Dynamic_linker>`_ when resolving the
+applications dependencies at runtime, to load a library supporting the correct
+ABI version. The library loaded at runtime therefore, may be a minor revision
+supporting the same major abi version (e.g. ``librte_eal.20.2``), as the library
+used to link the application (e.g ``librte_eal.20.0``).
+
+Major ABI versions
 ------------------
 
-Downstreams might want to provide different DPDK releases at the same time to
-support multiple consumers of DPDK linked against older and newer sonames.
+An ABI version change to a given library, especially in core libraries such as
+``librte_mbuf``, may cause an implicit ripple effect on the ABI of it's
+dependent libraries, causing ABI breakages. There may however be no explicit
+reason to bump a dependent library's ABI version, as there may have been no
+obvious change to the dependent library's API, even though the library's ABI
+compatibility will have been broken.
+
+This interdependence of DPDK libraries, means that ABI versioning of libraries
+is more manageable at a project level, with all project libraries sharing a
+**single ABI version**. In addition, the need to maintain a stable ABI for some
+number of releases as described in the section `<The DPDK ABI policy>`_, means
+that ABI version increments need to carefully planned and managed at a project
+level.
+
+Major ABI versions are therefore declared typically aligned with an LTS release
+and is then supported some number of subsequent releases, shared across all
+libraries. This means that a single project level ABI version, reflected in all
+individual library's soname, library filenames and associated version maps
+persists over multiple releases.
+
+.. code-block:: none
 
-Also due to the interdependencies that DPDK libraries can have applications
-might end up with an executable space in which multiple versions of a library
-are mapped by ld.so.
+ $ head ./lib/librte_acl/rte_acl_version.map
+ DPDK_20.0 {
+        global:
+ ...
 
-Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
-depending on LibA.
+ $ head ./lib/librte_eal/rte_eal_version.map
+ DPDK_20.0 {
+        global:
+ ...
 
-.. note::
+When an ABI change is made between major ABI versions to a given library, a new
+section is added to that library's version map describing the impending new ABI
+version, as described in the section `<Examples of ABI Macro use>`_. The
+library's soname and filename however do not change, e.g. ``libacl.so.20``, as
+ABI compatibility with the last major ABI version continues to be preserved for
+that library.
 
-    Application
-    \-> LibA.old
-    \-> LibB.new -> LibA.new
+.. code-block:: none
 
-That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
-If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
-library - versions defined in the libraries ``LIBABIVER``.
-An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
-``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
+ $ head ./lib/librte_acl/rte_acl_version.map
+ DPDK_20.0 {
+        global:
+ ...
 
+ DPDK_21.0 {
+        global:
+
+ } DPDK_20.0;
+ ...
+
+ $ head ./lib/librte_eal/rte_eal_version.map
+ DPDK_20.0 {
+        global:
+ ...
+
+However when a new ABI version is declared, for example DPDK 21.0, old
+depreciated functions may be safely removed at this point and the entire old
+major ABI version removed, see section `<Deprecating an entire ABI version>`_ on
+how this may be done.
+
+.. code-block:: none
+
+ $ head ./lib/librte_acl/rte_acl_version.map
+ DPDK_21.0 {
+        global:
+ ...
+
+ $ head -n 3 ./lib/librte_eal/rte_eal_version.map
+ DPDK_21.0 {
+        global:
+ ...
+
+At the same time, the major ABI version is changed atomically across all
+libraries by incrementing the major version in individual library's soname, e.g.
+``libacl.so.21``. This is done by bumping the LIBABIVER number in the libraries
+Makefile to indicate to dynamic linking applications that this is a later, and
+possibly incompatible library version:
+
+.. code-block:: c
+
+   -LIBABIVER := 20
+   +LIBABIVER := 21
 
-ABI versioning
---------------
 
 Versioning Macros
-~~~~~~~~~~~~~~~~~
+-----------------
 
 When a symbol is exported from a library to provide an API, it also provides a
 calling convention (ABI) that is embodied in its name, return type and
 arguments. Occasionally that function may need to change to accommodate new
-functionality or behavior. When that occurs, it is desirable to allow for
+functionality or behavior. When that occurs, it is may be required to allow for
 backward compatibility for a time with older binaries that are dynamically
 linked to the DPDK.
 
@@ -62,7 +146,7 @@ The macros exported are:
   can still be mapped back to the public symbol name.
 
 Examples of ABI Macro use
-^^^^^^^^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Updating a public API
 _____________________
@@ -106,16 +190,16 @@ maintain previous ABI versions that are accessible only to previously compiled
 binaries
 
 The addition of a parameter to the function is ABI breaking as the function is
-public, and existing application may use it in its current form.  However, the
+public, and existing application may use it in its current form. However, the
 compatibility macros in DPDK allow a developer to use symbol versioning so that
 multiple functions can be mapped to the same public symbol based on when an
-application was linked to it.  To see how this is done, we start with the
-requisite libraries version map file.  Initially the version map file for the
-acl library looks like this
+application was linked to it. To see how this is done, we start with the
+requisite libraries version map file. Initially the version map file for the acl
+library looks like this
 
 .. code-block:: none
 
-   DPDK_2.0 {
+   DPDK_20.0 {
         global:
 
         rte_acl_add_rules;
@@ -141,7 +225,7 @@ This file needs to be modified as follows
 
 .. code-block:: none
 
-   DPDK_2.0 {
+   DPDK_20.0 {
         global:
 
         rte_acl_add_rules;
@@ -163,16 +247,16 @@ This file needs to be modified as follows
         local: *;
    };
 
-   DPDK_2.1 {
+   DPDK_21.0 {
         global:
         rte_acl_create;
 
-   } DPDK_2.0;
+   } DPDK_20.0;
 
 The addition of the new block tells the linker that a new version node is
-available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
-symbols from the DPDK_2.0 node.  This list is directly translated into a list of
-exported symbols when DPDK is compiled as a shared library
+available (DPDK_21.0), which contains the symbol rte_acl_create, and inherits
+the symbols from the DPDK_20.0 node. This list is directly translated into a
+list of exported symbols when DPDK is compiled as a shared library
 
 Next, we need to specify in the code which function map to the rte_acl_create
 symbol at which versions.  First, at the site of the initial symbol definition,
@@ -191,22 +275,22 @@ with the public symbol name
 
 Note that the base name of the symbol was kept intact, as this is conducive to
 the macros used for versioning symbols.  That is our next step, mapping this new
-symbol name to the initial symbol name at version node 2.0.  Immediately after
+symbol name to the initial symbol name at version node 20.0.  Immediately after
 the function, we add this line of code
 
 .. code-block:: c
 
-   VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+   VERSION_SYMBOL(rte_acl_create, _v20, 20.0);
 
 Remembering to also add the rte_compat.h header to the requisite c file where
-these changes are being made.  The above macro instructs the linker to create a
-new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
-builds, but now points to the above newly named function.  We have now mapped
-the original rte_acl_create symbol to the original function (but with a new
-name)
+these changes are being made. The above macro instructs the linker to create a
+new symbol ``rte_acl_create@DPDK_20.0``, which matches the symbol created in
+older builds, but now points to the above newly named function. We have now
+mapped the original rte_acl_create symbol to the original function (but with a
+new name)
 
-Next, we need to create the 2.1 version of the symbol.  We create a new function
-name, with a different suffix, and  implement it appropriately
+Next, we need to create the 21.0 version of the symbol. We create a new function
+name, with a different suffix, and implement it appropriately
 
 .. code-block:: c
 
@@ -220,12 +304,12 @@ name, with a different suffix, and  implement it appropriately
         return ctx;
    }
 
-This code serves as our new API call.  Its the same as our old call, but adds
-the new parameter in place.  Next we need to map this function to the symbol
-``rte_acl_create@DPDK_2.1``.  To do this, we modify the public prototype of the call
-in the header file, adding the macro there to inform all including applications,
-that on re-link, the default rte_acl_create symbol should point to this
-function.  Note that we could do this by simply naming the function above
+This code serves as our new API call. Its the same as our old call, but adds the
+new parameter in place. Next we need to map this function to the symbol
+``rte_acl_create@DPDK_21.0``. To do this, we modify the public prototype of the
+call in the header file, adding the macro there to inform all including
+applications, that on re-link, the default rte_acl_create symbol should point to
+this function. Note that we could do this by simply naming the function above
 rte_acl_create, and the linker would chose the most recent version tag to apply
 in the version script, but we can also do this in the header file
 
@@ -233,11 +317,11 @@ in the version script, but we can also do this in the header file
 
    struct rte_acl_ctx *
    -rte_acl_create(const struct rte_acl_param *param);
-   +rte_acl_create(const struct rte_acl_param *param, int debug);
-   +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+   +rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+   +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21.0);
 
 The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
-header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
+header, to link to the rte_acl_create_v21 function and apply the DPDK_21.0
 version node to it.  This method is more explicit and flexible than just
 re-implementing the exact symbol name, and allows for other features (such as
 linking to the old symbol version by default, when the new ABI is to be opt-in
@@ -257,6 +341,7 @@ assumption is that the most recent version of the symbol is the one you want to
 map.  So, back in the C file where, immediately after ``rte_acl_create_v21`` is
 defined, we add this
 
+
 .. code-block:: c
 
    struct rte_acl_ctx *
@@ -270,21 +355,22 @@ That tells the compiler that, when building a static library, any calls to the
 symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
 
 That's it, on the next shared library rebuild, there will be two versions of
-rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
-and a new DPDK_2.1 version, used by future built applications.
+rte_acl_create, an old DPDK_20.0 version, used by previously built applications,
+and a new DPDK_21.0 version, used by future built applications.
 
 
 Deprecating part of a public API
 ________________________________
 
-Lets assume that you've done the above update, and after a few releases have
-passed you decide you would like to retire the old version of the function.
-After having gone through the ABI deprecation announcement process, removal is
-easy.  Start by removing the symbol from the requisite version map file:
+Lets assume that you've done the above update, and in preparation for the next
+major ABI version you decide you would like to retire the old version of the
+function. After having gone through the ABI deprecation announcement process,
+removal is easy. Start by removing the symbol from the requisite version map
+file:
 
 .. code-block:: none
 
-   DPDK_2.0 {
+   DPDK_20.0 {
         global:
 
         rte_acl_add_rules;
@@ -306,10 +392,10 @@ easy.  Start by removing the symbol from the requisite version map file:
         local: *;
    };
 
-   DPDK_2.1 {
+   DPDK_21.0 {
         global:
         rte_acl_create;
-   } DPDK_2.0;
+   } DPDK_20.0;
 
 
 Next remove the corresponding versioned export.
@@ -320,34 +406,26 @@ Next remove the corresponding versioned export.
 
 
 Note that the internal function definition could also be removed, but its used
-in our example by the newer version _v21, so we leave it in place.  This is a
-coding style choice.
-
-Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
-indicate to applications doing dynamic linking that this is a later, and
-possibly incompatible library version:
-
-.. code-block:: c
-
-   -LIBABIVER := 1
-   +LIBABIVER := 2
+in our example by the newer version _v21, so we leave it in place and declare it
+as static. This is a coding style choice.
 
 Deprecating an entire ABI version
 _________________________________
 
-While removing a symbol from and ABI may be useful, it is often more practical
-to remove an entire version node at once.  If a version node completely
-specifies an API, then removing part of it, typically makes it incomplete.  In
-those cases it is better to remove the entire node
+While removing a symbol from an ABI may be useful, it is more practical to
+remove an entire version node at once, as is typically done at the declaration
+of a major ABI version. If a version node completely specifies an API, then
+removing part of it, typically makes it incomplete. In those cases it is better
+to remove the entire node.
 
 To do this, start by modifying the version map file, such that all symbols from
-the node to be removed are merged into the next node in the map
+the node to be removed are merged into the next node in the map.
 
 In the case of our map above, it would transform to look as follows
 
 .. code-block:: none
 
-   DPDK_2.1 {
+   DPDK_21.0 {
         global:
 
         rte_acl_add_rules;
@@ -375,8 +453,8 @@ symbols.
 
 .. code-block:: c
 
- -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
- +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 20.0);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21.0);
 
 Lastly, any VERSION_SYMBOL macros that point to the old version node should be
 removed, taking care to keep, where need old code in place to support newer
-- 
2.7.4


^ permalink raw reply	[relevance 28%]

* [dpdk-dev] [PATCH v2 2/3] doc: changes to abi policy introducing major abi versions
  2019-08-02 15:38 11% [dpdk-dev] [PATCH v2 0/3] doc: changes to abi policy introducing major abi versions Ray Kinsella
  2019-08-02 15:38 13% ` [dpdk-dev] [PATCH v2 1/3] doc: separate versioning.rst into version and policy Ray Kinsella
@ 2019-08-02 15:38 32% ` Ray Kinsella
  2019-08-02 15:38 28% ` [dpdk-dev] [PATCH v2 3/3] doc: updates to versioning guide for " Ray Kinsella
  2 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-02 15:38 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, hemant.agrawal

This policy change introduces major ABI versions, these are
declared every year, typically aligned with the LTS release
and are supported by subsequent releases in the following year.
This change is intended to improve ABI stabilty for those projects
consuming DPDK.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 doc/guides/contributing/abi_policy.rst | 272 +++++++++++++++++++++++----------
 doc/guides/contributing/stable.rst     |  36 +++--
 2 files changed, 213 insertions(+), 95 deletions(-)

diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
index 55bacb4..fa78622 100644
--- a/doc/guides/contributing/abi_policy.rst
+++ b/doc/guides/contributing/abi_policy.rst
@@ -1,5 +1,5 @@
 ..  SPDX-License-Identifier: BSD-3-Clause
-    Copyright 2018 The DPDK contributors
+    Copyright 2019 The DPDK contributors
 
 .. abi_api_policy:
 
@@ -9,25 +9,37 @@ DPDK ABI/API policy
 Description
 -----------
 
-This document details some methods for handling ABI management in the DPDK.
+This document details the DPDK ABI/API management policy, to ensure the
+long-term stability of the DPDK ABI/API.
 
 General Guidelines
 ------------------
 
-#. Whenever possible, ABI should be preserved
-#. ABI/API may be changed with a deprecation process
-#. The modification of symbols can generally be managed with versioning
-#. Libraries or APIs marked in ``experimental`` state may change without constraint
-#. New APIs will be marked as ``experimental`` for at least one release to allow
-   any issues found by users of the new API to be fixed quickly
-#. The addition of symbols is generally not problematic
-#. The removal of symbols generally is an ABI break and requires bumping of the
-   LIBABIVER macro
-#. Updates to the minimum hardware requirements, which drop support for hardware which
-   was previously supported, should be treated as an ABI change.
-
-What is an ABI
-~~~~~~~~~~~~~~
+#. Major ABI versions are declared every **year** and are then supported
+   for one year, typically aligned with the LTS release.
+#. ABI versioning is managed at a project level in DPDK, with the supported ABI
+   version reflected in all library's soname.
+#. The ABI should be preserved and not changed lightly. The ABI may still be
+   changed, by following the outlined deprecation process.
+#. The addition of symbols is generally not problematic. The modification of
+   symbols should be managed with ABI versioning.
+#. The removal of symbols is considered an ABI breakage, once approved these
+   will form part of the next ABI version.
+#. Libraries or APIs marked as ``experimental`` are not considered part of the
+   major ABI version and may change without constraint.
+#. Updates to the minimum hardware requirements, which drop support for hardware
+   which was previously supported, should be treated as an ABI change.
+
+.. note::
+
+   Note that in 2019 the DPDK community stated it's intention to move to ABI
+   stable releases over a number of releases. Beginning with maintaining ABI
+   stability through one year of DPDK releases starting from DPDK 19.11. This
+   policy will be reviewed in 2020 with intention of lengthening the stability
+   period.
+
+What is an ABI?
+~~~~~~~~~~~~~~~
 
 An ABI (Application Binary Interface) is the set of runtime interfaces exposed
 by a library. It is similar to an API (Application Programming Interface) but
@@ -39,30 +51,40 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
 preserved, or (when modified), done in such a way that the application is unable
 to behave improperly or in an unexpected fashion.
 
-
-ABI/API Deprecation
+The DPDK ABI policy
 -------------------
 
-The DPDK ABI policy
-~~~~~~~~~~~~~~~~~~~
+A major ABI version is declared every years, aligned with that years LTS
+release, e.g. v19.11 . This ABI version is then supported for one year by all
+subsequent releases within that time period, until the next LTS release, e.g.
+v20.11.
+
+At the declaration of a major ABI version, major version numbers encoded in
+libraries soname's are bumped to indicate the new version, with minor version
+reset to 0. An example would be ``librte_eal.so.20.3`` would become
+``librte_eal.so.21.0``.
+
+The ABI may then change multiple times, without warning, between the last major
+ABI version increment and the HEAD label of the git tree, with the condition
+that ABI compatibility with the major ABI version is preserved and therefore
+soname's do not change.
 
-ABI versions are set at the time of major release labeling, and the ABI may
-change multiple times, without warning, between the last release label and the
-HEAD label of the git tree.
+Minor versions are incremented to indicate the release of a new ABI compatible
+DPDK release, typically the DPDK quarterly releases. An example of this, might
+be that ``librte_eal.so.20.1`` would indicate the first ABI compatible DPDK
+release, following the declaration of the new major ABI version 20.0.
 
-ABI versions, once released, are available until such time as their
-deprecation has been noted in the Release Notes for at least one major release
-cycle. For example consider the case where the ABI for DPDK 2.0 has been
-shipped and then a decision is made to modify it during the development of
-DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
-release and the modification will be made available in the DPDK 2.2 release.
+ABI versions, are supported by each release until such time as the next major
+ABI version is declared. At that time, the deprecation of the previous major ABI
+version will be noted in the Release Notes with guidance on individual symbol
+depreciation and upgrade notes provided.
 
-ABI versions may be deprecated in whole or in part as needed by a given
-update.
+ABI Changes
+~~~~~~~~~~~
 
-Some ABI changes may be too significant to reasonably maintain multiple
-versions. In those cases ABI's may be updated without backward compatibility
-being provided. The requirements for doing so are:
+The ABI may still change after the declaration of a major ABI version, that is
+new APIs may be still added or existing APIs may be modified. The requirements
+for doing so are:
 
 #. At least 3 acknowledgments of the need to do so must be made on the
    dpdk.org mailing list.
@@ -71,81 +93,165 @@ being provided. The requirements for doing so are:
      no maintainer is available for the component, the tree/sub-tree maintainer
      for that component must acknowledge the ABI change instead.
 
+   - The acknowledgment of a member of the technical board, as a delegate of the
+     `technical board <https://core.dpdk.org/techboard/>`_ acknowledging the
+     need for the ABI change, is also mandatory.
+
    - It is also recommended that acknowledgments from different "areas of
      interest" be sought for each deprecation, for example: from NIC vendors,
      CPU vendors, end-users, etc.
 
-#. The changes (including an alternative map file) can be included with
-   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
-   to provide more details about oncoming changes.
-   ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
-   More preferred way to provide this information is sending the feature
-   as a separate patch and reference it in deprecation notice.
+#. Backward compatibly with the major ABI version must be maintained through
+   `<ABI versioning>`_, with forward-only compatibility offered for any ABI
+   changes that are indicated to be part of the next ABI version.
+
+   - In situations were backward compatibility is not possible, read the
+     section `<ABI  Breakages>`_.
 
-#. A full deprecation cycle, as explained above, must be made to offer
-   downstream consumers sufficient warning of the change.
+   - No backward or forward compatibility is offered for API changes marked as
+     ``experimental``, as described in the section `<Experimental APIs>`_.
 
-Note that the above process for ABI deprecation should not be undertaken
-lightly. ABI stability is extremely important for downstream consumers of the
-DPDK, especially when distributed in shared object form. Every effort should
-be made to preserve the ABI whenever possible. The ABI should only be changed
-for significant reasons, such as performance enhancements. ABI breakage due to
-changes such as reorganizing public structure fields for aesthetic or
-readability purposes should be avoided.
+#. If a newly proposed API functionally replaces an existing one, when the new
+   API becomes non-experimental, then the old one is marked with
+   ``__rte_deprecated``.
+
+    - The depreciated API should follow the notification process to be removed,
+      see `<Examples of Deprecation Notices>`_;
+
+    - At the declaration of the next major ABI version, those ABI changes then
+      become a formal part of the new ABI and the requirement to preserve ABI
+      compatibility with the last major ABI version is then dropped.
+
+    - The responsibility for removing ABI compatibility preserving code rests
+      with the original contributor of the ABI changes, then with the
+      contributor's company and then finally with the maintainer.
+
+.. note::
+
+   Note that the above process for ABI deprecation should not be undertaken
+   lightly. ABI stability is extremely important for downstream consumers of the
+   DPDK, especially when distributed in shared object form. Every effort should
+   be made to preserve the ABI whenever possible. The ABI should only be changed
+   for significant reasons, such as performance enhancements. ABI breakage due
+   to changes such as reorganizing public structure fields for aesthetic or
+   readability purposes should be avoided.
+
+.. _forward-only:
+
+.. note::
+
+   Note that forward-only compatibility is offered for those changes made
+   between major ABI versions. As a library's soname however only describes
+   compatibility with the last major ABI version, until the next major ABI
+   version is declared, these changes therefore cannot be resolved as a runtime
+   dependency through the soname. Therefore any application wishing to make use
+   of these ABI changes can only ensure that it's runtime dependencies are met
+   through Operating System package versioning.
 
 .. note::
 
    Updates to the minimum hardware requirements, which drop support for hardware
    which was previously supported, should be treated as an ABI change, and
-   follow the relevant deprecation policy procedures as above: 3 acks and
-   announcement at least one release in advance.
+   follow the relevant deprecation policy procedures as above: 3 acks, technical
+   board approval and announcement at least one release in advance.
+
+
+ABI Breakages
+^^^^^^^^^^^^^
+
+For those ABI changes that may be too significant to reasonably maintain
+multiple versions. In those cases, ABIs may be updated without backward
+compatibility being provided.
+
+The additional requirements to approve an ABI breakage, on top of those
+that described in the section `<ABI Changes>`_ are:
+
+#. ABI breaking changes (including an alternative map file) can be included with
+   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option, to provide
+   more details about oncoming changes. ``RTE_NEXT_ABI`` wrapper will be removed
+   at the declaration of the next major ABI version.
+
+#. Once approved and after the depreciation notice has been observed these
+   changes will form part of the next declared major ABI version.
+
+Examples of ABI Changes
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The following are examples of allowable ABI changes occurring between
+declarations of major ABI versions.
+
+* DPDK 19.11 release, defines the function ``rte_foo()``, and ``rte_foo()``
+  as part of the major ABI version DPDK 20.0.
+
+* DPDK 20.02 release defines a new function ``rte_foo(uint8_t bar)``, and
+  this is not a problem as long as the symbol ``rte_foo@DPDK20.0`` is
+  preserved through `<ABI versioning>`_.
+
+  - The new function may be marked with the ``__rte_experimental`` tag for a
+    number of releases, as described in the section `<Experimental APIs>`_;
+
+  - Once ``rte_foo(uint8_t bar)`` becomes non-experimental ``rte_foo()`` is then
+    declared as ``__rte_depreciated``, with an associated deprecation notice
+    provided.
+
+* DPDK 19.11 is not re-released to include ``rte_foo(uint8_t bar)``, the new
+  version of ``rte_foo`` only exists from DPDK 20.02 onwards as described in the
+  note on `forward-only`_ compatibility.
+
+* DPDK 20.02 release defines the experimental function ``__rte_experimental
+  rte_baz()``. This function may or may not exist in the DPDK 20.05 release.
+
+* An application ``dPacket`` wishes to use ``rte_foo(uint8_t bar)``, before the
+  declaration of the DPDK 21.0 major API version. The application can only
+  ensure it's runtime dependencies are met by specifying ``DPDK (>= 20.2)`` as
+  an explicit package dependency, as the soname only may only indicate the
+  supporting major ABI version.
+
+* At the release of DPDK 20.11, the function ``rte_foo(uint8_t bar)`` becomes
+  formally part of then new major ABI version DPDK 21.0 and ``rte_foo()`` may be
+  removed.
+
 
 Examples of Deprecation Notices
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The following are some examples of ABI deprecation notices which would be
 added to the Release Notes:
 
-* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
-  to be replaced with the inline function ``rte_foo()``.
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with ABI version
+  21.0, to be replaced with the inline function ``rte_foo()``.
 
 * The function ``rte_mbuf_grok()`` has been updated to include a new parameter
-  in version 2.0. Backwards compatibility will be maintained for this function
-  until the release of version 2.1
+  in version 20.2. Backwards compatibility will be maintained for this function
+  until the release of the new DPDK major ABI version 21.0, in DPDK version
+  20.11.
 
-* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+* The members of ``struct rte_foo`` have been reorganized in DPDK 20.02 for
   performance reasons. Existing binary applications will have backwards
-  compatibility in release 2.0, while newly built binaries will need to
-  reference the new structure variant ``struct rte_foo2``. Compatibility will
-  be removed in release 2.2, and all applications will require updating and
+  compatibility in release 20.02, while newly built binaries will need to
+  reference the new structure variant ``struct rte_foo2``. Compatibility will be
+  removed in release 20.11, and all applications will require updating and
   rebuilding to the new structure at that time, which will be renamed to the
   original ``struct rte_foo``.
 
 * Significant ABI changes are planned for the ``librte_dostuff`` library. The
-  upcoming release 2.0 will not contain these changes, but release 2.1 will,
+  upcoming release 20.02 will not contain these changes, but release 20.11 will,
   and no backwards compatibility is planned due to the extensive nature of
-  these changes. Binaries using this library built prior to version 2.1 will
+  these changes. Binaries using this library built prior to ABI version 21 will
   require updating and recompilation.
 
-New API replacing previous one
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Experimental
+------------
 
-If a new API proposed functionally replaces an existing one, when the new API
-becomes non-experimental then the old one is marked with ``__rte_deprecated``.
-Deprecated APIs are removed completely just after the next LTS.
+APIs
+~~~~
 
-Reminder that old API should follow deprecation process to be removed.
-
-
-Experimental APIs
------------------
-
-APIs marked as ``experimental`` are not considered part of the ABI and may
-change without warning at any time.  Since changes to APIs are most likely
-immediately after their introduction, as users begin to take advantage of
-those new APIs and start finding issues with them, new DPDK APIs will be
-automatically marked as ``experimental`` to allow for a period of stabilization
-before they become part of a tracked ABI.
+APIs marked as ``experimental`` are not considered part of an ABI version and
+may change without warning at any time. Since changes to APIs are most likely
+immediately after their introduction, as users begin to take advantage of those
+new APIs and start finding issues with them, new DPDK APIs will be automatically
+marked as ``experimental`` to allow for a period of stabilization before they
+become part of a tracked ABI version.
 
 Note that marking an API as experimental is a multi step process.
 To mark an API as experimental, the symbols which are desired to be exported
@@ -167,3 +273,11 @@ For removing the experimental tag associated with an API, deprecation notice
 is not required. Though, an API should remain in experimental state for at least
 one release. Thereafter, normal process of posting patch for review to mailing
 list can be followed.
+
+Libraries
+~~~~~~~~~
+
+Libraries marked as ``experimental`` are entirely not considered part of an ABI
+version, and may change without warning at any time. Experimental libraries
+always have a major version of ``0`` to indicate they exist outside of ABI
+versioning, with minor version incremented with each ABI change to library.
diff --git a/doc/guides/contributing/stable.rst b/doc/guides/contributing/stable.rst
index 6a5eee9..db783c7 100644
--- a/doc/guides/contributing/stable.rst
+++ b/doc/guides/contributing/stable.rst
@@ -53,6 +53,9 @@ year's November (X.11) release will be maintained as an LTS for 2 years.
 After the X.11 release, an LTS branch will be created for it at
 http://git.dpdk.org/dpdk-stable where bugfixes will be backported to.
 
+A LTS release may align with the declaration of a new major ABI version,
+please read the `<DPDK ABI/API policy>`_ for more information.
+
 It is anticipated that there will be at least 4 releases per year of the LTS
 or approximately 1 every 3 months. However, the cadence can be shorter or
 longer depending on the number and criticality of the backported
@@ -68,10 +71,13 @@ point the LTS branch will no longer be maintained with no further releases.
 What changes should be backported
 ---------------------------------
 
-Backporting should be limited to bug fixes. All patches accepted on the master
-branch with a Fixes: tag should be backported to the relevant stable/LTS
-branches, unless the submitter indicates otherwise. If there are exceptions,
-they will be discussed on the mailing lists.
+Backporting is a naturally conservative activity, and therefore should only
+include bug fixes and support for new hardware, were adding support does not
+necessitate DPDK ABI/API changes.
+
+All patches accepted on the master branch with a Fixes: tag should be backported
+to the relevant stable/LTS branches, unless the submitter indicates otherwise.
+If there are exceptions, they will be discussed on the mailing lists.
 
 Fixes suitable for backport should have a ``Cc: stable@dpdk.org`` tag in the
 commit message body as follows::
@@ -86,13 +92,18 @@ commit message body as follows::
      Signed-off-by: Alex Smith <alex.smith@example.com>
 
 
-Fixes not suitable for backport should not include the ``Cc: stable@dpdk.org`` tag.
+Fixes not suitable for backport should not include the ``Cc: stable@dpdk.org``
+tag.
 
-Features should not be backported to stable releases. It may be acceptable, in
-limited cases, to back port features for the LTS release where:
+New features, with the exception of new hardware support, should not be
+backported to stable releases. In the case of new hardware support or any other
+exceptional circumstances limited backporting maybe permitted to the LTS release
+where:
 
-* There is a justifiable use case (for example a new PMD).
-* The change is non-invasive.
+* There is a justifiable use case, for example the change is required to support
+  a new platform or device (for example a new PMD).
+* The change is ABI/API preserving, it does not present an obvious "new feature"
+  to end consumer.
 * The work of preparing the backport is done by the proposer.
 * There is support within the community.
 
@@ -119,10 +130,3 @@ A Stable Release will be released by:
   list.
 
 Stable releases are available on the `dpdk.org download page <http://core.dpdk.org/download/>`_.
-
-
-ABI
----
-
-The Stable Release should not be seen as a way of breaking or circumventing
-the DPDK ABI policy.
-- 
2.7.4


^ permalink raw reply	[relevance 32%]

* [dpdk-dev] [PATCH v2 1/3] doc: separate versioning.rst into version and policy
  2019-08-02 15:38 11% [dpdk-dev] [PATCH v2 0/3] doc: changes to abi policy introducing major abi versions Ray Kinsella
@ 2019-08-02 15:38 13% ` Ray Kinsella
  2019-08-02 15:38 32% ` [dpdk-dev] [PATCH v2 2/3] doc: changes to abi policy introducing major abi versions Ray Kinsella
  2019-08-02 15:38 28% ` [dpdk-dev] [PATCH v2 3/3] doc: updates to versioning guide for " Ray Kinsella
  2 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-08-02 15:38 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, hemant.agrawal

Separate versioning.rst into abi versioning and abi policy guidance, in
preparation for adding more detail to the abi policy.

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 doc/guides/contributing/abi_policy.rst     | 169 +++++++++
 doc/guides/contributing/abi_versioning.rst | 427 +++++++++++++++++++++
 doc/guides/contributing/index.rst          |   3 +-
 doc/guides/contributing/versioning.rst     | 591 -----------------------------
 4 files changed, 598 insertions(+), 592 deletions(-)
 create mode 100644 doc/guides/contributing/abi_policy.rst
 create mode 100644 doc/guides/contributing/abi_versioning.rst
 delete mode 100644 doc/guides/contributing/versioning.rst

diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
new file mode 100644
index 0000000..55bacb4
--- /dev/null
+++ b/doc/guides/contributing/abi_policy.rst
@@ -0,0 +1,169 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
+.. abi_api_policy:
+
+DPDK ABI/API policy
+===================
+
+Description
+-----------
+
+This document details some methods for handling ABI management in the DPDK.
+
+General Guidelines
+------------------
+
+#. Whenever possible, ABI should be preserved
+#. ABI/API may be changed with a deprecation process
+#. The modification of symbols can generally be managed with versioning
+#. Libraries or APIs marked in ``experimental`` state may change without constraint
+#. New APIs will be marked as ``experimental`` for at least one release to allow
+   any issues found by users of the new API to be fixed quickly
+#. The addition of symbols is generally not problematic
+#. The removal of symbols generally is an ABI break and requires bumping of the
+   LIBABIVER macro
+#. Updates to the minimum hardware requirements, which drop support for hardware which
+   was previously supported, should be treated as an ABI change.
+
+What is an ABI
+~~~~~~~~~~~~~~
+
+An ABI (Application Binary Interface) is the set of runtime interfaces exposed
+by a library. It is similar to an API (Application Programming Interface) but
+is the result of compilation.  It is also effectively cloned when applications
+link to dynamic libraries.  That is to say when an application is compiled to
+link against dynamic libraries, it is assumed that the ABI remains constant
+between the time the application is compiled/linked, and the time that it runs.
+Therefore, in the case of dynamic linking, it is critical that an ABI is
+preserved, or (when modified), done in such a way that the application is unable
+to behave improperly or in an unexpected fashion.
+
+
+ABI/API Deprecation
+-------------------
+
+The DPDK ABI policy
+~~~~~~~~~~~~~~~~~~~
+
+ABI versions are set at the time of major release labeling, and the ABI may
+change multiple times, without warning, between the last release label and the
+HEAD label of the git tree.
+
+ABI versions, once released, are available until such time as their
+deprecation has been noted in the Release Notes for at least one major release
+cycle. For example consider the case where the ABI for DPDK 2.0 has been
+shipped and then a decision is made to modify it during the development of
+DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
+release and the modification will be made available in the DPDK 2.2 release.
+
+ABI versions may be deprecated in whole or in part as needed by a given
+update.
+
+Some ABI changes may be too significant to reasonably maintain multiple
+versions. In those cases ABI's may be updated without backward compatibility
+being provided. The requirements for doing so are:
+
+#. At least 3 acknowledgments of the need to do so must be made on the
+   dpdk.org mailing list.
+
+   - The acknowledgment of the maintainer of the component is mandatory, or if
+     no maintainer is available for the component, the tree/sub-tree maintainer
+     for that component must acknowledge the ABI change instead.
+
+   - It is also recommended that acknowledgments from different "areas of
+     interest" be sought for each deprecation, for example: from NIC vendors,
+     CPU vendors, end-users, etc.
+
+#. The changes (including an alternative map file) can be included with
+   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
+   to provide more details about oncoming changes.
+   ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
+   More preferred way to provide this information is sending the feature
+   as a separate patch and reference it in deprecation notice.
+
+#. A full deprecation cycle, as explained above, must be made to offer
+   downstream consumers sufficient warning of the change.
+
+Note that the above process for ABI deprecation should not be undertaken
+lightly. ABI stability is extremely important for downstream consumers of the
+DPDK, especially when distributed in shared object form. Every effort should
+be made to preserve the ABI whenever possible. The ABI should only be changed
+for significant reasons, such as performance enhancements. ABI breakage due to
+changes such as reorganizing public structure fields for aesthetic or
+readability purposes should be avoided.
+
+.. note::
+
+   Updates to the minimum hardware requirements, which drop support for hardware
+   which was previously supported, should be treated as an ABI change, and
+   follow the relevant deprecation policy procedures as above: 3 acks and
+   announcement at least one release in advance.
+
+Examples of Deprecation Notices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+  to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+  in version 2.0. Backwards compatibility will be maintained for this function
+  until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+  performance reasons. Existing binary applications will have backwards
+  compatibility in release 2.0, while newly built binaries will need to
+  reference the new structure variant ``struct rte_foo2``. Compatibility will
+  be removed in release 2.2, and all applications will require updating and
+  rebuilding to the new structure at that time, which will be renamed to the
+  original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+  upcoming release 2.0 will not contain these changes, but release 2.1 will,
+  and no backwards compatibility is planned due to the extensive nature of
+  these changes. Binaries using this library built prior to version 2.1 will
+  require updating and recompilation.
+
+New API replacing previous one
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If a new API proposed functionally replaces an existing one, when the new API
+becomes non-experimental then the old one is marked with ``__rte_deprecated``.
+Deprecated APIs are removed completely just after the next LTS.
+
+Reminder that old API should follow deprecation process to be removed.
+
+
+Experimental APIs
+-----------------
+
+APIs marked as ``experimental`` are not considered part of the ABI and may
+change without warning at any time.  Since changes to APIs are most likely
+immediately after their introduction, as users begin to take advantage of
+those new APIs and start finding issues with them, new DPDK APIs will be
+automatically marked as ``experimental`` to allow for a period of stabilization
+before they become part of a tracked ABI.
+
+Note that marking an API as experimental is a multi step process.
+To mark an API as experimental, the symbols which are desired to be exported
+must be placed in an EXPERIMENTAL version block in the corresponding libraries'
+version map script.
+Secondly, the corresponding prototypes of those exported functions (in the
+development header files), must be marked with the ``__rte_experimental`` tag
+(see ``rte_compat.h``).
+The DPDK build makefiles perform a check to ensure that the map file and the
+C code reflect the same list of symbols.
+This check can be circumvented by defining ``ALLOW_EXPERIMENTAL_API``
+during compilation in the corresponding library Makefile.
+
+In addition to tagging the code with ``__rte_experimental``,
+the doxygen markup must also contain the EXPERIMENTAL string,
+and the MAINTAINERS file should note the EXPERIMENTAL libraries.
+
+For removing the experimental tag associated with an API, deprecation notice
+is not required. Though, an API should remain in experimental state for at least
+one release. Thereafter, normal process of posting patch for review to mailing
+list can be followed.
diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
new file mode 100644
index 0000000..53e6ac0
--- /dev/null
+++ b/doc/guides/contributing/abi_versioning.rst
@@ -0,0 +1,427 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2018 The DPDK contributors
+
+.. library_versioning:
+
+Library versioning
+------------------
+
+Downstreams might want to provide different DPDK releases at the same time to
+support multiple consumers of DPDK linked against older and newer sonames.
+
+Also due to the interdependencies that DPDK libraries can have applications
+might end up with an executable space in which multiple versions of a library
+are mapped by ld.so.
+
+Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
+depending on LibA.
+
+.. note::
+
+    Application
+    \-> LibA.old
+    \-> LibB.new -> LibA.new
+
+That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
+If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
+library - versions defined in the libraries ``LIBABIVER``.
+An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
+``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
+
+
+ABI versioning
+--------------
+
+Versioning Macros
+~~~~~~~~~~~~~~~~~
+
+When a symbol is exported from a library to provide an API, it also provides a
+calling convention (ABI) that is embodied in its name, return type and
+arguments. Occasionally that function may need to change to accommodate new
+functionality or behavior. When that occurs, it is desirable to allow for
+backward compatibility for a time with older binaries that are dynamically
+linked to the DPDK.
+
+To support backward compatibility the ``rte_compat.h``
+header file provides macros to use when updating exported functions. These
+macros are used in conjunction with the ``rte_<library>_version.map`` file for
+a given library to allow multiple versions of a symbol to exist in a shared
+library so that older binaries need not be immediately recompiled.
+
+The macros exported are:
+
+* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
+  versioned symbol ``b@DPDK_n`` to the internal function ``b_e``.
+
+* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
+  the linker to bind references to symbol ``b`` to the internal symbol
+  ``b_e``.
+
+* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
+  fully qualified function ``p``, so that if a symbol becomes versioned, it
+  can still be mapped back to the public symbol name.
+
+Examples of ABI Macro use
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Updating a public API
+_____________________
+
+Assume we have a function as follows
+
+.. code-block:: c
+
+ /*
+  * Create an acl context object for apps to
+  * manipulate
+  */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param)
+ {
+        ...
+ }
+
+
+Assume that struct rte_acl_ctx is a private structure, and that a developer
+wishes to enhance the acl api so that a debugging flag can be enabled on a
+per-context basis.  This requires an addition to the structure (which, being
+private, is safe), but it also requires modifying the code as follows
+
+.. code-block:: c
+
+ /*
+  * Create an acl context object for apps to
+  * manipulate
+  */
+ struct rte_acl_ctx *
+ rte_acl_create(const struct rte_acl_param *param, int debug)
+ {
+        ...
+ }
+
+
+Note also that, being a public function, the header file prototype must also be
+changed, as must all the call sites, to reflect the new ABI footprint.  We will
+maintain previous ABI versions that are accessible only to previously compiled
+binaries
+
+The addition of a parameter to the function is ABI breaking as the function is
+public, and existing application may use it in its current form.  However, the
+compatibility macros in DPDK allow a developer to use symbol versioning so that
+multiple functions can be mapped to the same public symbol based on when an
+application was linked to it.  To see how this is done, we start with the
+requisite libraries version map file.  Initially the version map file for the
+acl library looks like this
+
+.. code-block:: none
+
+   DPDK_2.0 {
+        global:
+
+        rte_acl_add_rules;
+        rte_acl_build;
+        rte_acl_classify;
+        rte_acl_classify_alg;
+        rte_acl_classify_scalar;
+        rte_acl_create;
+        rte_acl_dump;
+        rte_acl_find_existing;
+        rte_acl_free;
+        rte_acl_ipv4vlan_add_rules;
+        rte_acl_ipv4vlan_build;
+        rte_acl_list_dump;
+        rte_acl_reset;
+        rte_acl_reset_rules;
+        rte_acl_set_ctx_classify;
+
+        local: *;
+   };
+
+This file needs to be modified as follows
+
+.. code-block:: none
+
+   DPDK_2.0 {
+        global:
+
+        rte_acl_add_rules;
+        rte_acl_build;
+        rte_acl_classify;
+        rte_acl_classify_alg;
+        rte_acl_classify_scalar;
+        rte_acl_create;
+        rte_acl_dump;
+        rte_acl_find_existing;
+        rte_acl_free;
+        rte_acl_ipv4vlan_add_rules;
+        rte_acl_ipv4vlan_build;
+        rte_acl_list_dump;
+        rte_acl_reset;
+        rte_acl_reset_rules;
+        rte_acl_set_ctx_classify;
+
+        local: *;
+   };
+
+   DPDK_2.1 {
+        global:
+        rte_acl_create;
+
+   } DPDK_2.0;
+
+The addition of the new block tells the linker that a new version node is
+available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
+symbols from the DPDK_2.0 node.  This list is directly translated into a list of
+exported symbols when DPDK is compiled as a shared library
+
+Next, we need to specify in the code which function map to the rte_acl_create
+symbol at which versions.  First, at the site of the initial symbol definition,
+we need to update the function so that it is uniquely named, and not in conflict
+with the public symbol name
+
+.. code-block:: c
+
+  struct rte_acl_ctx *
+ -rte_acl_create(const struct rte_acl_param *param)
+ +rte_acl_create_v20(const struct rte_acl_param *param)
+ {
+        size_t sz;
+        struct rte_acl_ctx *ctx;
+        ...
+
+Note that the base name of the symbol was kept intact, as this is conducive to
+the macros used for versioning symbols.  That is our next step, mapping this new
+symbol name to the initial symbol name at version node 2.0.  Immediately after
+the function, we add this line of code
+
+.. code-block:: c
+
+   VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+Remembering to also add the rte_compat.h header to the requisite c file where
+these changes are being made.  The above macro instructs the linker to create a
+new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
+builds, but now points to the above newly named function.  We have now mapped
+the original rte_acl_create symbol to the original function (but with a new
+name)
+
+Next, we need to create the 2.1 version of the symbol.  We create a new function
+name, with a different suffix, and  implement it appropriately
+
+.. code-block:: c
+
+   struct rte_acl_ctx *
+   rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+   {
+        struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
+
+        ctx->debug = debug;
+
+        return ctx;
+   }
+
+This code serves as our new API call.  Its the same as our old call, but adds
+the new parameter in place.  Next we need to map this function to the symbol
+``rte_acl_create@DPDK_2.1``.  To do this, we modify the public prototype of the call
+in the header file, adding the macro there to inform all including applications,
+that on re-link, the default rte_acl_create symbol should point to this
+function.  Note that we could do this by simply naming the function above
+rte_acl_create, and the linker would chose the most recent version tag to apply
+in the version script, but we can also do this in the header file
+
+.. code-block:: c
+
+   struct rte_acl_ctx *
+   -rte_acl_create(const struct rte_acl_param *param);
+   +rte_acl_create(const struct rte_acl_param *param, int debug);
+   +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
+header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
+version node to it.  This method is more explicit and flexible than just
+re-implementing the exact symbol name, and allows for other features (such as
+linking to the old symbol version by default, when the new ABI is to be opt-in
+for a period.
+
+One last thing we need to do.  Note that we've taken what was a public symbol,
+and duplicated it into two uniquely and differently named symbols.  We've then
+mapped each of those back to the public symbol ``rte_acl_create`` with different
+version tags.  This only applies to dynamic linking, as static linking has no
+notion of versioning.  That leaves this code in a position of no longer having a
+symbol simply named ``rte_acl_create`` and a static build will fail on that
+missing symbol.
+
+To correct this, we can simply map a function of our choosing back to the public
+symbol in the static build with the ``MAP_STATIC_SYMBOL`` macro.  Generally the
+assumption is that the most recent version of the symbol is the one you want to
+map.  So, back in the C file where, immediately after ``rte_acl_create_v21`` is
+defined, we add this
+
+.. code-block:: c
+
+   struct rte_acl_ctx *
+   rte_acl_create_v21(const struct rte_acl_param *param, int debug)
+   {
+        ...
+   }
+   MAP_STATIC_SYMBOL(struct rte_acl_ctx *rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v21);
+
+That tells the compiler that, when building a static library, any calls to the
+symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
+
+That's it, on the next shared library rebuild, there will be two versions of
+rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
+and a new DPDK_2.1 version, used by future built applications.
+
+
+Deprecating part of a public API
+________________________________
+
+Lets assume that you've done the above update, and after a few releases have
+passed you decide you would like to retire the old version of the function.
+After having gone through the ABI deprecation announcement process, removal is
+easy.  Start by removing the symbol from the requisite version map file:
+
+.. code-block:: none
+
+   DPDK_2.0 {
+        global:
+
+        rte_acl_add_rules;
+        rte_acl_build;
+        rte_acl_classify;
+        rte_acl_classify_alg;
+        rte_acl_classify_scalar;
+        rte_acl_dump;
+ -      rte_acl_create
+        rte_acl_find_existing;
+        rte_acl_free;
+        rte_acl_ipv4vlan_add_rules;
+        rte_acl_ipv4vlan_build;
+        rte_acl_list_dump;
+        rte_acl_reset;
+        rte_acl_reset_rules;
+        rte_acl_set_ctx_classify;
+
+        local: *;
+   };
+
+   DPDK_2.1 {
+        global:
+        rte_acl_create;
+   } DPDK_2.0;
+
+
+Next remove the corresponding versioned export.
+
+.. code-block:: c
+
+ -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
+
+
+Note that the internal function definition could also be removed, but its used
+in our example by the newer version _v21, so we leave it in place.  This is a
+coding style choice.
+
+Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
+indicate to applications doing dynamic linking that this is a later, and
+possibly incompatible library version:
+
+.. code-block:: c
+
+   -LIBABIVER := 1
+   +LIBABIVER := 2
+
+Deprecating an entire ABI version
+_________________________________
+
+While removing a symbol from and ABI may be useful, it is often more practical
+to remove an entire version node at once.  If a version node completely
+specifies an API, then removing part of it, typically makes it incomplete.  In
+those cases it is better to remove the entire node
+
+To do this, start by modifying the version map file, such that all symbols from
+the node to be removed are merged into the next node in the map
+
+In the case of our map above, it would transform to look as follows
+
+.. code-block:: none
+
+   DPDK_2.1 {
+        global:
+
+        rte_acl_add_rules;
+        rte_acl_build;
+        rte_acl_classify;
+        rte_acl_classify_alg;
+        rte_acl_classify_scalar;
+        rte_acl_dump;
+        rte_acl_create
+        rte_acl_find_existing;
+        rte_acl_free;
+        rte_acl_ipv4vlan_add_rules;
+        rte_acl_ipv4vlan_build;
+        rte_acl_list_dump;
+        rte_acl_reset;
+        rte_acl_reset_rules;
+        rte_acl_set_ctx_classify;
+
+        local: *;
+ };
+
+Then any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be
+updated to point to the new version node in any header files for all affected
+symbols.
+
+.. code-block:: c
+
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
+
+Lastly, any VERSION_SYMBOL macros that point to the old version node should be
+removed, taking care to keep, where need old code in place to support newer
+versions of the symbol.
+
+
+Running the ABI Validator
+-------------------------
+
+The ``devtools`` directory in the DPDK source tree contains a utility program,
+``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
+Compliance Checker
+<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
+
+This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
+utilities which can be installed via a package manager. For example::
+
+   sudo yum install abi-compliance-checker
+   sudo yum install abi-dumper
+
+The syntax of the ``validate-abi.sh`` utility is::
+
+   ./devtools/validate-abi.sh <REV1> <REV2>
+
+Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
+https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
+on the local repo.
+
+For example::
+
+   # Check between the previous and latest commit:
+   ./devtools/validate-abi.sh HEAD~1 HEAD
+
+   # Check on a specific compilation target:
+   ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
+
+   # Check between two tags:
+   ./devtools/validate-abi.sh v2.0.0 v2.1.0
+
+   # Check between git master and local topic-branch "vhost-hacking":
+   ./devtools/validate-abi.sh master vhost-hacking
+
+After the validation script completes (it can take a while since it need to
+compile both tags) it will create compatibility reports in the
+``./abi-check/compat_report`` directory. Listed incompatibilities can be found
+as follows::
+
+  grep -lr Incompatible abi-check/compat_reports/
diff --git a/doc/guides/contributing/index.rst b/doc/guides/contributing/index.rst
index e2608d3..2fefd91 100644
--- a/doc/guides/contributing/index.rst
+++ b/doc/guides/contributing/index.rst
@@ -10,7 +10,8 @@ Contributor's Guidelines
 
     coding_style
     design
-    versioning
+    abi_policy
+    abi_versioning
     documentation
     patches
     vulnerability
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
deleted file mode 100644
index 3ab2c43..0000000
--- a/doc/guides/contributing/versioning.rst
+++ /dev/null
@@ -1,591 +0,0 @@
-..  SPDX-License-Identifier: BSD-3-Clause
-    Copyright 2018 The DPDK contributors
-
-DPDK ABI/API policy
-===================
-
-Description
------------
-
-This document details some methods for handling ABI management in the DPDK.
-
-General Guidelines
-------------------
-
-#. Whenever possible, ABI should be preserved
-#. ABI/API may be changed with a deprecation process
-#. The modification of symbols can generally be managed with versioning
-#. Libraries or APIs marked in ``experimental`` state may change without constraint
-#. New APIs will be marked as ``experimental`` for at least one release to allow
-   any issues found by users of the new API to be fixed quickly
-#. The addition of symbols is generally not problematic
-#. The removal of symbols generally is an ABI break and requires bumping of the
-   LIBABIVER macro
-#. Updates to the minimum hardware requirements, which drop support for hardware which
-   was previously supported, should be treated as an ABI change.
-
-What is an ABI
-~~~~~~~~~~~~~~
-
-An ABI (Application Binary Interface) is the set of runtime interfaces exposed
-by a library. It is similar to an API (Application Programming Interface) but
-is the result of compilation.  It is also effectively cloned when applications
-link to dynamic libraries.  That is to say when an application is compiled to
-link against dynamic libraries, it is assumed that the ABI remains constant
-between the time the application is compiled/linked, and the time that it runs.
-Therefore, in the case of dynamic linking, it is critical that an ABI is
-preserved, or (when modified), done in such a way that the application is unable
-to behave improperly or in an unexpected fashion.
-
-
-ABI/API Deprecation
--------------------
-
-The DPDK ABI policy
-~~~~~~~~~~~~~~~~~~~
-
-ABI versions are set at the time of major release labeling, and the ABI may
-change multiple times, without warning, between the last release label and the
-HEAD label of the git tree.
-
-ABI versions, once released, are available until such time as their
-deprecation has been noted in the Release Notes for at least one major release
-cycle. For example consider the case where the ABI for DPDK 2.0 has been
-shipped and then a decision is made to modify it during the development of
-DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
-release and the modification will be made available in the DPDK 2.2 release.
-
-ABI versions may be deprecated in whole or in part as needed by a given
-update.
-
-Some ABI changes may be too significant to reasonably maintain multiple
-versions. In those cases ABI's may be updated without backward compatibility
-being provided. The requirements for doing so are:
-
-#. At least 3 acknowledgments of the need to do so must be made on the
-   dpdk.org mailing list.
-
-   - The acknowledgment of the maintainer of the component is mandatory, or if
-     no maintainer is available for the component, the tree/sub-tree maintainer
-     for that component must acknowledge the ABI change instead.
-
-   - It is also recommended that acknowledgments from different "areas of
-     interest" be sought for each deprecation, for example: from NIC vendors,
-     CPU vendors, end-users, etc.
-
-#. The changes (including an alternative map file) can be included with
-   deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
-   to provide more details about oncoming changes.
-   ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
-   More preferred way to provide this information is sending the feature
-   as a separate patch and reference it in deprecation notice.
-
-#. A full deprecation cycle, as explained above, must be made to offer
-   downstream consumers sufficient warning of the change.
-
-Note that the above process for ABI deprecation should not be undertaken
-lightly. ABI stability is extremely important for downstream consumers of the
-DPDK, especially when distributed in shared object form. Every effort should
-be made to preserve the ABI whenever possible. The ABI should only be changed
-for significant reasons, such as performance enhancements. ABI breakage due to
-changes such as reorganizing public structure fields for aesthetic or
-readability purposes should be avoided.
-
-.. note::
-
-   Updates to the minimum hardware requirements, which drop support for hardware
-   which was previously supported, should be treated as an ABI change, and
-   follow the relevant deprecation policy procedures as above: 3 acks and
-   announcement at least one release in advance.
-
-Examples of Deprecation Notices
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following are some examples of ABI deprecation notices which would be
-added to the Release Notes:
-
-* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
-  to be replaced with the inline function ``rte_foo()``.
-
-* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
-  in version 2.0. Backwards compatibility will be maintained for this function
-  until the release of version 2.1
-
-* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
-  performance reasons. Existing binary applications will have backwards
-  compatibility in release 2.0, while newly built binaries will need to
-  reference the new structure variant ``struct rte_foo2``. Compatibility will
-  be removed in release 2.2, and all applications will require updating and
-  rebuilding to the new structure at that time, which will be renamed to the
-  original ``struct rte_foo``.
-
-* Significant ABI changes are planned for the ``librte_dostuff`` library. The
-  upcoming release 2.0 will not contain these changes, but release 2.1 will,
-  and no backwards compatibility is planned due to the extensive nature of
-  these changes. Binaries using this library built prior to version 2.1 will
-  require updating and recompilation.
-
-New API replacing previous one
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If a new API proposed functionally replaces an existing one, when the new API
-becomes non-experimental then the old one is marked with ``__rte_deprecated``.
-Deprecated APIs are removed completely just after the next LTS.
-
-Reminder that old API should follow deprecation process to be removed.
-
-
-Experimental APIs
------------------
-
-APIs marked as ``experimental`` are not considered part of the ABI and may
-change without warning at any time.  Since changes to APIs are most likely
-immediately after their introduction, as users begin to take advantage of
-those new APIs and start finding issues with them, new DPDK APIs will be
-automatically marked as ``experimental`` to allow for a period of stabilization
-before they become part of a tracked ABI.
-
-Note that marking an API as experimental is a multi step process.
-To mark an API as experimental, the symbols which are desired to be exported
-must be placed in an EXPERIMENTAL version block in the corresponding libraries'
-version map script.
-Secondly, the corresponding prototypes of those exported functions (in the
-development header files), must be marked with the ``__rte_experimental`` tag
-(see ``rte_compat.h``).
-The DPDK build makefiles perform a check to ensure that the map file and the
-C code reflect the same list of symbols.
-This check can be circumvented by defining ``ALLOW_EXPERIMENTAL_API``
-during compilation in the corresponding library Makefile.
-
-In addition to tagging the code with ``__rte_experimental``,
-the doxygen markup must also contain the EXPERIMENTAL string,
-and the MAINTAINERS file should note the EXPERIMENTAL libraries.
-
-For removing the experimental tag associated with an API, deprecation notice
-is not required. Though, an API should remain in experimental state for at least
-one release. Thereafter, normal process of posting patch for review to mailing
-list can be followed.
-
-
-Library versioning
-------------------
-
-Downstreams might want to provide different DPDK releases at the same time to
-support multiple consumers of DPDK linked against older and newer sonames.
-
-Also due to the interdependencies that DPDK libraries can have applications
-might end up with an executable space in which multiple versions of a library
-are mapped by ld.so.
-
-Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
-depending on LibA.
-
-.. note::
-
-    Application
-    \-> LibA.old
-    \-> LibB.new -> LibA.new
-
-That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
-If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
-library - versions defined in the libraries ``LIBABIVER``.
-An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
-``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
-
-
-ABI versioning
---------------
-
-Versioning Macros
-~~~~~~~~~~~~~~~~~
-
-When a symbol is exported from a library to provide an API, it also provides a
-calling convention (ABI) that is embodied in its name, return type and
-arguments. Occasionally that function may need to change to accommodate new
-functionality or behavior. When that occurs, it is desirable to allow for
-backward compatibility for a time with older binaries that are dynamically
-linked to the DPDK.
-
-To support backward compatibility the ``rte_compat.h``
-header file provides macros to use when updating exported functions. These
-macros are used in conjunction with the ``rte_<library>_version.map`` file for
-a given library to allow multiple versions of a symbol to exist in a shared
-library so that older binaries need not be immediately recompiled.
-
-The macros exported are:
-
-* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
-  versioned symbol ``b@DPDK_n`` to the internal function ``b_e``.
-
-* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
-  the linker to bind references to symbol ``b`` to the internal symbol
-  ``b_e``.
-
-* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
-  fully qualified function ``p``, so that if a symbol becomes versioned, it
-  can still be mapped back to the public symbol name.
-
-Examples of ABI Macro use
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Updating a public API
-_____________________
-
-Assume we have a function as follows
-
-.. code-block:: c
-
- /*
-  * Create an acl context object for apps to
-  * manipulate
-  */
- struct rte_acl_ctx *
- rte_acl_create(const struct rte_acl_param *param)
- {
-        ...
- }
-
-
-Assume that struct rte_acl_ctx is a private structure, and that a developer
-wishes to enhance the acl api so that a debugging flag can be enabled on a
-per-context basis.  This requires an addition to the structure (which, being
-private, is safe), but it also requires modifying the code as follows
-
-.. code-block:: c
-
- /*
-  * Create an acl context object for apps to
-  * manipulate
-  */
- struct rte_acl_ctx *
- rte_acl_create(const struct rte_acl_param *param, int debug)
- {
-        ...
- }
-
-
-Note also that, being a public function, the header file prototype must also be
-changed, as must all the call sites, to reflect the new ABI footprint.  We will
-maintain previous ABI versions that are accessible only to previously compiled
-binaries
-
-The addition of a parameter to the function is ABI breaking as the function is
-public, and existing application may use it in its current form.  However, the
-compatibility macros in DPDK allow a developer to use symbol versioning so that
-multiple functions can be mapped to the same public symbol based on when an
-application was linked to it.  To see how this is done, we start with the
-requisite libraries version map file.  Initially the version map file for the
-acl library looks like this
-
-.. code-block:: none
-
-   DPDK_2.0 {
-        global:
-
-        rte_acl_add_rules;
-        rte_acl_build;
-        rte_acl_classify;
-        rte_acl_classify_alg;
-        rte_acl_classify_scalar;
-        rte_acl_create;
-        rte_acl_dump;
-        rte_acl_find_existing;
-        rte_acl_free;
-        rte_acl_ipv4vlan_add_rules;
-        rte_acl_ipv4vlan_build;
-        rte_acl_list_dump;
-        rte_acl_reset;
-        rte_acl_reset_rules;
-        rte_acl_set_ctx_classify;
-
-        local: *;
-   };
-
-This file needs to be modified as follows
-
-.. code-block:: none
-
-   DPDK_2.0 {
-        global:
-
-        rte_acl_add_rules;
-        rte_acl_build;
-        rte_acl_classify;
-        rte_acl_classify_alg;
-        rte_acl_classify_scalar;
-        rte_acl_create;
-        rte_acl_dump;
-        rte_acl_find_existing;
-        rte_acl_free;
-        rte_acl_ipv4vlan_add_rules;
-        rte_acl_ipv4vlan_build;
-        rte_acl_list_dump;
-        rte_acl_reset;
-        rte_acl_reset_rules;
-        rte_acl_set_ctx_classify;
-
-        local: *;
-   };
-
-   DPDK_2.1 {
-        global:
-        rte_acl_create;
-
-   } DPDK_2.0;
-
-The addition of the new block tells the linker that a new version node is
-available (DPDK_2.1), which contains the symbol rte_acl_create, and inherits the
-symbols from the DPDK_2.0 node.  This list is directly translated into a list of
-exported symbols when DPDK is compiled as a shared library
-
-Next, we need to specify in the code which function map to the rte_acl_create
-symbol at which versions.  First, at the site of the initial symbol definition,
-we need to update the function so that it is uniquely named, and not in conflict
-with the public symbol name
-
-.. code-block:: c
-
-  struct rte_acl_ctx *
- -rte_acl_create(const struct rte_acl_param *param)
- +rte_acl_create_v20(const struct rte_acl_param *param)
- {
-        size_t sz;
-        struct rte_acl_ctx *ctx;
-        ...
-
-Note that the base name of the symbol was kept intact, as this is conducive to
-the macros used for versioning symbols.  That is our next step, mapping this new
-symbol name to the initial symbol name at version node 2.0.  Immediately after
-the function, we add this line of code
-
-.. code-block:: c
-
-   VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
-
-Remembering to also add the rte_compat.h header to the requisite c file where
-these changes are being made.  The above macro instructs the linker to create a
-new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
-builds, but now points to the above newly named function.  We have now mapped
-the original rte_acl_create symbol to the original function (but with a new
-name)
-
-Next, we need to create the 2.1 version of the symbol.  We create a new function
-name, with a different suffix, and  implement it appropriately
-
-.. code-block:: c
-
-   struct rte_acl_ctx *
-   rte_acl_create_v21(const struct rte_acl_param *param, int debug);
-   {
-        struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
-
-        ctx->debug = debug;
-
-        return ctx;
-   }
-
-This code serves as our new API call.  Its the same as our old call, but adds
-the new parameter in place.  Next we need to map this function to the symbol
-``rte_acl_create@DPDK_2.1``.  To do this, we modify the public prototype of the call
-in the header file, adding the macro there to inform all including applications,
-that on re-link, the default rte_acl_create symbol should point to this
-function.  Note that we could do this by simply naming the function above
-rte_acl_create, and the linker would chose the most recent version tag to apply
-in the version script, but we can also do this in the header file
-
-.. code-block:: c
-
-   struct rte_acl_ctx *
-   -rte_acl_create(const struct rte_acl_param *param);
-   +rte_acl_create(const struct rte_acl_param *param, int debug);
-   +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
-
-The BIND_DEFAULT_SYMBOL macro explicitly tells applications that include this
-header, to link to the rte_acl_create_v21 function and apply the DPDK_2.1
-version node to it.  This method is more explicit and flexible than just
-re-implementing the exact symbol name, and allows for other features (such as
-linking to the old symbol version by default, when the new ABI is to be opt-in
-for a period.
-
-One last thing we need to do.  Note that we've taken what was a public symbol,
-and duplicated it into two uniquely and differently named symbols.  We've then
-mapped each of those back to the public symbol ``rte_acl_create`` with different
-version tags.  This only applies to dynamic linking, as static linking has no
-notion of versioning.  That leaves this code in a position of no longer having a
-symbol simply named ``rte_acl_create`` and a static build will fail on that
-missing symbol.
-
-To correct this, we can simply map a function of our choosing back to the public
-symbol in the static build with the ``MAP_STATIC_SYMBOL`` macro.  Generally the
-assumption is that the most recent version of the symbol is the one you want to
-map.  So, back in the C file where, immediately after ``rte_acl_create_v21`` is
-defined, we add this
-
-.. code-block:: c
-
-   struct rte_acl_ctx *
-   rte_acl_create_v21(const struct rte_acl_param *param, int debug)
-   {
-        ...
-   }
-   MAP_STATIC_SYMBOL(struct rte_acl_ctx *rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v21);
-
-That tells the compiler that, when building a static library, any calls to the
-symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
-
-That's it, on the next shared library rebuild, there will be two versions of
-rte_acl_create, an old DPDK_2.0 version, used by previously built applications,
-and a new DPDK_2.1 version, used by future built applications.
-
-
-Deprecating part of a public API
-________________________________
-
-Lets assume that you've done the above update, and after a few releases have
-passed you decide you would like to retire the old version of the function.
-After having gone through the ABI deprecation announcement process, removal is
-easy.  Start by removing the symbol from the requisite version map file:
-
-.. code-block:: none
-
-   DPDK_2.0 {
-        global:
-
-        rte_acl_add_rules;
-        rte_acl_build;
-        rte_acl_classify;
-        rte_acl_classify_alg;
-        rte_acl_classify_scalar;
-        rte_acl_dump;
- -      rte_acl_create
-        rte_acl_find_existing;
-        rte_acl_free;
-        rte_acl_ipv4vlan_add_rules;
-        rte_acl_ipv4vlan_build;
-        rte_acl_list_dump;
-        rte_acl_reset;
-        rte_acl_reset_rules;
-        rte_acl_set_ctx_classify;
-
-        local: *;
-   };
-
-   DPDK_2.1 {
-        global:
-        rte_acl_create;
-   } DPDK_2.0;
-
-
-Next remove the corresponding versioned export.
-
-.. code-block:: c
-
- -VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
-
-
-Note that the internal function definition could also be removed, but its used
-in our example by the newer version _v21, so we leave it in place.  This is a
-coding style choice.
-
-Lastly, we need to bump the LIBABIVER number for this library in the Makefile to
-indicate to applications doing dynamic linking that this is a later, and
-possibly incompatible library version:
-
-.. code-block:: c
-
-   -LIBABIVER := 1
-   +LIBABIVER := 2
-
-Deprecating an entire ABI version
-_________________________________
-
-While removing a symbol from and ABI may be useful, it is often more practical
-to remove an entire version node at once.  If a version node completely
-specifies an API, then removing part of it, typically makes it incomplete.  In
-those cases it is better to remove the entire node
-
-To do this, start by modifying the version map file, such that all symbols from
-the node to be removed are merged into the next node in the map
-
-In the case of our map above, it would transform to look as follows
-
-.. code-block:: none
-
-   DPDK_2.1 {
-        global:
-
-        rte_acl_add_rules;
-        rte_acl_build;
-        rte_acl_classify;
-        rte_acl_classify_alg;
-        rte_acl_classify_scalar;
-        rte_acl_dump;
-        rte_acl_create
-        rte_acl_find_existing;
-        rte_acl_free;
-        rte_acl_ipv4vlan_add_rules;
-        rte_acl_ipv4vlan_build;
-        rte_acl_list_dump;
-        rte_acl_reset;
-        rte_acl_reset_rules;
-        rte_acl_set_ctx_classify;
-
-        local: *;
- };
-
-Then any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be
-updated to point to the new version node in any header files for all affected
-symbols.
-
-.. code-block:: c
-
- -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 2.0);
- +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 2.1);
-
-Lastly, any VERSION_SYMBOL macros that point to the old version node should be
-removed, taking care to keep, where need old code in place to support newer
-versions of the symbol.
-
-
-Running the ABI Validator
--------------------------
-
-The ``devtools`` directory in the DPDK source tree contains a utility program,
-``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
-Compliance Checker
-<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
-
-This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
-utilities which can be installed via a package manager. For example::
-
-   sudo yum install abi-compliance-checker
-   sudo yum install abi-dumper
-
-The syntax of the ``validate-abi.sh`` utility is::
-
-   ./devtools/validate-abi.sh <REV1> <REV2>
-
-Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
-https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
-on the local repo.
-
-For example::
-
-   # Check between the previous and latest commit:
-   ./devtools/validate-abi.sh HEAD~1 HEAD
-
-   # Check on a specific compilation target:
-   ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
-
-   # Check between two tags:
-   ./devtools/validate-abi.sh v2.0.0 v2.1.0
-
-   # Check between git master and local topic-branch "vhost-hacking":
-   ./devtools/validate-abi.sh master vhost-hacking
-
-After the validation script completes (it can take a while since it need to
-compile both tags) it will create compatibility reports in the
-``./abi-check/compat_report`` directory. Listed incompatibilities can be found
-as follows::
-
-  grep -lr Incompatible abi-check/compat_reports/
-- 
2.7.4


^ permalink raw reply	[relevance 13%]

* [dpdk-dev] [PATCH v2 0/3] doc: changes to abi policy introducing major abi versions
@ 2019-08-02 15:38 11% Ray Kinsella
  2019-08-02 15:38 13% ` [dpdk-dev] [PATCH v2 1/3] doc: separate versioning.rst into version and policy Ray Kinsella
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Ray Kinsella @ 2019-08-02 15:38 UTC (permalink / raw)
  To: dev
  Cc: mdr, thomas, stephen, bruce.richardson, ferruh.yigit,
	konstantin.ananyev, jerinj, olivier.matz, nhorman,
	maxime.coquelin, hemant.agrawal

TL;DR Abbreviation:
A major ABI version that all DPDK releases during a one year period
support. ABI versioning is managed at a project-level, in place of library-level
management. ABI changes to add new features are permitted, as long as ABI
compatibility with the major ABI version is maintained.

Detail:
This patch introduces major ABI versions, supported for one year and released
aligned with the LTS release. This ABI version is then supported by all
subsequent releases within that one year period. The intention is that the one
year support period, will then be reviewed after the initial year with the
intention of lengthing the support period for the next ABI version.

ABI changes that preserve ABI compatibility with the major ABI version are
permitted in subsequent releases. ABI changes, follow similar approval rules as
before with the additional gate of now requiring technical board approval. The
merging and release of ABI breaking changes would now be pushed to the
declaration of the next major ABI version.

This change encourages developers to maintain ABI compatibility with the major
ABI version, by promoting a permissive culture around those changes that
preserve ABI compatibility. This approach begins to align DPDK with those
projects that declare major ABI versions (e.g. version 2.x, 3.x) and support
those versions for some period, typically two years or more.

To provide an example of how this might work in practice:

 * DPDK v20 is declared as the supported ABI version for one year, aligned with
   the DPDK v19.11 (LTS) release. All library sonames are updated to reflect the
   new ABI version, e.g. librte_eal.so.20, librte_acl.so.20...
 * DPDK v20.02 .. v20.08 releases are ABI compatible with the DPDK v20 ABI. ABI
   changes are permitted from DPDK v20.02 onwards, with the condition that ABI
   compatibility with DPDK v20 is preserved.
 * DPDK v21 is declared as the new supported ABI version for two years, aligned
   with the DPDK v20.11 (LTS) release. The DPDK v20 ABI is now depreciated,
   library sonames are updated to v21 and ABI compatibility breaking changes may
   be introduced.

---

v2
 * Restructured the patch into 3 patches:
   1. Splits the original versioning document into an ABI policy document
     and ABI versioning document.
   2. Add changes to the policy document introducing major ABI versions.
   3. Fixes up the versioning document in light of major ABI versioning. 
 * Reduces the initial ABI stability from two years to one year, with a review
   after the first year.
 * Adds detail around ABI version handling for experimental libraries.
 * Adds detail around chain of responsility for removing deprecated symbols.

Ray Kinsella (3):
  doc: separate versioning.rst into version and policy
  doc: changes to abi policy introducing major abi versions
  doc: updates to versioning guide for abi versions

 doc/guides/contributing/abi_policy.rst     | 283 ++++++++++++++
 doc/guides/contributing/abi_versioning.rst | 505 ++++++++++++++++++++++++
 doc/guides/contributing/index.rst          |   3 +-
 doc/guides/contributing/stable.rst         |  36 +-
 doc/guides/contributing/versioning.rst     | 591 -----------------------------
 5 files changed, 810 insertions(+), 608 deletions(-)
 create mode 100644 doc/guides/contributing/abi_policy.rst
 create mode 100644 doc/guides/contributing/abi_versioning.rst
 delete mode 100644 doc/guides/contributing/versioning.rst

-- 
2.7.4


^ permalink raw reply	[relevance 11%]

* Re: [dpdk-dev] [PATCH] doc: announce lcore_config symbol removal
  2019-07-31 11:06  5% [dpdk-dev] [PATCH] doc: announce lcore_config symbol removal David Marchand
@ 2019-07-31 13:48  0% ` Stephen Hemminger
  2019-08-08  9:31  5% ` [dpdk-dev] [PATCH v2] " David Marchand
  1 sibling, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-07-31 13:48 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, thomas, bruce.richardson

On Wed, 31 Jul 2019 13:06:17 +0200
David Marchand <david.marchand@redhat.com> wrote:

> New accessors have been introduced to provide the hidden information.
> This symbol can now be kept internal.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
>  doc/guides/rel_notes/deprecation.rst | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 37b8592..b18de70 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -23,6 +23,10 @@ Deprecation Notices
>  * eal: The function ``rte_eal_remote_launch`` will return new error codes
>    after read or write error on the pipe, instead of calling ``rte_panic``.
>  
> +* eal: the ``lcore_config`` struct and global symbol will be made private to
> +  remove it from the externally visible ABI and allow it to be updated in the
> +  future.
> +
>  * eal: both declaring and identifying devices will be streamlined in v18.11.
>    New functions will appear to query a specific port from buses, classes of
>    device and device drivers. Device declaration will be made coherent with the

Acked-by: Stephen Hemminger <stephen@networkplumber.org>

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] doc: announce lcore_config symbol removal
@ 2019-07-31 11:06  5% David Marchand
  2019-07-31 13:48  0% ` Stephen Hemminger
  2019-08-08  9:31  5% ` [dpdk-dev] [PATCH v2] " David Marchand
  0 siblings, 2 replies; 200+ results
From: David Marchand @ 2019-07-31 11:06 UTC (permalink / raw)
  To: dev; +Cc: thomas, stephen, bruce.richardson

New accessors have been introduced to provide the hidden information.
This symbol can now be kept internal.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 doc/guides/rel_notes/deprecation.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 37b8592..b18de70 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -23,6 +23,10 @@ Deprecation Notices
 * eal: The function ``rte_eal_remote_launch`` will return new error codes
   after read or write error on the pipe, instead of calling ``rte_panic``.
 
+* eal: the ``lcore_config`` struct and global symbol will be made private to
+  remove it from the externally visible ABI and allow it to be updated in the
+  future.
+
 * eal: both declaring and identifying devices will be streamlined in v18.11.
   New functions will appear to query a specific port from buses, classes of
   device and device drivers. Device declaration will be made coherent with the
-- 
1.8.3.1


^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH v2 2/2] drivers/raw: standardize naming
  2019-07-30 13:39  7%   ` [dpdk-dev] [PATCH v2 2/2] drivers/raw: standardize naming Thomas Monjalon
@ 2019-07-31  7:29  0%     ` Xu, Rosen
  0 siblings, 0 replies; 200+ results
From: Xu, Rosen @ 2019-07-31  7:29 UTC (permalink / raw)
  To: Thomas Monjalon, dev, Mcnamara, John, Kovacevic, Marko,
	Nipun Gupta, Zhang, Tianfei, Richardson, Bruce, Li, Xiaoyun, Wu,
	Jingjing, Satha Rao, Vamsi Attunuru, Shreyansh Jain,
	Hemant Agrawal
  Cc: Neil Horman

Hi,

I'm okay if it's applied in 19.11.

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Tuesday, July 30, 2019 21:40
> To: dev@dpdk.org; Mcnamara, John <john.mcnamara@intel.com>;
> Kovacevic, Marko <marko.kovacevic@intel.com>; Nipun Gupta
> <nipun.gupta@nxp.com>; Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei
> <tianfei.zhang@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Li, Xiaoyun <xiaoyun.li@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>; Satha Rao <skoteshwar@marvell.com>;
> Vamsi Attunuru <vattunuru@marvell.com>; Shreyansh Jain
> <shreyansh.jain@nxp.com>; Hemant Agrawal <hemant.agrawal@nxp.com>
> Cc: Neil Horman <nhorman@tuxdriver.com>
> Subject: [PATCH v2 2/2] drivers/raw: standardize naming
> 
> From: Bruce Richardson <bruce.richardson@intel.com>
> 
> The driver names for rawdevs were both different in make and meson builds
> and were non-standard in the make version in that some included "rawdev"
> in the name while others didn't.
> 
> Therefore, for global consistency of naming, we can use "rte_rawdev" rather
> than "rte_pmd" for the prefix for the libraries. While most other driver
> categories use "rte_pmd" as a prefix, there is precedent for this in the
> mempool drivers use "rte_mempool" as a prefix.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>  doc/guides/rel_notes/release_19_08.rst             |  3 +++
>  drivers/raw/dpaa2_cmdif/Makefile                   |  4 ++--
>  ...sion.map => rte_rawdev_dpaa2_cmdif_version.map} |  0
>  drivers/raw/dpaa2_qdma/Makefile                    |  4 ++--
>  ...rsion.map => rte_rawdev_dpaa2_qdma_version.map} |  0
>  drivers/raw/ifpga/Makefile                         |  4 ++--
>  ...ga_version.map => rte_rawdev_ifpga_version.map} |  0
>  drivers/raw/ioat/Makefile                          |  4 ++--
>  ...oat_version.map => rte_rawdev_ioat_version.map} |  0
>  drivers/raw/meson.build                            |  2 +-
>  drivers/raw/ntb/Makefile                           |  4 ++--
>  ..._ntb_version.map => rte_rawdev_ntb_version.map} |  0
>  drivers/raw/octeontx2_dma/Makefile                 |  4 ++--
>  ...on.map => rte_rawdev_octeontx2_dma_version.map} |  0
>  drivers/raw/skeleton/Makefile                      |  4 ++--
>  ...version.map => rte_rawdev_skeleton_version.map} |  0
>  mk/rte.app.mk                                      | 14 +++++++-------
>  17 files changed, 25 insertions(+), 22 deletions(-)  rename
> drivers/raw/dpaa2_cmdif/{rte_pmd_dpaa2_cmdif_version.map =>
> rte_rawdev_dpaa2_cmdif_version.map} (100%)  rename
> drivers/raw/dpaa2_qdma/{rte_pmd_dpaa2_qdma_version.map =>
> rte_rawdev_dpaa2_qdma_version.map} (100%)  rename
> drivers/raw/ifpga/{rte_pmd_ifpga_version.map =>
> rte_rawdev_ifpga_version.map} (100%)  rename
> drivers/raw/ioat/{rte_pmd_ioat_version.map =>
> rte_rawdev_ioat_version.map} (100%)  rename
> drivers/raw/ntb/{rte_pmd_ntb_version.map =>
> rte_rawdev_ntb_version.map} (100%)  rename
> drivers/raw/octeontx2_dma/{rte_pmd_octeontx2_dma_version.map =>
> rte_rawdev_octeontx2_dma_version.map} (100%)  rename
> drivers/raw/skeleton/{rte_pmd_skeleton_version.map =>
> rte_rawdev_skeleton_version.map} (100%)
> 
> diff --git a/doc/guides/rel_notes/release_19_08.rst
> b/doc/guides/rel_notes/release_19_08.rst
> index fcd1386a5..13a98f520 100644
> --- a/doc/guides/rel_notes/release_19_08.rst
> +++ b/doc/guides/rel_notes/release_19_08.rst
> @@ -351,6 +351,9 @@ ABI Changes
>  * bbdev: New operations and parameters added to support new 5GNR
> operations.
>    The bbdev ABI is still kept experimental.
> 
> +* rawdev: The driver names have been changed to ``librte_rawdev_*``.
> +  Now they all have the same prefix, and same name with make and meson
> builds.
> +
> 
>  Shared Library Versions
>  -----------------------
> diff --git a/drivers/raw/dpaa2_cmdif/Makefile
> b/drivers/raw/dpaa2_cmdif/Makefile
> index 9bd5ff229..2b4150c2d 100644
> --- a/drivers/raw/dpaa2_cmdif/Makefile
> +++ b/drivers/raw/dpaa2_cmdif/Makefile
> @@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk  #  # library name  # -
> LIB = librte_pmd_dpaa2_cmdif.a
> +LIB = librte_rawdev_dpaa2_cmdif.a
> 
>  CFLAGS += -DALLOW_EXPERIMENTAL_API
>  CFLAGS += -O3
> @@ -23,7 +23,7 @@ LDLIBS += -lrte_mempool_dpaa2  LDLIBS += -
> lrte_rawdev  LDLIBS += -lrte_common_dpaax
> 
> -EXPORT_MAP := rte_pmd_dpaa2_cmdif_version.map
> +EXPORT_MAP := rte_rawdev_dpaa2_cmdif_version.map
> 
>  LIBABIVER := 2
> 
> diff --git a/drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map
> b/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
> similarity index 100%
> rename from drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map
> rename to drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
> diff --git a/drivers/raw/dpaa2_qdma/Makefile
> b/drivers/raw/dpaa2_qdma/Makefile index f9a810cc6..0009fd4c6 100644
> --- a/drivers/raw/dpaa2_qdma/Makefile
> +++ b/drivers/raw/dpaa2_qdma/Makefile
> @@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk  #  # library name  # -
> LIB = librte_pmd_dpaa2_qdma.a
> +LIB = librte_rawdev_dpaa2_qdma.a
> 
>  CFLAGS += -DALLOW_EXPERIMENTAL_API
>  CFLAGS += -O3
> @@ -24,7 +24,7 @@ LDLIBS += -lrte_kvargs  LDLIBS += -lrte_ring  LDLIBS += -
> lrte_common_dpaax
> 
> -EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
> +EXPORT_MAP := rte_rawdev_dpaa2_qdma_version.map
> 
>  LIBABIVER := 3
> 
> diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
> b/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
> similarity index 100%
> rename from
> drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
> rename to
> drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
> diff --git a/drivers/raw/ifpga/Makefile b/drivers/raw/ifpga/Makefile index
> 5fa9303d5..655b29288 100644
> --- a/drivers/raw/ifpga/Makefile
> +++ b/drivers/raw/ifpga/Makefile
> @@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk  #  # library name  # -
> LIB = librte_pmd_ifpga_rawdev.a
> +LIB = librte_rawdev_ifpga.a
> 
>  CFLAGS += -DALLOW_EXPERIMENTAL_API
>  CFLAGS += -O3
> @@ -21,7 +21,7 @@ LDLIBS += -lrte_kvargs  LDLIBS += -lrte_bus_pci  LDLIBS
> += -lrte_bus_ifpga
> 
> -EXPORT_MAP := rte_pmd_ifpga_version.map
> +EXPORT_MAP := rte_rawdev_ifpga_version.map
> 
>  LIBABIVER := 1
> 
> diff --git a/drivers/raw/ifpga/rte_pmd_ifpga_version.map
> b/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
> similarity index 100%
> rename from drivers/raw/ifpga/rte_pmd_ifpga_version.map
> rename to drivers/raw/ifpga/rte_rawdev_ifpga_version.map
> diff --git a/drivers/raw/ioat/Makefile b/drivers/raw/ioat/Makefile index
> 32f079845..e852afb57 100644
> --- a/drivers/raw/ioat/Makefile
> +++ b/drivers/raw/ioat/Makefile
> @@ -4,7 +4,7 @@
>  include $(RTE_SDK)/mk/rte.vars.mk
> 
>  # library name
> -LIB = librte_pmd_ioat_rawdev.a
> +LIB = librte_rawdev_ioat.a
> 
>  # build flags
>  CFLAGS += -O3
> @@ -18,7 +18,7 @@ LDLIBS += -lrte_mbuf -lrte_mempool  LIBABIVER := 1
> 
>  # versioning export map
> -EXPORT_MAP := rte_pmd_ioat_version.map
> +EXPORT_MAP := rte_rawdev_ioat_version.map
> 
>  # library source files
>  SRCS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV) += ioat_rawdev.c diff --
> git a/drivers/raw/ioat/rte_pmd_ioat_version.map
> b/drivers/raw/ioat/rte_rawdev_ioat_version.map
> similarity index 100%
> rename from drivers/raw/ioat/rte_pmd_ioat_version.map
> rename to drivers/raw/ioat/rte_rawdev_ioat_version.map
> diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build index
> bcd5553e1..d7037cd87 100644
> --- a/drivers/raw/meson.build
> +++ b/drivers/raw/meson.build
> @@ -7,4 +7,4 @@ drivers = ['dpaa2_cmdif', 'dpaa2_qdma',
>  	'skeleton']
>  std_deps = ['rawdev']
>  config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
> -driver_name_fmt = 'rte_pmd_@0@'
> +driver_name_fmt = 'rte_rawdev_@0@'
> diff --git a/drivers/raw/ntb/Makefile b/drivers/raw/ntb/Makefile index
> edd49fe75..6fe2aaf40 100644
> --- a/drivers/raw/ntb/Makefile
> +++ b/drivers/raw/ntb/Makefile
> @@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk  #  # library name  # -
> LIB = librte_pmd_ntb.a
> +LIB = librte_rawdev_ntb.a
> 
>  CFLAGS += -DALLOW_EXPERIMENTAL_API
>  CFLAGS += -O3
> @@ -15,7 +15,7 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool  LDLIBS
> += -lrte_pci -lrte_bus_pci  LDLIBS += -lrte_rawdev
> 
> -EXPORT_MAP := rte_pmd_ntb_version.map
> +EXPORT_MAP := rte_rawdev_ntb_version.map
> 
>  LIBABIVER := 1
> 
> diff --git a/drivers/raw/ntb/rte_pmd_ntb_version.map
> b/drivers/raw/ntb/rte_rawdev_ntb_version.map
> similarity index 100%
> rename from drivers/raw/ntb/rte_pmd_ntb_version.map
> rename to drivers/raw/ntb/rte_rawdev_ntb_version.map
> diff --git a/drivers/raw/octeontx2_dma/Makefile
> b/drivers/raw/octeontx2_dma/Makefile
> index 96f782eb6..f101e4916 100644
> --- a/drivers/raw/octeontx2_dma/Makefile
> +++ b/drivers/raw/octeontx2_dma/Makefile
> @@ -5,7 +5,7 @@
>  include $(RTE_SDK)/mk/rte.vars.mk
> 
>  # library name
> -LIB = librte_pmd_octeontx2_dma.a
> +LIB = librte_rawdev_octeontx2_dma.a
> 
>  CFLAGS += -O3 $(WERROR_FLAGS)
>  CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx2/
> @@ -22,7 +22,7 @@ CFLAGS += -diag-disable 2259  endif  endif
> 
> -EXPORT_MAP := rte_pmd_octeontx2_dma_version.map
> +EXPORT_MAP := rte_rawdev_octeontx2_dma_version.map
> 
>  LIBABIVER := 1
> 
> diff --git
> a/drivers/raw/octeontx2_dma/rte_pmd_octeontx2_dma_version.map
> b/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
> similarity index 100%
> rename from
> drivers/raw/octeontx2_dma/rte_pmd_octeontx2_dma_version.map
> rename to
> drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
> diff --git a/drivers/raw/skeleton/Makefile b/drivers/raw/skeleton/Makefile
> index 9641e6505..783b1e952 100644
> --- a/drivers/raw/skeleton/Makefile
> +++ b/drivers/raw/skeleton/Makefile
> @@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk  #  # library name  # -
> LIB = librte_pmd_skeleton_rawdev.a
> +LIB = librte_rawdev_skeleton.a
> 
>  CFLAGS += -O3
>  CFLAGS += $(WERROR_FLAGS)
> @@ -15,7 +15,7 @@ LDLIBS += -lrte_rawdev  LDLIBS += -lrte_bus_vdev
> LDLIBS += -lrte_kvargs
> 
> -EXPORT_MAP := rte_pmd_skeleton_version.map
> +EXPORT_MAP := rte_rawdev_skeleton_version.map
> 
>  LIBABIVER := 1
> 
> diff --git a/drivers/raw/skeleton/rte_pmd_skeleton_version.map
> b/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
> similarity index 100%
> rename from drivers/raw/skeleton/rte_pmd_skeleton_version.map
> rename to drivers/raw/skeleton/rte_rawdev_skeleton_version.map
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk index a277c808e..ba5c39e01
> 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -312,19 +312,19 @@ _LDLIBS-
> $(CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV) += -lrte_pmd_opdl_event
> endif # CONFIG_RTE_LIBRTE_EVENTDEV
> 
>  ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
> -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -
> lrte_pmd_skeleton_rawdev
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) +=
> +-lrte_rawdev_skeleton
>  ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
> -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += -
> lrte_pmd_dpaa2_cmdif
> -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -
> lrte_pmd_dpaa2_qdma
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) +=
> +-lrte_rawdev_dpaa2_cmdif
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) +=
> +-lrte_rawdev_dpaa2_qdma
>  endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
>  ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
> -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -
> lrte_pmd_ifpga_rawdev
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -
> lrte_rawdev_ifpga
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
>  endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
> -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -
> lrte_pmd_ioat_rawdev
> -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb
> -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_DMA_RAWDEV) += -
> lrte_pmd_octeontx2_dma
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -
> lrte_rawdev_ioat
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_rawdev_ntb
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_DMA_RAWDEV) +=
> +-lrte_rawdev_octeontx2_dma
>  endif # CONFIG_RTE_LIBRTE_RAWDEV
> 
>  endif # !CONFIG_RTE_BUILD_SHARED_LIBS
> --
> 2.21.0

Acked-by: Rosen Xu <rosen.xu@intel.com>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH] librte_flow_classify: fix out-of-bounds access
  2019-07-30 16:55  0%           ` Ferruh Yigit
@ 2019-07-30 17:30  0%             ` Aaron Conole
  0 siblings, 0 replies; 200+ results
From: Aaron Conole @ 2019-07-30 17:30 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: David Marchand, Bernard Iremonger, dev, dpdk stable,
	Thomas Monjalon, Singh, Jasvinder, Flavia Musatescu,
	Adrien Mazarguil

Ferruh Yigit <ferruh.yigit@intel.com> writes:

> On 7/30/2019 4:43 PM, Aaron Conole wrote:
>> Ferruh Yigit <ferruh.yigit@intel.com> writes:
>> 
>>> On 7/30/2019 3:42 PM, Aaron Conole wrote:
>>>> David Marchand <david.marchand@redhat.com> writes:
>>>>
>>>>> On Wed, Jul 10, 2019 at 11:49 PM Thomas Monjalon <thomas@monjalon.net> wrote:
>>>>>>
>>>>>> 09/07/2019 13:09, Bernard Iremonger:
>>>>>>> This patch fixes the out-of-bounds coverity issue by removing the
>>>>>>> offending line of code at line 107 in rte_flow_classify_parse.c
>>>>>>> which is never executed.
>>>>>>>
>>>>>>> Coverity issue: 343454
>>>>>>>
>>>>>>> Fixes: be41ac2a330f ("flow_classify: introduce flow classify library")
>>>>>>> Cc: stable@dpdk.org
>>>>>>> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
>>>>>>
>>>>>> Applied, thanks
>>>>>
>>>>> We have a segfault in the unit tests since this patch.
>>>>
>>>> I think this patch is still correct.  The issue is in the semantic of
>>>> the flow classify pattern.  It *MUST* always have a valid end marker,
>>>> but the test passes an invalid end marker.  This causes the bounds to
>>>> exceed.
>>>>
>>>> So, it would be best to fix it, either by having a "failure" on unknown
>>>> markers (f.e. -1), or by passing a length around.  However, the crash
>>>> should be expected.  The fact that the previous code was also incorrect
>>>> and resulted in no segfault is pure luck.
>>>>
>>>> See rte_flow_classify_parse.c:80 and test_flow_classify.c:387
>>>>
>>>> I would be in favor of passing the lengths of the two arrays to these
>>>> APIs.  That would let us still make use of the markers (for valid
>>>> construction), but also let us reason about lengths in a sane way.
>>>>
>>>> WDYT?
>>>>
>>>
>>> +1, I also just replied with something very similar.
>>>
>>> With current API the testcase is wrong, and it will crash, also the invalid
>>> action one has exact same problem.
>>>
>>> The API can be updated as you suggested, with a length field and testcases can
>>> be added back.
>>>
>>> What worries me more is the rte_flow, which uses same arguments, and open to
>>> same errors, should we consider updating rte_flow APIs to have lengths values too?
>> 
>> Probably.
>> 
>> Here's a first crack at the change I think is appropriate.  I have done
>> some limited testing.  Let me know if you want me to submit it formally.
>> 
>> ---------------------------- 8< ---------------------------------
>> Subject: [PATCH] rte_flow_classify: fix up the API and preserve ABI
>> 
>> Introduces a new API for doing length validations, and preserves the old semantics
>> and API.  The previous API couldn't handle corrupted end markers.  A future
>> version of the API might be able to eschew the end marker and trust the length,
>> but that is a discussion for future.
>> 
>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>> ---
>>  app/test/test_flow_classify.c                | 30 +-------
>>  lib/librte_flow_classify/rte_flow_classify.c | 72 +++++++++++++++++---
>>  lib/librte_flow_classify/rte_flow_classify.h | 28 ++++++++
>>  3 files changed, 91 insertions(+), 39 deletions(-)
>> 
>> diff --git a/app/test/test_flow_classify.c b/app/test/test_flow_classify.c
>> index 6bbaad364..ff5265c6a 100644
>> --- a/app/test/test_flow_classify.c
>> +++ b/app/test/test_flow_classify.c
>> @@ -125,7 +125,6 @@ static struct rte_flow_item  udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP,
>>  
>>  static struct rte_flow_item  end_item = { RTE_FLOW_ITEM_TYPE_END,
>>  	0, 0, 0 };
>> -static struct rte_flow_item  end_item_bad = { -1, 0, 0, 0 };
>>  
>>  /* test TCP pattern:
>>   * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8
>> @@ -181,7 +180,6 @@ static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT,
>>  static struct rte_flow_action count_action_bad = { -1, 0};
>>  
>>  static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0};
>> -static struct rte_flow_action end_action_bad =	{ -1, 0};
>>  
>>  static struct rte_flow_action actions[2];
>>  
>> @@ -384,7 +382,7 @@ test_invalid_patterns(void)
>>  
>>  	pattern[1] = ipv4_udp_item_1;
>>  	pattern[2] = udp_item_bad;
>> -	pattern[3] = end_item_bad;
>> +	pattern[3] = end_item;
>>  
>>  	ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
>>  			actions, &error);
>> @@ -458,32 +456,6 @@ test_invalid_actions(void)
>>  		return -1;
>>  	}
>>  
>> -	actions[0] = count_action;
>> -	actions[1] = end_action_bad;
>> -
>> -	ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
>> -			actions, &error);
>> -	if (!ret) {
>> -		printf("Line %i: rte_flow_classify_validate", __LINE__);
>> -		printf(" should have failed!\n");
>> -		return -1;
>> -	}
>> -
>> -	rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
>> -			actions, &key_found, &error);
>> -	if (rule) {
>> -		printf("Line %i: flow_classify_table_entry_add", __LINE__);
>> -		printf(" should have failed!\n");
>> -		return -1;
>> -	}
>> -
>> -	ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
>> -	if (!ret) {
>> -		printf("Line %i: rte_flow_classify_table_entry_delete",
>> -			__LINE__);
>> -		printf("should have failed!\n");
>> -		return -1;
>> -	}
>>  	return 0;
>>  }
>
> +1 to unit test updates, lgtm.
>
> And I am for pushing the library updates to the next release, but please find a
> few comments for now.

Okay - I'll do that.  But we probably will need to note that these APIs
should get deprecated.  Not sure if that should happen in this release -
as the author of most of the code, maybe you would take care of that
part? :)

>
>>  
>> diff --git a/lib/librte_flow_classify/rte_flow_classify.c b/lib/librte_flow_classify/rte_flow_classify.c
>> index 5ff585803..3ca1b1b44 100644
>> --- a/lib/librte_flow_classify/rte_flow_classify.c
>> +++ b/lib/librte_flow_classify/rte_flow_classify.c
>> @@ -89,18 +89,51 @@ struct rte_flow_classify_rule {
>>  	void *entry_ptr; /* handle to the table entry for rule meta data */
>>  };
>>  
>> +static size_t
>> +calc_flow_item_alen(const struct rte_flow_item pattern[])
>> +{
>> +	size_t i = 0;
>> +	while (pattern && (pattern + i)->type != RTE_FLOW_ITEM_TYPE_END)
>> +		i++;
>> +	return i + 1;
>
> I think better to send '0' if the pointer is NULL, (instead of 1)

Okay.  Makes sense.

> <...>
>
>> @@ -186,6 +186,34 @@ int
>>  rte_flow_classify_table_create(struct rte_flow_classifier *cls,
>>  		struct rte_flow_classify_table_params *params);
>>  
>> +/**
>> + * Flow classify validate
>> + *
>> + * @param cls
>> + *   Handle to flow classifier instance
>> + * @param[in] attr
>> + *   Flow rule attributes
>> + * @param[in] pattern
>> + *   Pattern specification (list terminated by the END pattern item).
>> + * @param[in] actions
>> + *   Associated actions (list terminated by the END pattern item).
>> + * @param[out] error
>> + *   Perform verbose error reporting if not NULL. Structure
>> + *   initialised in case of error only.
>> + * @return
>> + *   0 on success, error code otherwise
>> + */
>> +__rte_experimental
>> +int
>> +rte_flow_classify_validate_l(struct rte_flow_classifier *cls,
>> +			     const struct rte_flow_attr *attr,
>> +			     const struct rte_flow_item pattern[],
>> +			     const size_t pattern_l,
>> +			     const struct rte_flow_action actions[],
>> +			     const size_t actions_l,
>> +			     struct rte_flow_error *error);
>
> The doxygen comment is missing for 'pattern_l' & 'actions_l' but from code it is
> number of items in the lists, this is duplication of the END marker information.
> Instead, if those lengths are the length of the arrays will it be easier for the
> user? So user won't need to calculate the item count but can pass the size of
> the array. This still prevents API access out of the array.
>
> Anyway, as suggested above lets not make these decisions just a few days before
> the release, but just get the unit test fix for the release, does it make sense?

Sure.

> And if so, can you send the unit test patch?

Will do.

> Thanks,
> ferruh

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH] librte_flow_classify: fix out-of-bounds access
  2019-07-30 15:43  2%         ` Aaron Conole
@ 2019-07-30 16:55  0%           ` Ferruh Yigit
  2019-07-30 17:30  0%             ` Aaron Conole
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-07-30 16:55 UTC (permalink / raw)
  To: Aaron Conole
  Cc: David Marchand, Bernard Iremonger, dev, dpdk stable,
	Thomas Monjalon, Singh, Jasvinder, Flavia Musatescu,
	Adrien Mazarguil

On 7/30/2019 4:43 PM, Aaron Conole wrote:
> Ferruh Yigit <ferruh.yigit@intel.com> writes:
> 
>> On 7/30/2019 3:42 PM, Aaron Conole wrote:
>>> David Marchand <david.marchand@redhat.com> writes:
>>>
>>>> On Wed, Jul 10, 2019 at 11:49 PM Thomas Monjalon <thomas@monjalon.net> wrote:
>>>>>
>>>>> 09/07/2019 13:09, Bernard Iremonger:
>>>>>> This patch fixes the out-of-bounds coverity issue by removing the
>>>>>> offending line of code at line 107 in rte_flow_classify_parse.c
>>>>>> which is never executed.
>>>>>>
>>>>>> Coverity issue: 343454
>>>>>>
>>>>>> Fixes: be41ac2a330f ("flow_classify: introduce flow classify library")
>>>>>> Cc: stable@dpdk.org
>>>>>> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
>>>>>
>>>>> Applied, thanks
>>>>
>>>> We have a segfault in the unit tests since this patch.
>>>
>>> I think this patch is still correct.  The issue is in the semantic of
>>> the flow classify pattern.  It *MUST* always have a valid end marker,
>>> but the test passes an invalid end marker.  This causes the bounds to
>>> exceed.
>>>
>>> So, it would be best to fix it, either by having a "failure" on unknown
>>> markers (f.e. -1), or by passing a length around.  However, the crash
>>> should be expected.  The fact that the previous code was also incorrect
>>> and resulted in no segfault is pure luck.
>>>
>>> See rte_flow_classify_parse.c:80 and test_flow_classify.c:387
>>>
>>> I would be in favor of passing the lengths of the two arrays to these
>>> APIs.  That would let us still make use of the markers (for valid
>>> construction), but also let us reason about lengths in a sane way.
>>>
>>> WDYT?
>>>
>>
>> +1, I also just replied with something very similar.
>>
>> With current API the testcase is wrong, and it will crash, also the invalid
>> action one has exact same problem.
>>
>> The API can be updated as you suggested, with a length field and testcases can
>> be added back.
>>
>> What worries me more is the rte_flow, which uses same arguments, and open to
>> same errors, should we consider updating rte_flow APIs to have lengths values too?
> 
> Probably.
> 
> Here's a first crack at the change I think is appropriate.  I have done
> some limited testing.  Let me know if you want me to submit it formally.
> 
> ---------------------------- 8< ---------------------------------
> Subject: [PATCH] rte_flow_classify: fix up the API and preserve ABI
> 
> Introduces a new API for doing length validations, and preserves the old semantics
> and API.  The previous API couldn't handle corrupted end markers.  A future
> version of the API might be able to eschew the end marker and trust the length,
> but that is a discussion for future.
> 
> Signed-off-by: Aaron Conole <aconole@redhat.com>
> ---
>  app/test/test_flow_classify.c                | 30 +-------
>  lib/librte_flow_classify/rte_flow_classify.c | 72 +++++++++++++++++---
>  lib/librte_flow_classify/rte_flow_classify.h | 28 ++++++++
>  3 files changed, 91 insertions(+), 39 deletions(-)
> 
> diff --git a/app/test/test_flow_classify.c b/app/test/test_flow_classify.c
> index 6bbaad364..ff5265c6a 100644
> --- a/app/test/test_flow_classify.c
> +++ b/app/test/test_flow_classify.c
> @@ -125,7 +125,6 @@ static struct rte_flow_item  udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP,
>  
>  static struct rte_flow_item  end_item = { RTE_FLOW_ITEM_TYPE_END,
>  	0, 0, 0 };
> -static struct rte_flow_item  end_item_bad = { -1, 0, 0, 0 };
>  
>  /* test TCP pattern:
>   * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8
> @@ -181,7 +180,6 @@ static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT,
>  static struct rte_flow_action count_action_bad = { -1, 0};
>  
>  static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0};
> -static struct rte_flow_action end_action_bad =	{ -1, 0};
>  
>  static struct rte_flow_action actions[2];
>  
> @@ -384,7 +382,7 @@ test_invalid_patterns(void)
>  
>  	pattern[1] = ipv4_udp_item_1;
>  	pattern[2] = udp_item_bad;
> -	pattern[3] = end_item_bad;
> +	pattern[3] = end_item;
>  
>  	ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
>  			actions, &error);
> @@ -458,32 +456,6 @@ test_invalid_actions(void)
>  		return -1;
>  	}
>  
> -	actions[0] = count_action;
> -	actions[1] = end_action_bad;
> -
> -	ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
> -			actions, &error);
> -	if (!ret) {
> -		printf("Line %i: rte_flow_classify_validate", __LINE__);
> -		printf(" should have failed!\n");
> -		return -1;
> -	}
> -
> -	rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
> -			actions, &key_found, &error);
> -	if (rule) {
> -		printf("Line %i: flow_classify_table_entry_add", __LINE__);
> -		printf(" should have failed!\n");
> -		return -1;
> -	}
> -
> -	ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
> -	if (!ret) {
> -		printf("Line %i: rte_flow_classify_table_entry_delete",
> -			__LINE__);
> -		printf("should have failed!\n");
> -		return -1;
> -	}
>  	return 0;
>  }

+1 to unit test updates, lgtm.

And I am for pushing the library updates to the next release, but please find a
few comments for now.


>  
> diff --git a/lib/librte_flow_classify/rte_flow_classify.c b/lib/librte_flow_classify/rte_flow_classify.c
> index 5ff585803..3ca1b1b44 100644
> --- a/lib/librte_flow_classify/rte_flow_classify.c
> +++ b/lib/librte_flow_classify/rte_flow_classify.c
> @@ -89,18 +89,51 @@ struct rte_flow_classify_rule {
>  	void *entry_ptr; /* handle to the table entry for rule meta data */
>  };
>  
> +static size_t
> +calc_flow_item_alen(const struct rte_flow_item pattern[])
> +{
> +	size_t i = 0;
> +	while (pattern && (pattern + i)->type != RTE_FLOW_ITEM_TYPE_END)
> +		i++;
> +	return i + 1;

I think better to send '0' if the pointer is NULL, (instead of 1)

<...>

> @@ -186,6 +186,34 @@ int
>  rte_flow_classify_table_create(struct rte_flow_classifier *cls,
>  		struct rte_flow_classify_table_params *params);
>  
> +/**
> + * Flow classify validate
> + *
> + * @param cls
> + *   Handle to flow classifier instance
> + * @param[in] attr
> + *   Flow rule attributes
> + * @param[in] pattern
> + *   Pattern specification (list terminated by the END pattern item).
> + * @param[in] actions
> + *   Associated actions (list terminated by the END pattern item).
> + * @param[out] error
> + *   Perform verbose error reporting if not NULL. Structure
> + *   initialised in case of error only.
> + * @return
> + *   0 on success, error code otherwise
> + */
> +__rte_experimental
> +int
> +rte_flow_classify_validate_l(struct rte_flow_classifier *cls,
> +			     const struct rte_flow_attr *attr,
> +			     const struct rte_flow_item pattern[],
> +			     const size_t pattern_l,
> +			     const struct rte_flow_action actions[],
> +			     const size_t actions_l,
> +			     struct rte_flow_error *error);

The doxygen comment is missing for 'pattern_l' & 'actions_l' but from code it is
number of items in the lists, this is duplication of the END marker information.
Instead, if those lengths are the length of the arrays will it be easier for the
user? So user won't need to calculate the item count but can pass the size of
the array. This still prevents API access out of the array.

Anyway, as suggested above lets not make these decisions just a few days before
the release, but just get the unit test fix for the release, does it make sense?

And if so, can you send the unit test patch?

Thanks,
ferruh

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [EXT] Re: [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline
  2019-07-30 16:05  5% ` Bruce Richardson
@ 2019-07-30 16:24  3%   ` Jerin Jacob Kollanukkaran
  0 siblings, 0 replies; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-07-30 16:24 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: Marcin Zapolski, dev

> -----Original Message-----
> From: Bruce Richardson <bruce.richardson@intel.com>
> Sent: Tuesday, July 30, 2019 9:36 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> Subject: [EXT] Re: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions
> non-inline
> 
> On Tue, Jul 30, 2019 at 03:45:38PM +0000, Jerin Jacob Kollanukkaran wrote:
> > > -----Original Message-----
> > > From: Bruce Richardson <bruce.richardson@intel.com>
> > > Sent: Tuesday, July 30, 2019 9:02 PM
> > > To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> > > Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> > > Subject: [EXT] Re: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core
> > > functions non-inline
> > >
> > > --------------------------------------------------------------------
> > > -- On Tue, Jul 30, 2019 at 03:01:00PM +0000, Jerin Jacob
> > > Kollanukkaran wrote:
> > > > > -----Original Message----- From: dev <dev-bounces@dpdk.org> On
> > > > > Behalf Of Marcin Zapolski Sent: Tuesday, July 30, 2019 6:20 PM To:
> > > > > dev@dpdk.org Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> > > > > Subject: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core
> > > > > functions
> > > > > non- inline
> > > > >
> > > > > Make rte_eth_rx_burst, rte_eth_tx_burst and other static inline
> > > > > ethdev functions not inline. They are referencing DPDK internal
> > > > > structures and inlining forces those structures to be exposed to
> > > > > user
> > > applications.
> > > > >
> > > > > In internal testing with i40e NICs a performance drop of about
> > > > > 2% was observed with testpmd.
> > > >
> > > > I tested on two class of arm64 machines(Highend and lowend) one
> > > > has 1.4% drop And other one has 3.6% drop.
> > > >
> > > This is with testpmd only right? I'd just point out that we need to
> > > remember that these numbers need to be scaled down appropriately for
> > > a realworld app where IO is only a (hopefully small) proportion of
> > > the packet processing budget. For example, I would expect the ~2%
> > > drop we saw in testpmd to correspond to <0.5% drop in something like OVS.
> >
> > I see it as bit different view, Cycles saved infrastructure layer,
> > cycles gained in application. So IMO it vary between end user
> > application need what kind of machine it runs.
> >
> Sure. My thinking more is that to get ABI compatibility involves some tradeoffs
> and spending one more cycle per-packet when an app workload is typically
> hundreds of cycles, I believe, is a small cost worth paying.

I agree. But, We need take only the cost, If it is really costs.I don't think, we don't
need two level of indirection.

> 
> > >
> > > > I second to not expose internal data structure to avoid ABI break.
> > > >
> > > > IMO, This patch has performance issue due to it is fixing it in
> > > > simple way.
> > > >
> > > > It is not worth two have function call overhead to call the driver
> > > > function.  Some thoughts below to reduce the performance impact
> > > > without exposing internal structures.
> > > >
> > > The big concern I have with what you propose is that would involve
> > > changing each and every ethdev driver in DPDK! I'd prefer to make
> > > sure that the impact of this change is actually felt in real-world
> > > apps before we start looking to make such updates across the DPDK
> codebase.
> >
> > I see those changes are NO BRAINER from driver POV. Once we add in one
> > driver, individual PMD Maintainer can update easily. I think, we can do it once
> for all.
> 
> Ok, if it's doable in one go then sure. The issue is that if even one driver is not
> updated we can't switch over, all have to effectively be done simultaneously. [It

I agree. But I think, we can give enough time for driver to migrate.
If it does not migrate in time. We can take necessary action to fix it.
If it is a no brainer changes then all drivers will do it. We cannot pay cost
Because one driver is not maintaining. I can commit to take care of ALL Marvell PMDs.

> would also make backporting fixes trickier, but I wouldn't be concerned about
> that particularly.]
> 
> Have you tried out making the changes to a driver or two, to see how large the
> delta is? [And to verify it doesn't affect performance]

I hope, The RFC author will take first stab, I can help in reviewing it.

> 
> > I am sure, you must aware of How hard is make 2% improvement in
> > driver. I can spend time in This NO brainer to get 2% improvement back. I
> prefer later.
> >
> The other alternative I see is to leave the inline functions there, just disabled by
> default, and put in a build-time option for reduced ABI compatibility. That way
> the standard-built packages are all ABI compatible, but for those who absolutely
> need max perf and are rolling-their-own-build to get it can disable that ABI
> compatibility.

But currently there no ABI break. Right? We should do it before we have one on those
structures. I think, we should cleanup the low hanging ones first and to fast
path structures in parallel.


> 
> /Bruce

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline
  2019-07-30 15:45  0% [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline Jerin Jacob Kollanukkaran
@ 2019-07-30 16:05  5% ` Bruce Richardson
  2019-07-30 16:24  3%   ` [dpdk-dev] [EXT] " Jerin Jacob Kollanukkaran
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2019-07-30 16:05 UTC (permalink / raw)
  To: Jerin Jacob Kollanukkaran; +Cc: Marcin Zapolski, dev

On Tue, Jul 30, 2019 at 03:45:38PM +0000, Jerin Jacob Kollanukkaran wrote:
> > -----Original Message-----
> > From: Bruce Richardson <bruce.richardson@intel.com>
> > Sent: Tuesday, July 30, 2019 9:02 PM
> > To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> > Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> > Subject: [EXT] Re: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions
> > non-inline
> > 
> > ----------------------------------------------------------------------
> > On Tue, Jul 30, 2019 at 03:01:00PM +0000, Jerin Jacob Kollanukkaran wrote:
> > > > -----Original Message----- From: dev <dev-bounces@dpdk.org> On
> > > > Behalf Of Marcin Zapolski Sent: Tuesday, July 30, 2019 6:20 PM To:
> > > > dev@dpdk.org Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> > > > Subject: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions
> > > > non- inline
> > > >
> > > > Make rte_eth_rx_burst, rte_eth_tx_burst and other static inline
> > > > ethdev functions not inline. They are referencing DPDK internal
> > > > structures and inlining forces those structures to be exposed to user
> > applications.
> > > >
> > > > In internal testing with i40e NICs a performance drop of about 2%
> > > > was observed with testpmd.
> > >
> > > I tested on two class of arm64 machines(Highend and lowend) one has
> > > 1.4% drop And other one has 3.6% drop.
> > >
> > This is with testpmd only right? I'd just point out that we need to remember that
> > these numbers need to be scaled down appropriately for a realworld app where
> > IO is only a (hopefully small) proportion of the packet processing budget. For
> > example, I would expect the ~2% drop we saw in testpmd to correspond to
> > <0.5% drop in something like OVS.
> 
> I see it as bit different view, Cycles saved infrastructure layer, cycles gained in
> application. So IMO it vary between end user application need what kind of
> machine it runs.
>
Sure. My thinking more is that to get ABI compatibility involves some
tradeoffs and spending one more cycle per-packet when an app workload is
typically hundreds of cycles, I believe, is a small cost worth paying.

> > 
> > > I second to not expose internal data structure to avoid ABI break.
> > >
> > > IMO, This patch has performance issue due to it is fixing it in simple
> > > way.
> > >
> > > It is not worth two have function call overhead to call the driver
> > > function.  Some thoughts below to reduce the performance impact
> > > without exposing internal structures.
> > >
> > The big concern I have with what you propose is that would involve changing
> > each and every ethdev driver in DPDK! I'd prefer to make sure that the impact of
> > this change is actually felt in real-world apps before we start looking to make
> > such updates across the DPDK codebase.
> 
> I see those changes are NO BRAINER from driver POV. Once we add in one driver, individual
> PMD Maintainer can update easily. I think, we can do it once for all.

Ok, if it's doable in one go then sure. The issue is that if even one driver
is not updated we can't switch over, all have to effectively be done
simultaneously. [It would also make backporting fixes trickier, but I
wouldn't be concerned about that particularly.]

Have you tried out making the changes to a driver or two, to see how large
the delta is? [And to verify it doesn't affect performance]

> I am sure, you must aware of How hard is make 2% improvement in driver. I can spend time in
> This NO brainer to get 2% improvement back. I prefer later.
> 
The other alternative I see is to leave the inline functions there, just
disabled by default, and put in a build-time option for reduced ABI
compatibility. That way the standard-built packages are all ABI compatible,
but for those who absolutely need max perf and are rolling-their-own-build
to get it can disable that ABI compatibility.

/Bruce

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline
@ 2019-07-30 15:45  0% Jerin Jacob Kollanukkaran
  2019-07-30 16:05  5% ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-07-30 15:45 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: Marcin Zapolski, dev

> -----Original Message-----
> From: Bruce Richardson <bruce.richardson@intel.com>
> Sent: Tuesday, July 30, 2019 9:02 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> Subject: [EXT] Re: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions
> non-inline
> 
> ----------------------------------------------------------------------
> On Tue, Jul 30, 2019 at 03:01:00PM +0000, Jerin Jacob Kollanukkaran wrote:
> > > -----Original Message----- From: dev <dev-bounces@dpdk.org> On
> > > Behalf Of Marcin Zapolski Sent: Tuesday, July 30, 2019 6:20 PM To:
> > > dev@dpdk.org Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> > > Subject: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions
> > > non- inline
> > >
> > > Make rte_eth_rx_burst, rte_eth_tx_burst and other static inline
> > > ethdev functions not inline. They are referencing DPDK internal
> > > structures and inlining forces those structures to be exposed to user
> applications.
> > >
> > > In internal testing with i40e NICs a performance drop of about 2%
> > > was observed with testpmd.
> >
> > I tested on two class of arm64 machines(Highend and lowend) one has
> > 1.4% drop And other one has 3.6% drop.
> >
> This is with testpmd only right? I'd just point out that we need to remember that
> these numbers need to be scaled down appropriately for a realworld app where
> IO is only a (hopefully small) proportion of the packet processing budget. For
> example, I would expect the ~2% drop we saw in testpmd to correspond to
> <0.5% drop in something like OVS.

I see it as bit different view, Cycles saved infrastructure layer, cycles gained in
application. So IMO it vary between end user application need what kind of
machine it runs.

> 
> > I second to not expose internal data structure to avoid ABI break.
> >
> > IMO, This patch has performance issue due to it is fixing it in simple
> > way.
> >
> > It is not worth two have function call overhead to call the driver
> > function.  Some thoughts below to reduce the performance impact
> > without exposing internal structures.
> >
> The big concern I have with what you propose is that would involve changing
> each and every ethdev driver in DPDK! I'd prefer to make sure that the impact of
> this change is actually felt in real-world apps before we start looking to make
> such updates across the DPDK codebase.

I see those changes are NO BRAINER from driver POV. Once we add in one driver, individual
PMD Maintainer can update easily. I think, we can do it once for all.
I am sure, you must aware of How hard is make 2% improvement in driver. I can spend time in
This NO brainer to get 2% improvement back. I prefer later.


> 
> > And I think, We need to follow the similar mechanism for cryptodev,
> > Eventdev, rawdev Etc so bring the common scheme to address this semantics
> will be use full.
> >
> Agreed.
> 
> Regards,
> /Bruce

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [dpdk-stable] [PATCH] librte_flow_classify: fix out-of-bounds access
  @ 2019-07-30 15:43  2%         ` Aaron Conole
  2019-07-30 16:55  0%           ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Aaron Conole @ 2019-07-30 15:43 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: David Marchand, Bernard Iremonger, dev, dpdk stable,
	Thomas Monjalon, Singh, Jasvinder, Flavia Musatescu,
	Adrien Mazarguil

Ferruh Yigit <ferruh.yigit@intel.com> writes:

> On 7/30/2019 3:42 PM, Aaron Conole wrote:
>> David Marchand <david.marchand@redhat.com> writes:
>> 
>>> On Wed, Jul 10, 2019 at 11:49 PM Thomas Monjalon <thomas@monjalon.net> wrote:
>>>>
>>>> 09/07/2019 13:09, Bernard Iremonger:
>>>>> This patch fixes the out-of-bounds coverity issue by removing the
>>>>> offending line of code at line 107 in rte_flow_classify_parse.c
>>>>> which is never executed.
>>>>>
>>>>> Coverity issue: 343454
>>>>>
>>>>> Fixes: be41ac2a330f ("flow_classify: introduce flow classify library")
>>>>> Cc: stable@dpdk.org
>>>>> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
>>>>
>>>> Applied, thanks
>>>
>>> We have a segfault in the unit tests since this patch.
>> 
>> I think this patch is still correct.  The issue is in the semantic of
>> the flow classify pattern.  It *MUST* always have a valid end marker,
>> but the test passes an invalid end marker.  This causes the bounds to
>> exceed.
>> 
>> So, it would be best to fix it, either by having a "failure" on unknown
>> markers (f.e. -1), or by passing a length around.  However, the crash
>> should be expected.  The fact that the previous code was also incorrect
>> and resulted in no segfault is pure luck.
>> 
>> See rte_flow_classify_parse.c:80 and test_flow_classify.c:387
>> 
>> I would be in favor of passing the lengths of the two arrays to these
>> APIs.  That would let us still make use of the markers (for valid
>> construction), but also let us reason about lengths in a sane way.
>> 
>> WDYT?
>> 
>
> +1, I also just replied with something very similar.
>
> With current API the testcase is wrong, and it will crash, also the invalid
> action one has exact same problem.
>
> The API can be updated as you suggested, with a length field and testcases can
> be added back.
>
> What worries me more is the rte_flow, which uses same arguments, and open to
> same errors, should we consider updating rte_flow APIs to have lengths values too?

Probably.

Here's a first crack at the change I think is appropriate.  I have done
some limited testing.  Let me know if you want me to submit it formally.

---------------------------- 8< ---------------------------------
Subject: [PATCH] rte_flow_classify: fix up the API and preserve ABI

Introduces a new API for doing length validations, and preserves the old semantics
and API.  The previous API couldn't handle corrupted end markers.  A future
version of the API might be able to eschew the end marker and trust the length,
but that is a discussion for future.

Signed-off-by: Aaron Conole <aconole@redhat.com>
---
 app/test/test_flow_classify.c                | 30 +-------
 lib/librte_flow_classify/rte_flow_classify.c | 72 +++++++++++++++++---
 lib/librte_flow_classify/rte_flow_classify.h | 28 ++++++++
 3 files changed, 91 insertions(+), 39 deletions(-)

diff --git a/app/test/test_flow_classify.c b/app/test/test_flow_classify.c
index 6bbaad364..ff5265c6a 100644
--- a/app/test/test_flow_classify.c
+++ b/app/test/test_flow_classify.c
@@ -125,7 +125,6 @@ static struct rte_flow_item  udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP,
 
 static struct rte_flow_item  end_item = { RTE_FLOW_ITEM_TYPE_END,
 	0, 0, 0 };
-static struct rte_flow_item  end_item_bad = { -1, 0, 0, 0 };
 
 /* test TCP pattern:
  * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8
@@ -181,7 +180,6 @@ static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT,
 static struct rte_flow_action count_action_bad = { -1, 0};
 
 static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0};
-static struct rte_flow_action end_action_bad =	{ -1, 0};
 
 static struct rte_flow_action actions[2];
 
@@ -384,7 +382,7 @@ test_invalid_patterns(void)
 
 	pattern[1] = ipv4_udp_item_1;
 	pattern[2] = udp_item_bad;
-	pattern[3] = end_item_bad;
+	pattern[3] = end_item;
 
 	ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
 			actions, &error);
@@ -458,32 +456,6 @@ test_invalid_actions(void)
 		return -1;
 	}
 
-	actions[0] = count_action;
-	actions[1] = end_action_bad;
-
-	ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
-			actions, &error);
-	if (!ret) {
-		printf("Line %i: rte_flow_classify_validate", __LINE__);
-		printf(" should have failed!\n");
-		return -1;
-	}
-
-	rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
-			actions, &key_found, &error);
-	if (rule) {
-		printf("Line %i: flow_classify_table_entry_add", __LINE__);
-		printf(" should have failed!\n");
-		return -1;
-	}
-
-	ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
-	if (!ret) {
-		printf("Line %i: rte_flow_classify_table_entry_delete",
-			__LINE__);
-		printf("should have failed!\n");
-		return -1;
-	}
 	return 0;
 }
 
diff --git a/lib/librte_flow_classify/rte_flow_classify.c b/lib/librte_flow_classify/rte_flow_classify.c
index 5ff585803..3ca1b1b44 100644
--- a/lib/librte_flow_classify/rte_flow_classify.c
+++ b/lib/librte_flow_classify/rte_flow_classify.c
@@ -89,18 +89,51 @@ struct rte_flow_classify_rule {
 	void *entry_ptr; /* handle to the table entry for rule meta data */
 };
 
+static size_t
+calc_flow_item_alen(const struct rte_flow_item pattern[])
+{
+	size_t i = 0;
+	while (pattern && (pattern + i)->type != RTE_FLOW_ITEM_TYPE_END)
+		i++;
+	return i + 1;
+}
+
+static size_t
+calc_flow_action_alen(const struct rte_flow_action actions[])
+{
+	size_t i = 0;
+	while (actions && (actions + i)->type != RTE_FLOW_ACTION_TYPE_END)
+		i++;
+	return i + 1;
+}
+
+int
+rte_flow_classify_validate(struct rte_flow_classifier *cls,
+			   const struct rte_flow_attr *attr,
+			   const struct rte_flow_item pattern[],
+			   const struct rte_flow_action actions[],
+			   struct rte_flow_error *error)
+{
+	return rte_flow_classify_validate_l(cls, attr, pattern,
+					    calc_flow_item_alen(pattern),
+					    actions,
+					    calc_flow_action_alen(actions),
+					    error);
+}
+
 int
-rte_flow_classify_validate(
-		   struct rte_flow_classifier *cls,
-		   const struct rte_flow_attr *attr,
-		   const struct rte_flow_item pattern[],
-		   const struct rte_flow_action actions[],
-		   struct rte_flow_error *error)
+rte_flow_classify_validate_l(struct rte_flow_classifier *cls,
+			     const struct rte_flow_attr *attr,
+			     const struct rte_flow_item pattern[],
+			     size_t pattern_l,
+			     const struct rte_flow_action actions[],
+			     size_t actions_l,
+			     struct rte_flow_error *error)
 {
 	struct rte_flow_item *items;
 	parse_filter_t parse_filter;
 	uint32_t item_num = 0;
-	uint32_t i = 0;
+	size_t i = 0;
 	int ret;
 
 	if (error == NULL)
@@ -134,17 +167,37 @@ rte_flow_classify_validate(
 		return -EINVAL;
 	}
 
+	while (i < actions_l && (actions + i)->type != RTE_FLOW_ACTION_TYPE_END)
+		i++;
+
+	if (i == actions_l) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ACTION_NUM,
+				   NULL, "Actions without end marker.");
+		return -EINVAL;
+	}
+
+	i = 0;
+
 	memset(&cls->ntuple_filter, 0, sizeof(cls->ntuple_filter));
 
 	/* Get the non-void item number of pattern */
-	while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) {
+	while (i < pattern_l && (pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) {
 		if ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_VOID)
 			item_num++;
 		i++;
 	}
+
 	item_num++;
 
-	items = malloc(item_num * sizeof(struct rte_flow_item));
+	if (i == pattern_l) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM,
+				   NULL, "Pattern without end marker.");
+		return -EINVAL;
+	}
+
+	items = calloc(item_num, sizeof(struct rte_flow_item));
 	if (!items) {
 		rte_flow_error_set(error, ENOMEM,
 				RTE_FLOW_ERROR_TYPE_ITEM_NUM,
@@ -152,7 +205,6 @@ rte_flow_classify_validate(
 		return -ENOMEM;
 	}
 
-	memset(items, 0, item_num * sizeof(struct rte_flow_item));
 	classify_pattern_skip_void_item(items, pattern);
 
 	parse_filter = classify_find_parse_filter_func(items);
diff --git a/lib/librte_flow_classify/rte_flow_classify.h b/lib/librte_flow_classify/rte_flow_classify.h
index 74d1ecaf5..0308f6fd2 100644
--- a/lib/librte_flow_classify/rte_flow_classify.h
+++ b/lib/librte_flow_classify/rte_flow_classify.h
@@ -186,6 +186,34 @@ int
 rte_flow_classify_table_create(struct rte_flow_classifier *cls,
 		struct rte_flow_classify_table_params *params);
 
+/**
+ * Flow classify validate
+ *
+ * @param cls
+ *   Handle to flow classifier instance
+ * @param[in] attr
+ *   Flow rule attributes
+ * @param[in] pattern
+ *   Pattern specification (list terminated by the END pattern item).
+ * @param[in] actions
+ *   Associated actions (list terminated by the END pattern item).
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL. Structure
+ *   initialised in case of error only.
+ * @return
+ *   0 on success, error code otherwise
+ */
+__rte_experimental
+int
+rte_flow_classify_validate_l(struct rte_flow_classifier *cls,
+			     const struct rte_flow_attr *attr,
+			     const struct rte_flow_item pattern[],
+			     const size_t pattern_l,
+			     const struct rte_flow_action actions[],
+			     const size_t actions_l,
+			     struct rte_flow_error *error);
+
+
 /**
  * Flow classify validate
  *
-- 
2.21.0


^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline
  2019-07-30 15:01  3%   ` Jerin Jacob Kollanukkaran
@ 2019-07-30 15:32  0%     ` Bruce Richardson
  0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-07-30 15:32 UTC (permalink / raw)
  To: Jerin Jacob Kollanukkaran; +Cc: Marcin Zapolski, dev

On Tue, Jul 30, 2019 at 03:01:00PM +0000, Jerin Jacob Kollanukkaran wrote:
> > -----Original Message----- From: dev <dev-bounces@dpdk.org> On Behalf
> > Of Marcin Zapolski Sent: Tuesday, July 30, 2019 6:20 PM To:
> > dev@dpdk.org Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> > Subject: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions
> > non- inline
> > 
> > Make rte_eth_rx_burst, rte_eth_tx_burst and other static inline ethdev
> > functions not inline. They are referencing DPDK internal structures and
> > inlining forces those structures to be exposed to user applications.
> > 
> > In internal testing with i40e NICs a performance drop of about 2% was
> > observed with testpmd.
> 
> I tested on two class of arm64 machines(Highend and lowend) one has 1.4%
> drop And other one has 3.6% drop.
>
This is with testpmd only right? I'd just point out that we need to
remember that these numbers need to be scaled down appropriately for a
realworld app where IO is only a (hopefully small) proportion of the packet
processing budget. For example, I would expect the ~2% drop we saw in
testpmd to correspond to <0.5% drop in something like OVS.
 
> I second to not expose internal data structure to avoid ABI break.
> 
> IMO, This patch has performance issue due to it is fixing it in simple
> way.
> 
> It is not worth two have function call overhead to call the driver
> function.  Some thoughts below to reduce the performance impact without
> exposing internal structures.
> 
The big concern I have with what you propose is that would involve changing
each and every ethdev driver in DPDK! I'd prefer to make sure that the
impact of this change is actually felt in real-world apps before we start
looking to make such updates across the DPDK codebase.

> And I think, We need to follow the similar mechanism for cryptodev, Eventdev, rawdev
> Etc so bring the common scheme to address this semantics will be use full.
> 
Agreed.

Regards,
/Bruce

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline
  @ 2019-07-30 15:01  3%   ` Jerin Jacob Kollanukkaran
  2019-07-30 15:32  0%     ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-07-30 15:01 UTC (permalink / raw)
  To: Marcin Zapolski, dev

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Marcin Zapolski
> Sent: Tuesday, July 30, 2019 6:20 PM
> To: dev@dpdk.org
> Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> Subject: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-
> inline
> 
> Make rte_eth_rx_burst, rte_eth_tx_burst and other static inline ethdev
> functions not inline. They are referencing DPDK internal structures and
> inlining forces those structures to be exposed to user applications.
> 
> In internal testing with i40e NICs a performance drop of about 2% was
> observed with testpmd.

I tested on two class of arm64 machines(Highend and lowend) one has 1.4% drop
And other one has 3.6% drop.

I second to not expose internal data structure to avoid ABI break.

IMO, This patch has performance issue due to it is fixing it in simple way.

It is not worth two have function call overhead to call the driver function.
Some thoughts below to reduce the performance impact without exposing internal 
structures.

And I think, We need to follow the similar mechanism for cryptodev, Eventdev, rawdev
Etc so bring the common scheme to address this semantics will be use full.

> 
> Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> ---
>  lib/librte_ethdev/rte_ethdev.c           | 168 +++++++++++++++++++++++
>  lib/librte_ethdev/rte_ethdev.h           | 166 ++--------------------
>  lib/librte_ethdev/rte_ethdev_version.map |  12 ++
>  3 files changed, 195 insertions(+), 151 deletions(-)
> 
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index 17d183e1f..31432a956 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -749,6 +749,174 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id)
>  	return rte_eth_devices[port_id].security_ctx;
>  }
> 
> +uint16_t
> +rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id,
> +		 struct rte_mbuf **rx_pkts, const uint16_t nb_pkts) {
> +	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
> +	uint16_t nb_rx;

I think, we only need to store 3 function pointers per port.
IMO, Let have structure for that.

i.e split the struct rte_eth_dev content as public and private.
I think, We nee only following elements in rte_eth_dev
struct rte_eth_dev_fns {
        eth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */
        eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
        eth_tx_prep_t tx_pkt_prepare; /**< Pointer to PMD transmit prepare function. *
};
struct rte_eth_dev  {
	struct rte_eth_dev_fns fns; // make it as first item allows type cast to struct rte_eth_dev_fns from struct rte_eth_dev  
               private ones
}


> +
> +#ifdef RTE_LIBRTE_ETHDEV_DEBUG
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->rx_pkt_burst, 0);
> +
> +	if (queue_id >= dev->data->nb_rx_queues) {
> +		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n",
> queue_id);
> +		return 0;
> +	}
> +#endif
> +	nb_rx = (*dev->rx_pkt_burst)(dev->data->rx_queues[queue_id],

I think, if we make driver funtions as (*dev->rx_pkt_burst)(dev, rx_pkts, nb_pkts)
Then no need to deference data from inline function.
Lets expose a helper function from driver layer and let PMD use to access queue memory.
No need to expose that helper to user app.

> +				     rx_pkts, nb_pkts);
> +
> +#ifdef RTE_ETHDEV_RXTX_CALLBACKS

# If we have ethdev driver helper function  for the same and PMD can call it as well no need
to call this inline function.
# I think, it make sense to as RX_OFFLOAD_FLAGS so that when app needs only
It can be included in fastpath.

# lastly we are not exposing rte_eth_dev to application then I think we can
Remove rte_ from name.


> +	if (unlikely(dev->post_rx_burst_cbs[queue_id] != NULL)) {
> +		struct rte_eth_rxtx_callback *cb =
> +				dev->post_rx_burst_cbs[queue_id];
> +
> +		do {
> +			nb_rx = cb->fn.rx(port_id, queue_id, rx_pkts, nb_rx,
> +						nb_pkts, cb->param);
> +			cb = cb->next;
> +		} while (cb != NULL);
> +	}
> +#endif
> +
> +	return nb_rx;
> +}
> +
>


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2 2/2] drivers/raw: standardize naming
  @ 2019-07-30 13:39  7%   ` Thomas Monjalon
  2019-07-31  7:29  0%     ` Xu, Rosen
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-07-30 13:39 UTC (permalink / raw)
  To: dev, John McNamara, Marko Kovacevic, Nipun Gupta, Rosen Xu,
	Tianfei zhang, Bruce Richardson, Xiaoyun Li, Jingjing Wu,
	Satha Rao, Vamsi Attunuru, Shreyansh Jain, Hemant Agrawal
  Cc: Neil Horman

From: Bruce Richardson <bruce.richardson@intel.com>

The driver names for rawdevs were both different in make and meson builds
and were non-standard in the make version in that some included "rawdev" in
the name while others didn't.

Therefore, for global consistency of naming, we can use "rte_rawdev" rather
than "rte_pmd" for the prefix for the libraries. While most other driver
categories use "rte_pmd" as a prefix, there is precedent for this in the
mempool drivers use "rte_mempool" as a prefix.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 doc/guides/rel_notes/release_19_08.rst             |  3 +++
 drivers/raw/dpaa2_cmdif/Makefile                   |  4 ++--
 ...sion.map => rte_rawdev_dpaa2_cmdif_version.map} |  0
 drivers/raw/dpaa2_qdma/Makefile                    |  4 ++--
 ...rsion.map => rte_rawdev_dpaa2_qdma_version.map} |  0
 drivers/raw/ifpga/Makefile                         |  4 ++--
 ...ga_version.map => rte_rawdev_ifpga_version.map} |  0
 drivers/raw/ioat/Makefile                          |  4 ++--
 ...oat_version.map => rte_rawdev_ioat_version.map} |  0
 drivers/raw/meson.build                            |  2 +-
 drivers/raw/ntb/Makefile                           |  4 ++--
 ..._ntb_version.map => rte_rawdev_ntb_version.map} |  0
 drivers/raw/octeontx2_dma/Makefile                 |  4 ++--
 ...on.map => rte_rawdev_octeontx2_dma_version.map} |  0
 drivers/raw/skeleton/Makefile                      |  4 ++--
 ...version.map => rte_rawdev_skeleton_version.map} |  0
 mk/rte.app.mk                                      | 14 +++++++-------
 17 files changed, 25 insertions(+), 22 deletions(-)
 rename drivers/raw/dpaa2_cmdif/{rte_pmd_dpaa2_cmdif_version.map => rte_rawdev_dpaa2_cmdif_version.map} (100%)
 rename drivers/raw/dpaa2_qdma/{rte_pmd_dpaa2_qdma_version.map => rte_rawdev_dpaa2_qdma_version.map} (100%)
 rename drivers/raw/ifpga/{rte_pmd_ifpga_version.map => rte_rawdev_ifpga_version.map} (100%)
 rename drivers/raw/ioat/{rte_pmd_ioat_version.map => rte_rawdev_ioat_version.map} (100%)
 rename drivers/raw/ntb/{rte_pmd_ntb_version.map => rte_rawdev_ntb_version.map} (100%)
 rename drivers/raw/octeontx2_dma/{rte_pmd_octeontx2_dma_version.map => rte_rawdev_octeontx2_dma_version.map} (100%)
 rename drivers/raw/skeleton/{rte_pmd_skeleton_version.map => rte_rawdev_skeleton_version.map} (100%)

diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index fcd1386a5..13a98f520 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -351,6 +351,9 @@ ABI Changes
 * bbdev: New operations and parameters added to support new 5GNR operations.
   The bbdev ABI is still kept experimental.
 
+* rawdev: The driver names have been changed to ``librte_rawdev_*``.
+  Now they all have the same prefix, and same name with make and meson builds.
+
 
 Shared Library Versions
 -----------------------
diff --git a/drivers/raw/dpaa2_cmdif/Makefile b/drivers/raw/dpaa2_cmdif/Makefile
index 9bd5ff229..2b4150c2d 100644
--- a/drivers/raw/dpaa2_cmdif/Makefile
+++ b/drivers/raw/dpaa2_cmdif/Makefile
@@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 # library name
 #
-LIB = librte_pmd_dpaa2_cmdif.a
+LIB = librte_rawdev_dpaa2_cmdif.a
 
 CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
@@ -23,7 +23,7 @@ LDLIBS += -lrte_mempool_dpaa2
 LDLIBS += -lrte_rawdev
 LDLIBS += -lrte_common_dpaax
 
-EXPORT_MAP := rte_pmd_dpaa2_cmdif_version.map
+EXPORT_MAP := rte_rawdev_dpaa2_cmdif_version.map
 
 LIBABIVER := 2
 
diff --git a/drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map b/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
similarity index 100%
rename from drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map
rename to drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile
index f9a810cc6..0009fd4c6 100644
--- a/drivers/raw/dpaa2_qdma/Makefile
+++ b/drivers/raw/dpaa2_qdma/Makefile
@@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 # library name
 #
-LIB = librte_pmd_dpaa2_qdma.a
+LIB = librte_rawdev_dpaa2_qdma.a
 
 CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
@@ -24,7 +24,7 @@ LDLIBS += -lrte_kvargs
 LDLIBS += -lrte_ring
 LDLIBS += -lrte_common_dpaax
 
-EXPORT_MAP := rte_pmd_dpaa2_qdma_version.map
+EXPORT_MAP := rte_rawdev_dpaa2_qdma_version.map
 
 LIBABIVER := 3
 
diff --git a/drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
similarity index 100%
rename from drivers/raw/dpaa2_qdma/rte_pmd_dpaa2_qdma_version.map
rename to drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
diff --git a/drivers/raw/ifpga/Makefile b/drivers/raw/ifpga/Makefile
index 5fa9303d5..655b29288 100644
--- a/drivers/raw/ifpga/Makefile
+++ b/drivers/raw/ifpga/Makefile
@@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 # library name
 #
-LIB = librte_pmd_ifpga_rawdev.a
+LIB = librte_rawdev_ifpga.a
 
 CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
@@ -21,7 +21,7 @@ LDLIBS += -lrte_kvargs
 LDLIBS += -lrte_bus_pci
 LDLIBS += -lrte_bus_ifpga
 
-EXPORT_MAP := rte_pmd_ifpga_version.map
+EXPORT_MAP := rte_rawdev_ifpga_version.map
 
 LIBABIVER := 1
 
diff --git a/drivers/raw/ifpga/rte_pmd_ifpga_version.map b/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
similarity index 100%
rename from drivers/raw/ifpga/rte_pmd_ifpga_version.map
rename to drivers/raw/ifpga/rte_rawdev_ifpga_version.map
diff --git a/drivers/raw/ioat/Makefile b/drivers/raw/ioat/Makefile
index 32f079845..e852afb57 100644
--- a/drivers/raw/ioat/Makefile
+++ b/drivers/raw/ioat/Makefile
@@ -4,7 +4,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 # library name
-LIB = librte_pmd_ioat_rawdev.a
+LIB = librte_rawdev_ioat.a
 
 # build flags
 CFLAGS += -O3
@@ -18,7 +18,7 @@ LDLIBS += -lrte_mbuf -lrte_mempool
 LIBABIVER := 1
 
 # versioning export map
-EXPORT_MAP := rte_pmd_ioat_version.map
+EXPORT_MAP := rte_rawdev_ioat_version.map
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV) += ioat_rawdev.c
diff --git a/drivers/raw/ioat/rte_pmd_ioat_version.map b/drivers/raw/ioat/rte_rawdev_ioat_version.map
similarity index 100%
rename from drivers/raw/ioat/rte_pmd_ioat_version.map
rename to drivers/raw/ioat/rte_rawdev_ioat_version.map
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index bcd5553e1..d7037cd87 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -7,4 +7,4 @@ drivers = ['dpaa2_cmdif', 'dpaa2_qdma',
 	'skeleton']
 std_deps = ['rawdev']
 config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
-driver_name_fmt = 'rte_pmd_@0@'
+driver_name_fmt = 'rte_rawdev_@0@'
diff --git a/drivers/raw/ntb/Makefile b/drivers/raw/ntb/Makefile
index edd49fe75..6fe2aaf40 100644
--- a/drivers/raw/ntb/Makefile
+++ b/drivers/raw/ntb/Makefile
@@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 # library name
 #
-LIB = librte_pmd_ntb.a
+LIB = librte_rawdev_ntb.a
 
 CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
@@ -15,7 +15,7 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_pci -lrte_bus_pci
 LDLIBS += -lrte_rawdev
 
-EXPORT_MAP := rte_pmd_ntb_version.map
+EXPORT_MAP := rte_rawdev_ntb_version.map
 
 LIBABIVER := 1
 
diff --git a/drivers/raw/ntb/rte_pmd_ntb_version.map b/drivers/raw/ntb/rte_rawdev_ntb_version.map
similarity index 100%
rename from drivers/raw/ntb/rte_pmd_ntb_version.map
rename to drivers/raw/ntb/rte_rawdev_ntb_version.map
diff --git a/drivers/raw/octeontx2_dma/Makefile b/drivers/raw/octeontx2_dma/Makefile
index 96f782eb6..f101e4916 100644
--- a/drivers/raw/octeontx2_dma/Makefile
+++ b/drivers/raw/octeontx2_dma/Makefile
@@ -5,7 +5,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 # library name
-LIB = librte_pmd_octeontx2_dma.a
+LIB = librte_rawdev_octeontx2_dma.a
 
 CFLAGS += -O3 $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx2/
@@ -22,7 +22,7 @@ CFLAGS += -diag-disable 2259
 endif
 endif
 
-EXPORT_MAP := rte_pmd_octeontx2_dma_version.map
+EXPORT_MAP := rte_rawdev_octeontx2_dma_version.map
 
 LIBABIVER := 1
 
diff --git a/drivers/raw/octeontx2_dma/rte_pmd_octeontx2_dma_version.map b/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
similarity index 100%
rename from drivers/raw/octeontx2_dma/rte_pmd_octeontx2_dma_version.map
rename to drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
diff --git a/drivers/raw/skeleton/Makefile b/drivers/raw/skeleton/Makefile
index 9641e6505..783b1e952 100644
--- a/drivers/raw/skeleton/Makefile
+++ b/drivers/raw/skeleton/Makefile
@@ -6,7 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 # library name
 #
-LIB = librte_pmd_skeleton_rawdev.a
+LIB = librte_rawdev_skeleton.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
@@ -15,7 +15,7 @@ LDLIBS += -lrte_rawdev
 LDLIBS += -lrte_bus_vdev
 LDLIBS += -lrte_kvargs
 
-EXPORT_MAP := rte_pmd_skeleton_version.map
+EXPORT_MAP := rte_rawdev_skeleton_version.map
 
 LIBABIVER := 1
 
diff --git a/drivers/raw/skeleton/rte_pmd_skeleton_version.map b/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
similarity index 100%
rename from drivers/raw/skeleton/rte_pmd_skeleton_version.map
rename to drivers/raw/skeleton/rte_rawdev_skeleton_version.map
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a277c808e..ba5c39e01 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -312,19 +312,19 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV) += -lrte_pmd_opdl_event
 endif # CONFIG_RTE_LIBRTE_EVENTDEV
 
 ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_rawdev_skeleton
 ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += -lrte_pmd_dpaa2_cmdif
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += -lrte_rawdev_dpaa2_cmdif
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_rawdev_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_pmd_ifpga_rawdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_pmd_ioat_rawdev
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_DMA_RAWDEV) += -lrte_pmd_octeontx2_dma
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_rawdev_ioat
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_rawdev_ntb
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_DMA_RAWDEV) += -lrte_rawdev_octeontx2_dma
 endif # CONFIG_RTE_LIBRTE_RAWDEV
 
 endif # !CONFIG_RTE_BUILD_SHARED_LIBS
-- 
2.21.0


^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v1] doc: update release notes for 19.08
@ 2019-07-30 13:24 14% John McNamara
  0 siblings, 0 replies; 200+ results
From: John McNamara @ 2019-07-30 13:24 UTC (permalink / raw)
  To: dev; +Cc: thomas, John McNamara

Fix grammar, spelling and formatting of DPDK 19.08 release notes.

Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_19_08.rst | 126 ++++++++++++++++-----------------
 1 file changed, 63 insertions(+), 63 deletions(-)

diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index fcd1386..78df3e1 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -58,20 +58,20 @@ New Features
 
 * **EAL will now pick IOVA as VA mode as the default in most cases.**
 
-  Previously, preferred default IOVA mode was selected to be IOVA as PA. The
+  Previously, the preferred default IOVA mode was selected to be IOVA as PA. The
   behavior has now been changed to handle IOVA mode detection in a more complex
   manner, and will default to IOVA as VA in most cases.
 
 * **Added MCS lock.**
 
   MCS lock provides scalability by spinning on a CPU/thread local variable
-  which avoids expensive cache bouncings.
+  which avoids expensive cache bouncing.
   It provides fairness by maintaining a list of acquirers and passing
   the lock to each CPU/thread in the order they acquired the lock.
 
 * **Updated the EAL Pseudo-random Number Generator.**
 
-  The lrand48()-based rte_rand() function is replaced with a
+  The ``lrand48()`` based ``rte_rand()`` function is replaced with a
   DPDK-native combined Linear Feedback Shift Register (LFSR)
   pseudo-random number generator (PRNG).
 
@@ -79,33 +79,33 @@ New Features
   higher-quality pseudo-random numbers (including full 64 bit
   support) and improved performance.
 
-  In addition, <rte_random.h> is extended with a new function
-  rte_rand_max() which supplies unbiased, bounded pseudo-random
+  In addition, ``<rte_random.h>`` is extended with a new function
+  ``rte_rand_max()`` which supplies unbiased, bounded pseudo-random
   numbers.
 
-* **Updated the bnxt PMD.**
+* **Updated the Broadcom bnxt PMD.**
 
-  Updated the bnxt PMD. The major enhancements include:
+  Updated the Broadcom bnxt PMD. The major enhancements include:
 
-  * Performance optimizations in non-vector Tx path
-  * Added support for SSE vector mode
-  * Updated HWRM API to version 1.10.0.91
+  * Performance optimizations in non-vector Tx path.
+  * Added support for SSE vector mode.
+  * Updated HWRM API to version 1.10.0.91.
 
 * **Added support for Broadcom NetXtreme-E BCM57500 Ethernet controllers.**
 
-  Added support to the bnxt PMD for the BCM57500 (a.k.a. "Thor") family
+  Added support to the Broadcom bnxt PMD for the BCM57500 (a.k.a. "Thor") family
   of Ethernet controllers. These controllers support link speeds up to
   200Gbps, 50G PAM-4, and PCIe 4.0.
 
-* **Added hinic PMD.**
+* **Added Huawei hinic PMD.**
 
   Added the new ``hinic`` net driver for Huawei Intelligent PCIE Network
   Adapters based on the Huawei Ethernet Controller Hi1822.
   See the :doc:`../nics/hinic` guide for more details on this new driver.
 
-* **Updated the ice driver.**
+* **Updated the Intel ice driver.**
 
-  Updated ice driver with new features and improvements, including:
+  Updated the Intel ice driver with new features and improvements, including:
 
   * Enabled Tx outer/inner L3/L4 checksum offload.
   * Enabled generic filter framework and supported switch filter.
@@ -120,8 +120,8 @@ New Features
   * Added support for match on ICMP/ICMP6 code and type.
   * Added support for matching on GRE's key and C,K,S present bits.
   * Added support for IP-in-IP tunnel.
-  * Accelerate flows with count action creation and destroy.
-  * Accelerate flows counter query.
+  * Accelerated flows with count action creation and destroy.
+  * Accelerated flows counter query.
   * Improved Tx datapath performance with enabled HW offloads.
   * Added support for LRO.
 
@@ -133,7 +133,7 @@ New Features
 
 * **Added memif PMD.**
 
-  Added the new Shared Memory Packet Interface (``memif``) PMD.
+  Added a new Shared Memory Packet Interface (``memif``) PMD.
   See the :doc:`../nics/memif` guide for more details on this new driver.
 
 * **Updated the AF_XDP PMD.**
@@ -141,31 +141,31 @@ New Features
   Updated the AF_XDP PMD. The new features include:
 
   * Enabled zero copy through mbuf's external memory mechanism to achieve
-    high performance
+    higher performance.
   * Added multi-queue support to allow one af_xdp vdev with multiple netdev
-    queues
-  * Enabled need_wakeup feature which can provide efficient support for case
-    that application and driver executing on the same core.
+    queues.
+  * Enabled "need_wakeup" feature which can provide efficient support for the
+    usecase where the application and driver executing on the same core.
 
 * **Enabled infinite Rx in the PCAP PMD.**
 
-  Added an infinite Rx feature which allows packets in the Rx PCAP of a PCAP
-  device to be received repeatedly at a high rate. This can be useful for quick
+  Added an infinite Rx feature to the PCAP PMD which allows packets in the Rx
+  PCAP to be received repeatedly at a high rate. This can be useful for quick
   performance testing of DPDK apps.
 
-* **Enabled Receiving no packet on PCAP Rx.**
+* **Enabled receiving no packet in the PCAP PMD.**
 
-  Added function to allow users to run without receiving any packets on PCAP Rx.
-  When function is called, a dummy queue is created for each Tx queue argument
-  passed.
+  Added function to allow users to run the PCAP PMD without receiving any
+  packets on PCAP Rx. When the function is called, a dummy queue is created
+  for each Tx queue argument passed.
 
 * **Added a FPGA_LTE_FEC bbdev PMD.**
 
-  Added the new ``fpga_lte_fec`` bbdev driver for the Intel® FPGA PAC
+  Added a new ``fpga_lte_fec`` bbdev driver for the Intel\ |reg| FPGA PAC
   (Programmable  Acceleration Card) N3000.  See the
   :doc:`../bbdevs/fpga_lte_fec` BBDEV guide for more details on this new driver.
 
-* **Updated TURBO_SW bbdev PMD.**
+* **Updated the TURBO_SW bbdev PMD.**
 
   Updated the ``turbo_sw`` bbdev driver with changes including:
 
@@ -173,17 +173,17 @@ New Features
     SDK libraries.
   * Added support for 5GNR encode/decode operations.
 
-* **Updated the QuickAssist Technology (QAT) symmetric crypto PMD.**
+* **Updated the Intel QuickAssist Technology (QAT) symmetric crypto PMD.**
 
   Added support for digest-encrypted cases where digest is appended
   to the data.
 
-* **Added Intel QuickData Technology PMD**
+* **Added the Intel QuickData Technology PMD.**
 
-  The PMD for Intel\ |reg|  QuickData Technology, part of
+  Added a PMD for the Intel\ |reg|  QuickData Technology, part of
   Intel\ |reg|  I/O Acceleration Technology `(Intel I/OAT)
   <https://www.intel.com/content/www/us/en/wireless-network/accel-technology.html>`_,
-  allows data copies to be done by hardware instead
+  which allows data copies to be done by hardware instead
   of via software, reducing cycles spent copying large blocks of data in
   applications.
 
@@ -191,25 +191,25 @@ New Features
 
   Added the new ``ethdev``, ``eventdev``, ``mempool``, ``eventdev Rx adapter``,
   ``eventdev Tx adapter``, ``eventdev Timer adapter`` and ``rawdev DMA``
-  drivers for various HW coprocessors available in ``OCTEON TX2`` SoC.
+  drivers for various HW co-processors available in ``OCTEON TX2`` SoC.
 
-  See :doc:`../platform/octeontx2` and driver informations:
+  See :doc:`../platform/octeontx2` and driver information:
 
   * :doc:`../nics/octeontx2`
   * :doc:`../mempool/octeontx2`
   * :doc:`../eventdevs/octeontx2`
   * :doc:`../rawdevs/octeontx2_dma`
 
-* **Introduced NTB PMD.**
+* **Introduced the Intel NTB PMD.**
 
-  Added a PMD for Intel NTB (Non-transparent Bridge). This PMD implemented
-  handshake between two separate hosts and can share local memory for peer
+  Added a PMD for Intel NTB (Non-transparent Bridge). This PMD implements
+  a handshake between two separate hosts and can share local memory for peer
   host to directly access.
 
-* **Updated IPSec library and IPsec Security Gateway application.**
+* **Updated the IPSec library and IPsec Security Gateway application.**
 
   Added the following features to ``librte_ipsec``. Corresponding changes are
-  also added in ``ipsec-secgw`` sample application.
+  also added in the ``ipsec-secgw`` sample application.
 
   * ECN and DSCP field header reconstruction as per RFC4301.
   * Transport mode with IPv6 extension headers.
@@ -222,8 +222,8 @@ New Features
 
 * **Added new telemetry mode for l3fwd-power application.**
 
-  Added telemetry mode to l3fwd-power application to report
-  application level busyness, empty and full polls of rte_eth_rx_burst().
+  Added a telemetry mode to the ``l3fwd-power`` application to report
+  application level busyness, empty and full polls of ``rte_eth_rx_burst()``.
 
 * **Updated the pdump application.**
 
@@ -231,7 +231,7 @@ New Features
 
 * **Updated test-compress-perf tool application.**
 
-  Added multiple cores feature to compression perf tool application.
+  Added a multiple cores feature to the compression perf tool application.
 
 
 Removed Items
@@ -246,7 +246,7 @@ Removed Items
    Also, make sure to start the actual text at the margin.
    =========================================================
 
-* Removed KNI ethtool, CONFIG_RTE_KNI_KMOD_ETHTOOL, support.
+* Removed KNI ethtool, ``CONFIG_RTE_KNI_KMOD_ETHTOOL``, support.
 
 * build: armv8 crypto extension is disabled.
 
@@ -266,17 +266,17 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
-* The ``rte_mem_config`` structure has been made private. The new accessor
+* The ``rte_mem_config`` structure has been made private. New accessor
   ``rte_mcfg_*`` functions were introduced to provide replacement for direct
   access to the shared mem config.
 
 * The network structures, definitions and functions have
   been prefixed by ``rte_`` to resolve conflicts with libc headers.
 
-* malloc: The function ``rte_malloc_set_limit`` was never implemented
-  is deprecated and will be removed in a future release.
+* malloc: The function ``rte_malloc_set_limit()`` was never implemented.
+  It is deprecated and will be removed in a future release.
 
-* cryptodev: the ``uint8_t *data`` member of ``key`` structure in the xforms
+* cryptodev: the ``uint8_t *data`` member of the ``key`` structure in the xforms
   structure (``rte_crypto_cipher_xform``, ``rte_crypto_auth_xform``, and
   ``rte_crypto_aead_xform``) have been changed to ``const uint8_t *data``.
 
@@ -287,8 +287,8 @@ API Changes
   announced at least one release before the ABI change is made. There are no
   ABI breaking changes planned.
 
-* ip_frag: IP fragmentation library converts input mbuf into fragments
-  using input MTU size via ``rte_ipv4_fragment_packet`` interface.
+* ip_frag: The IP fragmentation library converts input mbuf into fragments
+  using input MTU size via the ``rte_ipv4_fragment_packet()`` interface.
   Once fragmentation is done, each ``mbuf->ol_flags`` are set to enable IP
   checksum H/W offload irrespective of the platform capability.
   Cleared IP checksum H/W offload flag from the library. The application must
@@ -296,7 +296,7 @@ API Changes
   use it.
 
 * ip_frag: IP reassembly library converts the list of fragments into a
-  reassembled packet via ``rte_ipv4_frag_reassemble_packet`` interface.
+  reassembled packet via ``rte_ipv4_frag_reassemble_packet()`` interface.
   Once reassembly is done, ``mbuf->ol_flags`` are set to enable IP checksum H/W
   offload irrespective of the platform capability. Cleared IP checksum H/W
   offload flag from the library. The application must set this flag if it is
@@ -305,10 +305,11 @@ API Changes
 * sched: Macros ``RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS`` and
   ``RTE_SCHED_PIPE_PROFILES_PER_PORT`` are removed for flexible configuration
   of pipe traffic classes and their queues size, and for runtime configuration
-  of maximum number of pipe profiles, respectively. In addtion, wrr_weights
-  field of struct ``rte_sched_pipe_params`` is modifed to be used only for
-  best-effort tc, and qsize field of struct ``rte_sched_port_params`` is
-  changed to allow different size of the each queue.
+  of the maximum number of pipe profiles, respectively. In addition, the
+  ``wrr_weights`` field of struct ``rte_sched_pipe_params`` is modified to be
+  used only for best-effort tc, and the ``qsize`` field of struct
+  ``rte_sched_port_params`` is changed to allow different sizes for each
+  queue.
 
 
 ABI Changes
@@ -342,14 +343,14 @@ ABI Changes
   disable features supported by the crypto device. Only the following features
   would be allowed to be disabled this way,
 
-  - ``RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO``
-  - ``RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO``
-  - ``RTE_CRYPTODEV_FF_SECURITY``
+  - ``RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO``.
+  - ``RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO``.
+  - ``RTE_CRYPTODEV_FF_SECURITY``.
 
   Disabling unused features would facilitate efficient usage of HW/SW offload.
 
-* bbdev: New operations and parameters added to support new 5GNR operations.
-  The bbdev ABI is still kept experimental.
+* bbdev: New operations and parameters have been added to support new 5GNR
+  operations. The bbdev ABI is still kept experimental.
 
 
 Shared Library Versions
@@ -444,11 +445,11 @@ Known Issues
    Also, make sure to start the actual text at the margin.
    =========================================================
 
-* **Unsuitable IOVA mode may be picked as the default**
+* **Unsuitable IOVA mode may be picked as the default.**
 
   Not all kernel drivers and not all devices support all IOVA modes. EAL will
   attempt to pick a reasonable default based on a number of factors, but
-  there may be cases where the default may be unsuitable.
+  there may be cases where the default is unsuitable.
 
   It is recommended to use the `--iova-mode` command-line parameter if the
   default is not suitable.
@@ -472,4 +473,3 @@ Tested Platforms
    This section is a comment. Do not overwrite or remove it.
    Also, make sure to start the actual text at the margin.
    =========================================================
-
-- 
2.7.5


^ permalink raw reply	[relevance 14%]

* Re: [dpdk-dev] [PATCH] doc: Changes to ABI Policy introducing major ABI versions
  2019-07-30 10:34 10%   ` Mcnamara, John
@ 2019-07-30 10:35  5%     ` Ray Kinsella
  0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-07-30 10:35 UTC (permalink / raw)
  To: Mcnamara, John, dev

Thanks John,

I will fix it.

Ray K

On 30/07/2019 11:34, Mcnamara, John wrote:
> 
> 
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ray Kinsella
>> Sent: Thursday, July 4, 2019 1:27 PM
>> To: dev@dpdk.org
>> Cc: mdr@ashroe.eu
>> Subject: [dpdk-dev] [PATCH] doc: Changes to ABI Policy introducing major
>> ABI versions
>>
>> This policy change introduces major ABI versions, these are declared every
>> two years, typically aligned with the LTS release and are supported by
>> subsequent releases for the next two years.
>> This change is intended to improve ABI stabilty for those projects
>> consuming DPDK.
>>
> 
> 
> 
>> ...
>>
>> +A LTS release may align with the declaration of a new major ABI
>> +version, please read the `DPDK ABI/API policy`_ for more information.
> 
> This should be  `<DPDK ABI/API policy>`_ to avoid a build warning/error
> since the target contains spaces.
> 
> Also, the subject line should be lowercase by convention, apart from acronyms.
> 
>     $ ./devtools/check-git-log.sh 
>     Wrong headline uppercase:
>         doc: >C<hanges to ABI Policy introducing major ABI versions
> 
> Something like:
> 
>     doc: changes to ABI policy introducing major ABI versions
> 
> John
> 
> 

^ permalink raw reply	[relevance 5%]

* Re: [dpdk-dev] [PATCH] doc: Changes to ABI Policy introducing major ABI versions
  @ 2019-07-30 10:34 10%   ` Mcnamara, John
  2019-07-30 10:35  5%     ` Ray Kinsella
  0 siblings, 1 reply; 200+ results
From: Mcnamara, John @ 2019-07-30 10:34 UTC (permalink / raw)
  To: Ray Kinsella, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ray Kinsella
> Sent: Thursday, July 4, 2019 1:27 PM
> To: dev@dpdk.org
> Cc: mdr@ashroe.eu
> Subject: [dpdk-dev] [PATCH] doc: Changes to ABI Policy introducing major
> ABI versions
> 
> This policy change introduces major ABI versions, these are declared every
> two years, typically aligned with the LTS release and are supported by
> subsequent releases for the next two years.
> This change is intended to improve ABI stabilty for those projects
> consuming DPDK.
> 



>...
> 
> +A LTS release may align with the declaration of a new major ABI
> +version, please read the `DPDK ABI/API policy`_ for more information.

This should be  `<DPDK ABI/API policy>`_ to avoid a build warning/error
since the target contains spaces.

Also, the subject line should be lowercase by convention, apart from acronyms.

    $ ./devtools/check-git-log.sh 
    Wrong headline uppercase:
        doc: >C<hanges to ABI Policy introducing major ABI versions

Something like:

    doc: changes to ABI policy introducing major ABI versions

John



^ permalink raw reply	[relevance 10%]

* Re: [dpdk-dev] [RFC,v3] ethdev: extend RSS offload types
  @ 2019-07-30  7:42  4%     ` Adrien Mazarguil
  0 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2019-07-30  7:42 UTC (permalink / raw)
  To: Ori Kam; +Cc: simei, qi.z.zhang, jingjing.wu, ferruh.yigit, dev

On Tue, Jul 30, 2019 at 06:06:56AM +0000, Ori Kam wrote:
> Hi Simei,
> 
> 
> 
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of simei
> > Sent: Monday, July 29, 2019 5:44 AM
> > To: qi.z.zhang@intel.com; jingjing.wu@intel.com; ferruh.yigit@intel.com;
> > Adrien Mazarguil <adrien.mazarguil@6wind.com>
> > Cc: dev@dpdk.org; simei.su@intel.com
> > Subject: [dpdk-dev] [RFC,v3] ethdev: extend RSS offload types
> > 
> > From: Simei Su <simei.su@intel.com>
> > 
> > Make it easier to represent to define macro values as (1ULL << ###).
> > 
> > This RFC reserves several bits as input set selection from bottom
> > of the 64 bits. The flow type is combined with input set to
> > represent rss types.
> > 
> 
> 
> Why reserve from the bottom? and not from the first available space?

I assume the reason is that maintaining the existing model with
RTE_ETH_FLOW_* sibling macros doesn't make sense for these, so this approach
doesn't impact future ETH_RSS_* definitions...

> > for example:
> >     ETH_RSS_IPV4 | ETH_RSS_INSET_L3_SRC: hash on src ip address only
> >     ETH_RSS_IPV4_UDP | ETH_RSS_INSET_L4_DST: hash on src/dst IP and
> > 				            dst UDP port
> >     ETH_RSS_L2_PAYLOAD | ETH_RSS_INSET_L2_DST: hash on dst mac address
> > 
> 
> What happens when the user set ETH_RSS_IPV4? From what I understand from your RFC this will do nothing
> since no bits where enabled, am I correct? 
> If I'm correct this may break applications.

Also my thought, again I assume that ETH_RSS_INSET_* flags only act as
modifiers to ETH_RSS_IPV4 and friends, if none are provided, then both
source and destination are taken into account. If that's the design, it must
be properly documented still.

Looks like it's time to end the relationship between RTE_ETH_FLOW_* and
ETH_RSS_* seeing both serve different purposes, and these new macros only
make sense for RSS.

I suggest a prior patch that converts all those definitions:

 #define ETH_RSS_IPV4               (1ULL << RTE_ETH_FLOW_IPV4)
 [...]

To their numerical counterparts directly, in which case we have two options:

Without breaking ABI, e.g.:

 #define ETH_RSS_IPV4               (1ULL << 2)
 [...]

Or going further if we're ready to break ABI a tiny little bit, starting
over from zero and use unique flags for IPv4, IPv6, TCP and UDP without
distinguishing between NONFRAG, FRAG and IPV6_EX, which never made sense for
RSS, and separating L4 from L3 to save even more, that is:
 
 #define ETH_RSS_ETH                (1ULL << 0)
 #define ETH_RSS_IPV4               (1ULL << 1)
 #define ETH_RSS_IPV6               (1ULL << 2)
 #define ETH_RSS_UDP                (1ULL << 3)
 #define ETH_RSS_TCP                (1ULL << 4)
 #define ETH_RSS_SCTP               (1ULL << 5)
 [...]

Then the flags you would like to add would have to be more explicit. I think
Qi's original suggestion with "ONLY" was better in this regard than "INSET":

 #define ETH_RSS_L2_SRC_ONLY        (1ULL << 6)
 #define ETH_RSS_L2_DST_ONLY        (1ULL << 7)
 [...]

Otherwise there's still the negative approach:

 #define ETH_RSS_L2_NO_SRC          (1ULL << 6)
 #define ETH_RSS_L2_NO_DST          (1ULL << 7)
 [...]

Not sure which is better. Thoughts?

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [RFC] kni: support allmulticast mode set
  2019-07-29 13:38  4% ` Ferruh Yigit
@ 2019-07-29 15:25  3%   ` Ye Xiaolong
  0 siblings, 0 replies; 200+ results
From: Ye Xiaolong @ 2019-07-29 15:25 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: John McNamara, Marko Kovacevic, dev

Hi, Ferruh

On 07/29, Ferruh Yigit wrote:
>On 7/24/2019 4:35 PM, Xiaolong Ye wrote:
>> This patch adds support to allow users enable/disable allmulticast mode for
>> kni interface.
>> 
>> This requirement comes from bugzilla 312, more details can refer to:
>> https://bugs.dpdk.org/show_bug.cgi?id=312
>> 
>> Bugzilla ID: 312
>> 
>> Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
>
>Hi Xiaolong,
>
>Patch lgtm, I think it is too later for this release but I suggest sending v1
>for next release.

Got it, this patch is not that urgent, we can wait for next release.

>
>If there is an ABI breakage, to not block the patch for next release, a
>deprecation notice needs to be sent in this release.
>Although the patch updates header file, as far as I can see it doesn't break the
>ABI, since added fields either last element of the struct or the part of the
>union. But to be sure, can you please double check if I am missing something?

I don't think there is an ABI break either, I'll double check it anyway.

Thanks,
Xiaolong

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] ethdev: extend flow metadata
  2019-07-14 11:46  0%           ` Andrew Rybchenko
@ 2019-07-29 15:06  0%             ` Adrien Mazarguil
  0 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2019-07-29 15:06 UTC (permalink / raw)
  To: Andrew Rybchenko
  Cc: Yongseok Koh, Thomas Monjalon, Olivier Matz, Bruce Richardson,
	Shahaf Shuler, Ferruh Yigit, dev, Slava Ovsiienko

On Sun, Jul 14, 2019 at 02:46:58PM +0300, Andrew Rybchenko wrote:
> On 11.07.2019 10:44, Adrien Mazarguil wrote:
> > On Wed, Jul 10, 2019 at 04:37:46PM +0000, Yongseok Koh wrote:
> > > > On Jul 10, 2019, at 5:26 AM, Thomas Monjalon <thomas@monjalon.net> wrote:
> > > > 
> > > > 10/07/2019 14:01, Bruce Richardson:
> > > > > On Wed, Jul 10, 2019 at 12:07:43PM +0200, Olivier Matz wrote:
> > > > > > On Wed, Jul 10, 2019 at 10:55:34AM +0100, Bruce Richardson wrote:
> > > > > > > On Wed, Jul 10, 2019 at 11:31:56AM +0200, Olivier Matz wrote:
> > > > > > > > On Thu, Jul 04, 2019 at 04:21:22PM -0700, Yongseok Koh wrote:
> > > > > > > > > Currently, metadata can be set on egress path via mbuf tx_meatadata field
> > > > > > > > > with PKT_TX_METADATA flag and RTE_FLOW_ITEM_TYPE_RX_META matches metadata.
> > > > > > > > > 
> > > > > > > > > This patch extends the usability.
> > > > > > > > > 
> > > > > > > > > 1) RTE_FLOW_ACTION_TYPE_SET_META
> > > > > > > > > 
> > > > > > > > > When supporting multiple tables, Tx metadata can also be set by a rule and
> > > > > > > > > matched by another rule. This new action allows metadata to be set as a
> > > > > > > > > result of flow match.
> > > > > > > > > 
> > > > > > > > > 2) Metadata on ingress
> > > > > > > > > 
> > > > > > > > > There's also need to support metadata on packet Rx. Metadata can be set by
> > > > > > > > > SET_META action and matched by META item like Tx. The final value set by
> > > > > > > > > the action will be delivered to application via mbuf metadata field with
> > > > > > > > > PKT_RX_METADATA ol_flag.
> > > > > > > > > 
> > > > > > > > > For this purpose, mbuf->tx_metadata is moved as a separate new field and
> > > > > > > > > renamed to 'metadata' to support both Rx and Tx metadata.
> > > > > > > > > 
> > > > > > > > > For loopback/hairpin packet, metadata set on Rx/Tx may or may not be
> > > > > > > > > propagated to the other path depending on HW capability.
> > > > > > > > > 
> > > > > > > > > Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
> > > > > > > > > --- a/lib/librte_mbuf/rte_mbuf.h
> > > > > > > > > +++ b/lib/librte_mbuf/rte_mbuf.h
> > > > > > > > > @@ -648,17 +653,6 @@ struct rte_mbuf {
> > > > > > > > > 			/**< User defined tags. See rte_distributor_process() */
> > > > > > > > > 			uint32_t usr;
> > > > > > > > > 		} hash;                   /**< hash information */
> > > > > > > > > -		struct {
> > > > > > > > > -			/**
> > > > > > > > > -			 * Application specific metadata value
> > > > > > > > > -			 * for egress flow rule match.
> > > > > > > > > -			 * Valid if PKT_TX_METADATA is set.
> > > > > > > > > -			 * Located here to allow conjunct use
> > > > > > > > > -			 * with hash.sched.hi.
> > > > > > > > > -			 */
> > > > > > > > > -			uint32_t tx_metadata;
> > > > > > > > > -			uint32_t reserved;
> > > > > > > > > -		};
> > > > > > > > > 	};
> > > > > > > > > 
> > > > > > > > > 	/** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ is set. */
> > > > > > > > > @@ -727,6 +721,11 @@ struct rte_mbuf {
> > > > > > > > > 	 */
> > > > > > > > > 	struct rte_mbuf_ext_shared_info *shinfo;
> > > > > > > > > 
> > > > > > > > > +	/** Application specific metadata value for flow rule match.
> > > > > > > > > +	 * Valid if PKT_RX_METADATA or PKT_TX_METADATA is set.
> > > > > > > > > +	 */
> > > > > > > > > +	uint32_t metadata;
> > > > > > > > > +
> > > > > > > > > } __rte_cache_aligned;
> > > > > > > > This will break the ABI, so we cannot put it in 19.08, and we need a
> > > > > > > > deprecation notice.
> > > > > > > > 
> > > > > > > Does it actually break the ABI? Adding a new field to the mbuf should only
> > > > > > > break the ABI if it either causes new fields to move or changes the
> > > > > > > structure size. Since this is at the end, it's not going to move any older
> > > > > > > fields, and since everything is cache-aligned I don't think the structure
> > > > > > > size changes either.
> > > > > > I think it does break the ABI: in previous version, when the PKT_TX_METADATA
> > > > > > flag is set, the associated value is put in m->tx_metadata (offset 44 on
> > > > > > x86-64), and in the next version, it will be in m->metadata (offset 112). So,
> > > > > > these 2 versions are not binary compatible.
> > > > > > 
> > > > > > Anyway, at least it breaks the API.
> > > > > Ok, I misunderstood. I thought it was the structure change itself you were
> > > > > saying broke the ABI. Yes, putting the data in a different place is indeed
> > > > > an ABI break.
> > > > We could add the new field and keep the old one unused,
> > > > so it does not break the ABI.
> > > Still breaks ABI if PKT_TX_METADATA is set. :-) In order not to break it, I can
> > > keep the current union'd field (tx_metadata) as is with PKT_TX_METADATA, add
> > > the new one at the end and make it used with the new PKT_RX_METADATA.
> > > 
> > > > However I suppose everybody will prefer a version using dynamic fields.
> > > > Is someone against using dynamic field for such usage?
> > > However, given that the amazing dynamic fields is coming soon (thanks for your
> > > effort, Olivier and Thomas!), I'd be honored to be the first user of it.
> > > 
> > > Olivier, I'll take a look at your RFC.
> > Just got a crazy idea while reading this thread... How about repurposing
> > that "reserved" field as "rx_metadata" in the meantime?
> 
> It overlaps with hash.fdir.hi which has RSS hash.

While it does overlap with hash.fdir.hi, isn't the RSS hash stored in the
"rss" field overlapping with hash.fdir.lo? (see struct rte_flow_action_rss)

hash.fdir.hi was originally used by FDIR and later repurposed by rte_flow
for its MARK action, which neatly qualifies as Rx metadata so renaming
"reserved" as "rx_metadata" could already make sense.

That is, assuming users do not need two different kinds of Rx metadata
returned simultaneously with their packets. I think it's safe.

> > I know reserved fields are cursed and no one's ever supposed to touch them
> > but this risk is mitigated by having the end user explicitly request its
> > use, so the patch author (and his relatives) should be safe from the
> > resulting bad juju.
> > 
> > Joke aside, while I like the idea of Tx/Rx META, I think the similarities
> > with MARK (and TAG eventually) is a problem. I wasn't available and couldn't
> > comment when META was originally added to the Tx path, but there's a lot of
> > overlap between these items/actions, without anything explaining to the end
> > user how and why they should pick one over the other, if they can be
> > combined at all and what happens in that case.
> > 
> > All this must be documented, then we should think about unifying their
> > respective features and deprecate the less capable items/actions. In my
> > opinion, users need exactly one method to mark/match some mark while
> > processing Rx/Tx traffic and *optionally* have that mark read from/written
> > to the mbuf, which may or may not be possible depending on HW features.

Thoughts regarding this suggestion? From a user perspective I think all
these actions should be unified but maybe there are good reasons to keep
them separate?

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] kni: support allmulticast mode set
  @ 2019-07-29 13:38  4% ` Ferruh Yigit
  2019-07-29 15:25  3%   ` Ye Xiaolong
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-07-29 13:38 UTC (permalink / raw)
  To: Xiaolong Ye, John McNamara, Marko Kovacevic; +Cc: dev

On 7/24/2019 4:35 PM, Xiaolong Ye wrote:
> This patch adds support to allow users enable/disable allmulticast mode for
> kni interface.
> 
> This requirement comes from bugzilla 312, more details can refer to:
> https://bugs.dpdk.org/show_bug.cgi?id=312
> 
> Bugzilla ID: 312
> 
> Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>

Hi Xiaolong,

Patch lgtm, I think it is too later for this release but I suggest sending v1
for next release.

If there is an ABI breakage, to not block the patch for next release, a
deprecation notice needs to be sent in this release.
Although the patch updates header file, as far as I can see it doesn't break the
ABI, since added fields either last element of the struct or the part of the
union. But to be sure, can you please double check if I am missing something?

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v9 3/5] kni: add app specific mempool create & free routine
  @ 2019-07-29 12:13  3%     ` vattunuru
  0 siblings, 0 replies; 200+ results
From: vattunuru @ 2019-07-29 12:13 UTC (permalink / raw)
  To: dev
  Cc: thomas, jerinj, olivier.matz, ferruh.yigit, anatoly.burakov,
	arybchenko, kirankumark, Vamsi Attunuru

From: Vamsi Attunuru <vattunuru@marvell.com>

When KNI operates in IOVA = VA mode, it requires mbuf memory
to be physically contiguous to ensure KNI kernel module could
translate IOVA addresses properly. Patch adds a KNI specific
mempool create routine to populate the KNI packet mbuf pool
with memory objects that are being on a page.

KNI applications need to use this mempool create & free routines
so that mbuf related requirements in IOVA = VA mode are handled
inside those routines based on the enabled mode.

Updated the release notes with these new routine details.

Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
 doc/guides/rel_notes/release_19_08.rst |  6 ++++
 examples/kni/main.c                    |  5 ++-
 lib/librte_kni/Makefile                |  1 +
 lib/librte_kni/meson.build             |  1 +
 lib/librte_kni/rte_kni.c               | 60 ++++++++++++++++++++++++++++++++++
 lib/librte_kni/rte_kni.h               | 48 +++++++++++++++++++++++++++
 lib/librte_kni/rte_kni_version.map     |  2 ++
 7 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index c9bd3ce..b200aae 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -301,6 +301,12 @@ API Changes
   best-effort tc, and qsize field of struct ``rte_sched_port_params`` is
   changed to allow different size of the each queue.
 
+* kni: ``rte_kni_pktmbuf_pool_create`` ``rte_kni_pktmbuf_pool_free`` functions
+  were introduced for KNI applications for creating & freeing packet pool.
+  Since IOVA=VA mode was added in KNI, packet pool's mbuf memory should be
+  physically contiguous for the KNI kernel module to work in IOVA=VA mode,
+  this requirement was taken care in the kni packet pool creation fucntions.
+
 
 ABI Changes
 -----------
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 4710d71..fdfeed2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -975,7 +975,7 @@ main(int argc, char** argv)
 		rte_exit(EXIT_FAILURE, "Could not parse input parameters\n");
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+	pktmbuf_pool = rte_kni_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
 		MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool\n");
@@ -1043,6 +1043,9 @@ main(int argc, char** argv)
 			continue;
 		kni_free_kni(port);
 	}
+
+	rte_kni_pktmbuf_pool_free(pktmbuf_pool);
+
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
 		if (kni_port_params_array[i]) {
 			rte_free(kni_port_params_array[i]);
diff --git a/lib/librte_kni/Makefile b/lib/librte_kni/Makefile
index ab15d10..5e3dd01 100644
--- a/lib/librte_kni/Makefile
+++ b/lib/librte_kni/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 # library name
 LIB = librte_kni.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing
 CFLAGS += -I$(RTE_SDK)/drivers/bus/pci
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev
diff --git a/lib/librte_kni/meson.build b/lib/librte_kni/meson.build
index fd46f87..e357445 100644
--- a/lib/librte_kni/meson.build
+++ b/lib/librte_kni/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 if not is_linux or not dpdk_conf.get('RTE_ARCH_64')
 	build = false
 	reason = 'only supported on 64-bit linux'
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 2aaaeaa..15dda45 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -22,6 +22,7 @@
 #include <rte_tailq.h>
 #include <rte_rwlock.h>
 #include <rte_eal_memconfig.h>
+#include <rte_mbuf_pool_ops.h>
 #include <rte_kni_common.h>
 #include "rte_kni_fifo.h"
 
@@ -681,6 +682,65 @@ kni_allocate_mbufs(struct rte_kni *kni)
 	}
 }
 
+struct rte_mempool *
+rte_kni_pktmbuf_pool_create(const char *name, unsigned int n,
+	unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id)
+{
+	struct rte_pktmbuf_pool_private mbp_priv;
+	const char *mp_ops_name;
+	struct rte_mempool *mp;
+	unsigned int elt_size;
+	int ret;
+
+	if (RTE_ALIGN(priv_size, RTE_MBUF_PRIV_ALIGN) != priv_size) {
+		RTE_LOG(ERR, MBUF, "mbuf priv_size=%u is not aligned\n",
+			priv_size);
+		rte_errno = EINVAL;
+		return NULL;
+	}
+	elt_size = sizeof(struct rte_mbuf) + (unsigned int)priv_size +
+		(unsigned int)data_room_size;
+	mbp_priv.mbuf_data_room_size = data_room_size;
+	mbp_priv.mbuf_priv_size = priv_size;
+
+	mp = rte_mempool_create_empty(name, n, elt_size, cache_size,
+		 sizeof(struct rte_pktmbuf_pool_private), socket_id, 0);
+	if (mp == NULL)
+		return NULL;
+
+	mp_ops_name = rte_mbuf_best_mempool_ops();
+	ret = rte_mempool_set_ops_byname(mp, mp_ops_name, NULL);
+	if (ret != 0) {
+		RTE_LOG(ERR, MBUF, "error setting mempool handler\n");
+		rte_mempool_free(mp);
+		rte_errno = -ret;
+		return NULL;
+	}
+	rte_pktmbuf_pool_init(mp, &mbp_priv);
+
+	if (rte_eal_iova_mode() == RTE_IOVA_VA)
+		ret = rte_mempool_populate_from_pg_sz_chunks(mp);
+	else
+		ret = rte_mempool_populate_default(mp);
+
+	if (ret < 0) {
+		rte_mempool_free(mp);
+		rte_errno = -ret;
+		return NULL;
+	}
+
+	rte_mempool_obj_iter(mp, rte_pktmbuf_init, NULL);
+
+	return mp;
+}
+
+void
+rte_kni_pktmbuf_pool_free(struct rte_mempool *mp)
+{
+	rte_mempool_free(mp);
+}
+
 struct rte_kni *
 rte_kni_get(const char *name)
 {
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 5699a64..99d263d 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -184,6 +184,54 @@ unsigned rte_kni_tx_burst(struct rte_kni *kni, struct rte_mbuf **mbufs,
 		unsigned num);
 
 /**
+ * Create a kni packet mbuf pool.
+ *
+ * This function creates and initializes a packet mbuf pool for KNI applications
+ * It calls the required mempool populate routine based on the IOVA mode.
+ *
+ * @param name
+ *   The name of the mbuf pool.
+ * @param n
+ *   The number of elements in the mbuf pool. The optimum size (in terms
+ *   of memory usage) for a mempool is when n is a power of two minus one:
+ *   n = (2^q - 1).
+ * @param cache_size
+ *   Size of the per-core object cache. See rte_mempool_create() for
+ *   details.
+ * @param priv_size
+ *   Size of application private are between the rte_mbuf structure
+ *   and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
+ * @param data_room_size
+ *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
+ * @param socket_id
+ *   The socket identifier where the memory should be allocated. The
+ *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
+ *   reserved zone.
+ * @return
+ *   The pointer to the new allocated mempool, on success. NULL on error
+ *   with rte_errno set appropriately. Possible rte_errno values include:
+ *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ *    - E_RTE_SECONDARY - function was called from a secondary process instance
+ *    - EINVAL - cache size provided is too large, or priv_size is not aligned.
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a memzone with the same name already exists
+ *    - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+__rte_experimental
+struct rte_mempool *rte_kni_pktmbuf_pool_create(const char *name,
+		unsigned int n, unsigned int cache_size, uint16_t priv_size,
+		uint16_t data_room_size, int socket_id);
+
+/**
+ * Free the given packet mempool.
+ *
+ * @param mp
+ *  The mempool pointer.
+ */
+__rte_experimental
+void rte_kni_pktmbuf_pool_free(struct rte_mempool *mp);
+
+/**
  * Get the KNI context of its name.
  *
  * @param name
diff --git a/lib/librte_kni/rte_kni_version.map b/lib/librte_kni/rte_kni_version.map
index c877dc6..aba9728 100644
--- a/lib/librte_kni/rte_kni_version.map
+++ b/lib/librte_kni/rte_kni_version.map
@@ -20,4 +20,6 @@ EXPERIMENTAL {
 	global:
 
 	rte_kni_update_link;
+	rte_kni_pktmbuf_pool_create;
+	rte_kni_pktmbuf_pool_free;
 };
-- 
2.8.4


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v3] devtools: better freebsd support
  2019-07-29  8:31  0%   ` David Marchand
@ 2019-07-29  8:36  0%     ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-07-29  8:36 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev, Thomas Monjalon, Bruce Richardson, Flavia

On Mon, Jul 29, 2019 at 10:31 AM David Marchand
<david.marchand@redhat.com> wrote:
>
> On Thu, Jul 11, 2019 at 4:25 PM Olivier Matz <olivier.matz@6wind.com> wrote:
> >
> > - As "readlink -e" and "readlink -m" do not exist on freebsd,
> >   use "readlink -f", it should not have any impact in these cases.
> > - "sed -ri" is invalid on freebsd and should be replaced by
> >   "sed -ri=''"
> > - Use gmake instead of make.
> >
> > This fixes the following command:
> >   SYSDIR=/usr/src/sys ./devtools/test-build.sh \
> >     -j4 x86_64-native-freebsd-gcc
> >
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > ---
> >
> > v3:
> > - fix examples installation path, pointed-out by Flavia
> >
> > v2:
> > - remove sed_ri() function and use 'sed -ri=""' as suggested by Bruce
> >
> >  devtools/check-dup-includes.sh |  2 +-
> >  devtools/checkpatches.sh       |  8 ++--
> >  devtools/get-maintainer.sh     |  2 +-
> >  devtools/load-devel-config     |  4 +-
> >  devtools/test-build.sh         | 94 ++++++++++++++++++++++--------------------
> >  devtools/validate-abi.sh       |  2 +-
> >  6 files changed, 58 insertions(+), 54 deletions(-)
> >
> > diff --git a/devtools/check-dup-includes.sh b/devtools/check-dup-includes.sh
> > index e4c2748c6..591599949 100755
> > --- a/devtools/check-dup-includes.sh
> > +++ b/devtools/check-dup-includes.sh
> > @@ -5,7 +5,7 @@
> >  # Check C files in git repository for duplicated includes.
> >  # Usage: devtools/check-dup-includes.sh [directory]
> >
> > -dir=${1:-$(dirname $(readlink -m $0))/..}
> > +dir=${1:-$(dirname $(readlink -f $0))/..}
> >  cd $dir
> >
> >  # speed up by ignoring Unicode details
> > diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
> > index 560e6ce93..8e2beee16 100755
> > --- a/devtools/checkpatches.sh
> > +++ b/devtools/checkpatches.sh
> > @@ -7,9 +7,9 @@
> >  # - DPDK_CHECKPATCH_CODESPELL
> >  # - DPDK_CHECKPATCH_LINE_LENGTH
> >  # - DPDK_CHECKPATCH_OPTIONS
> > -. $(dirname $(readlink -e $0))/load-devel-config
> > +. $(dirname $(readlink -f $0))/load-devel-config
> >
> > -VALIDATE_NEW_API=$(dirname $(readlink -e $0))/check-symbol-change.sh
> > +VALIDATE_NEW_API=$(dirname $(readlink -f $0))/check-symbol-change.sh
> >
> >  # Enable codespell by default. This can be overwritten from a config file.
> >  # Codespell can also be enabled by setting DPDK_CHECKPATCH_CODESPELL to a valid path
> > @@ -66,7 +66,7 @@ check_forbidden_additions() { # <patch>
> >                 -v EXPRESSIONS="rte_panic\\\( rte_exit\\\(" \
> >                 -v RET_ON_FAIL=1 \
> >                 -v MESSAGE='Using rte_panic/rte_exit' \
> > -               -f $(dirname $(readlink -e $0))/check-forbidden-tokens.awk \
> > +               -f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
> >                 "$1" || res=1
> >
> >         # svg figures must be included with wildcard extension
> > @@ -75,7 +75,7 @@ check_forbidden_additions() { # <patch>
> >                 -v EXPRESSIONS='::[[:space:]]*[^[:space:]]*\\.svg' \
> >                 -v RET_ON_FAIL=1 \
> >                 -v MESSAGE='Using explicit .svg extension instead of .*' \
> > -               -f $(dirname $(readlink -e $0))/check-forbidden-tokens.awk \
> > +               -f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
> >                 "$1" || res=1
> >
> >         return $res
> > diff --git a/devtools/get-maintainer.sh b/devtools/get-maintainer.sh
> > index b9160486a..85740f5af 100755
> > --- a/devtools/get-maintainer.sh
> > +++ b/devtools/get-maintainer.sh
> > @@ -5,7 +5,7 @@
> >
> >  # Load config options:
> >  # - DPDK_GETMAINTAINER_PATH
> > -. $(dirname $(readlink -e $0))/load-devel-config
> > +. $(dirname $(readlink -f $0))/load-devel-config
> >
> >  options="--no-git-fallback"
> >  options="$options --no-rolestats"
> > diff --git a/devtools/load-devel-config b/devtools/load-devel-config
> > index 4f43cb352..380c79db4 100644
> > --- a/devtools/load-devel-config
> > +++ b/devtools/load-devel-config
> > @@ -6,7 +6,7 @@ test ! -r /etc/dpdk/devel.config ||
> >  test ! -r ~/.config/dpdk/devel.config ||
> >          . ~/.config/dpdk/devel.config
> >  # from local file
> > -test ! -r $(dirname $(readlink -m $0))/../.develconfig ||
> > -        . $(dirname $(readlink -m $0))/../.develconfig
> > +test ! -r $(dirname $(readlink -f $0))/../.develconfig ||
> > +        . $(dirname $(readlink -f $0))/../.develconfig
> >
> >  # The config files must export variables in the shell style
> > diff --git a/devtools/test-build.sh b/devtools/test-build.sh
> > index 9b50bf73d..3c029ce31 100755
> > --- a/devtools/test-build.sh
> > +++ b/devtools/test-build.sh
> > @@ -28,7 +28,7 @@ default_path=$PATH
> >  # - LIBSSO_SNOW3G_PATH
> >  # - LIBSSO_KASUMI_PATH
> >  # - LIBSSO_ZUC_PATH
> > -. $(dirname $(readlink -e $0))/load-devel-config
> > +. $(dirname $(readlink -f $0))/load-devel-config
> >
> >  print_usage () {
> >         echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] ...]]"
> > @@ -57,6 +57,10 @@ print_help () {
> >         END_OF_HELP
> >  }
> >
> > +[ -z $MAKE ] && command -v gmake > /dev/null && MAKE=gmake
> > +[ -z $MAKE ] && command -v make > /dev/null && MAKE=make
> > +[ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1
> > +
> >  J=$DPDK_MAKE_JOBS
> >  short=false
> >  unset verbose
> > @@ -90,7 +94,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT
> >  # notify result on exit
> >  trap on_exit EXIT
> >
> > -cd $(dirname $(readlink -m $0))/..
> > +cd $(dirname $(readlink -f $0))/..
> >
> >  reset_env ()
> >  {
> > @@ -127,83 +131,83 @@ config () # <directory> <target> <options>
> >         fi
> >         if [ ! -e $1/.config ] || $reconfig ; then
> >                 echo "================== Configure $1"
> > -               make T=$2 O=$1 config
> > +               ${MAKE} T=$2 O=$1 config
> >
> >                 echo 'Customize configuration'
> >                 # Built-in options (lowercase)
> >                 ! echo $3 | grep -q '+default' || \
> > -               sed -ri 's,(RTE_MACHINE=")native,\1default,' $1/.config
> > +               sed -ri="" 's,(RTE_MACHINE=")native,\1default,' $1/.config
> >                 echo $3 | grep -q '+next' || \
> > -               sed -ri           's,(NEXT_ABI=)y,\1n,' $1/.config
> > +               sed -ri=""           's,(NEXT_ABI=)y,\1n,' $1/.config
> >                 ! echo $3 | grep -q '+shared' || \
> > -               sed -ri         's,(SHARED_LIB=)n,\1y,' $1/.config
> > +               sed -ri=""         's,(SHARED_LIB=)n,\1y,' $1/.config
> >                 ! echo $3 | grep -q '+debug' || ( \
> > -               sed -ri  's,(RTE_LOG_DP_LEVEL=).*,\1RTE_LOG_DEBUG,' $1/.config
> > -               sed -ri           's,(_DEBUG.*=)n,\1y,' $1/.config
> > -               sed -ri            's,(_STAT.*=)n,\1y,' $1/.config
> > -               sed -ri 's,(TEST_PMD_RECORD_.*=)n,\1y,' $1/.config )
> > +               sed -ri=""  's,(RTE_LOG_DP_LEVEL=).*,\1RTE_LOG_DEBUG,' $1/.config
> > +               sed -ri=""           's,(_DEBUG.*=)n,\1y,' $1/.config
> > +               sed -ri=""            's,(_STAT.*=)n,\1y,' $1/.config
> > +               sed -ri="" 's,(TEST_PMD_RECORD_.*=)n,\1y,' $1/.config )
> >
> >                 # Automatic configuration
> >                 test "$DPDK_DEP_NUMA" != n || \
> > -               sed -ri             's,(NUMA.*=)y,\1n,' $1/.config
> > -               sed -ri    's,(LIBRTE_IEEE1588=)n,\1y,' $1/.config
> > -               sed -ri             's,(BYPASS=)n,\1y,' $1/.config
> > +               sed -ri=""             's,(NUMA.*=)y,\1n,' $1/.config
> > +               sed -ri=""    's,(LIBRTE_IEEE1588=)n,\1y,' $1/.config
> > +               sed -ri=""             's,(BYPASS=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_ARCHIVE" != y || \
> > -               sed -ri       's,(RESOURCE_TAR=)n,\1y,' $1/.config
> > +               sed -ri=""       's,(RESOURCE_TAR=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_ISAL" != y || \
> > -               sed -ri           's,(PMD_ISAL=)n,\1y,' $1/.config
> > +               sed -ri=""           's,(PMD_ISAL=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_MLX" != y || \
> > -               sed -ri           's,(MLX._PMD=)n,\1y,' $1/.config
> > +               sed -ri=""           's,(MLX._PMD=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_SZE" != y || \
> > -               sed -ri       's,(PMD_SZEDATA2=)n,\1y,' $1/.config
> > +               sed -ri=""       's,(PMD_SZEDATA2=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_ZLIB" != y || \
> > -               sed -ri          's,(BNX2X_PMD=)n,\1y,' $1/.config
> > +               sed -ri=""          's,(BNX2X_PMD=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_ZLIB" != y || \
> > -               sed -ri           's,(PMD_ZLIB=)n,\1y,' $1/.config
> > +               sed -ri=""           's,(PMD_ZLIB=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_ZLIB" != y || \
> > -               sed -ri   's,(COMPRESSDEV_TEST=)n,\1y,' $1/.config
> > +               sed -ri=""   's,(COMPRESSDEV_TEST=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_PCAP" != y || \
> > -               sed -ri               's,(PCAP=)n,\1y,' $1/.config
> > +               sed -ri=""               's,(PCAP=)n,\1y,' $1/.config
> >                 test -z "$ARMV8_CRYPTO_LIB_PATH" || \
> > -               sed -ri   's,(PMD_ARMV8_CRYPTO=)n,\1y,' $1/.config
> > +               sed -ri=""   's,(PMD_ARMV8_CRYPTO=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_IPSEC_MB" != y || \
> > -               sed -ri       's,(PMD_AESNI_MB=)n,\1y,' $1/.config
> > +               sed -ri=""       's,(PMD_AESNI_MB=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_IPSEC_MB" != y || \
> > -               sed -ri      's,(PMD_AESNI_GCM=)n,\1y,' $1/.config
> > +               sed -ri=""      's,(PMD_AESNI_GCM=)n,\1y,' $1/.config
> >                 test -z "$LIBSSO_SNOW3G_PATH" || \
> > -               sed -ri         's,(PMD_SNOW3G=)n,\1y,' $1/.config
> > +               sed -ri=""         's,(PMD_SNOW3G=)n,\1y,' $1/.config
> >                 test -z "$LIBSSO_KASUMI_PATH" || \
> > -               sed -ri         's,(PMD_KASUMI=)n,\1y,' $1/.config
> > +               sed -ri=""         's,(PMD_KASUMI=)n,\1y,' $1/.config
> >                 test -z "$LIBSSO_ZUC_PATH" || \
> > -               sed -ri            's,(PMD_ZUC=)n,\1y,' $1/.config
> > +               sed -ri=""            's,(PMD_ZUC=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_SSL" != y || \
> > -               sed -ri            's,(PMD_CCP=)n,\1y,' $1/.config
> > +               sed -ri=""            's,(PMD_CCP=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_SSL" != y || \
> > -               sed -ri        's,(PMD_OPENSSL=)n,\1y,' $1/.config
> > +               sed -ri=""        's,(PMD_OPENSSL=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_SSL" != y || \
> > -               sed -ri            's,(QAT_SYM=)n,\1y,' $1/.config
> > +               sed -ri=""            's,(QAT_SYM=)n,\1y,' $1/.config
> >                 test -z "$FLEXRAN_SDK" || \
> > -               sed -ri     's,(BBDEV_TURBO_SW=)n,\1y,' $1/.config
> > -               sed -ri           's,(SCHED_.*=)n,\1y,' $1/.config
> > +               sed -ri=""     's,(BBDEV_TURBO_SW=)n,\1y,' $1/.config
> > +               sed -ri=""           's,(SCHED_.*=)n,\1y,' $1/.config
> >                 test -z "$LIBMUSDK_PATH" || \
> > -               sed -ri   's,(PMD_MVSAM_CRYPTO=)n,\1y,' $1/.config
> > +               sed -ri=""   's,(PMD_MVSAM_CRYPTO=)n,\1y,' $1/.config
> >                 test -z "$LIBMUSDK_PATH" || \
> > -               sed -ri          's,(MVPP2_PMD=)n,\1y,' $1/.config
> > +               sed -ri=""          's,(MVPP2_PMD=)n,\1y,' $1/.config
> >                 test -z "$LIBMUSDK_PATH" || \
> > -               sed -ri         's,(MVNETA_PMD=)n,\1y,' $1/.config
> > +               sed -ri=""         's,(MVNETA_PMD=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_ELF" != y || \
> > -               sed -ri            's,(BPF_ELF=)n,\1y,' $1/.config
> > +               sed -ri=""            's,(BPF_ELF=)n,\1y,' $1/.config
> >                 test "$DPDK_DEP_JSON" != y || \
> > -               sed -ri          's,(TELEMETRY=)n,\1y,' $1/.config
> > +               sed -ri=""          's,(TELEMETRY=)n,\1y,' $1/.config
> >                 build_config_hook $1 $2 $3
> >
> >                 # Explicit enabler/disabler (uppercase)
> >                 for option in $(echo $3 | sed 's,[~+], &,g') ; do
> >                         pattern=$(echo $option | cut -c2-)
> >                         if echo $option | grep -q '^~' ; then
> > -                               sed -ri "s,($pattern=)y,\1n," $1/.config
> > +                               sed -ri="" "s,($pattern=)y,\1n," $1/.config
> >                         elif echo $option | grep -q '^+' ; then
> > -                               sed -ri "s,($pattern=)n,\1y," $1/.config
> > +                               sed -ri="" "s,($pattern=)n,\1y," $1/.config
> >                         fi
> >                 done
> >         fi
> > @@ -220,22 +224,22 @@ for conf in $configs ; do
> >         # reload config with DPDK_TARGET set
> >         DPDK_TARGET=$target
> >         reset_env
> > -       . $(dirname $(readlink -e $0))/load-devel-config
> > +       . $(dirname $(readlink -f $0))/load-devel-config
> >
> >         options=$(echo $conf | sed 's,[^~+]*,,')
> >         dir=$conf
> >         config $dir $target $options
> >
> >         echo "================== Build $dir"
> > -       make -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \
> > +       ${MAKE} -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \
> >                 EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose O=$dir
> >         ! $short || break
> >         echo "================== Build examples for $dir"
> >         export RTE_SDK=$(pwd)
> >         export RTE_TARGET=$dir
> > -       make -j$J -sC examples \
> > +       ${MAKE} -j$J -sC examples \
> >                 EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \
> > -               O=$(readlink -m $dir/examples)
> > +               O=$(readlink -f $dir)/examples
> >         unset RTE_TARGET
> >         echo "################## $dir done."
> >         unset dir
> > @@ -244,9 +248,9 @@ done
> >  if ! $short ; then
> >         mkdir -p .check
> >         echo "================== Build doxygen HTML API"
> > -       make doc-api-html >/dev/null 2>.check/doc.txt
> > +       ${MAKE} doc-api-html >/dev/null 2>.check/doc.txt
> >         echo "================== Build sphinx HTML guides"
> > -       make doc-guides-html >/dev/null 2>>.check/doc.txt
> > +       ${MAKE} doc-guides-html >/dev/null 2>>.check/doc.txt
> >         echo "================== Check docs"
> >         diff -u /dev/null .check/doc.txt
> >  fi
> > diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
> > index 138436d93..f64e19d38 100755
> > --- a/devtools/validate-abi.sh
> > +++ b/devtools/validate-abi.sh
> > @@ -181,7 +181,7 @@ case "${dst}" in
> >         /*) ;;
> >         *) dst=${PWD}/${dst} ;;
> >  esac
> > -dpdkroot=$(readlink -e $(dirname $0)/..)
> > +dpdkroot=$(readlink -f $(dirname $0)/..)
> >
> >  if [ -e "${dst}" -a "$force" = 0 ]; then
> >         echo "The ${dst} directory is not empty. Remove it, use another"
> > --
> > 2.11.0
> >
>
> Reviewed-by: David Marchand <david.marchand@redhat.com>

Small nit on the title, it should be FreeBSD.

-- 
David Marchand

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v3] devtools: better freebsd support
  2019-07-11 14:25  6% ` [dpdk-dev] [PATCH v3] " Olivier Matz
@ 2019-07-29  8:31  0%   ` David Marchand
  2019-07-29  8:36  0%     ` David Marchand
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2019-07-29  8:31 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev, Thomas Monjalon, Bruce Richardson, Flavia

On Thu, Jul 11, 2019 at 4:25 PM Olivier Matz <olivier.matz@6wind.com> wrote:
>
> - As "readlink -e" and "readlink -m" do not exist on freebsd,
>   use "readlink -f", it should not have any impact in these cases.
> - "sed -ri" is invalid on freebsd and should be replaced by
>   "sed -ri=''"
> - Use gmake instead of make.
>
> This fixes the following command:
>   SYSDIR=/usr/src/sys ./devtools/test-build.sh \
>     -j4 x86_64-native-freebsd-gcc
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
>
> v3:
> - fix examples installation path, pointed-out by Flavia
>
> v2:
> - remove sed_ri() function and use 'sed -ri=""' as suggested by Bruce
>
>  devtools/check-dup-includes.sh |  2 +-
>  devtools/checkpatches.sh       |  8 ++--
>  devtools/get-maintainer.sh     |  2 +-
>  devtools/load-devel-config     |  4 +-
>  devtools/test-build.sh         | 94 ++++++++++++++++++++++--------------------
>  devtools/validate-abi.sh       |  2 +-
>  6 files changed, 58 insertions(+), 54 deletions(-)
>
> diff --git a/devtools/check-dup-includes.sh b/devtools/check-dup-includes.sh
> index e4c2748c6..591599949 100755
> --- a/devtools/check-dup-includes.sh
> +++ b/devtools/check-dup-includes.sh
> @@ -5,7 +5,7 @@
>  # Check C files in git repository for duplicated includes.
>  # Usage: devtools/check-dup-includes.sh [directory]
>
> -dir=${1:-$(dirname $(readlink -m $0))/..}
> +dir=${1:-$(dirname $(readlink -f $0))/..}
>  cd $dir
>
>  # speed up by ignoring Unicode details
> diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
> index 560e6ce93..8e2beee16 100755
> --- a/devtools/checkpatches.sh
> +++ b/devtools/checkpatches.sh
> @@ -7,9 +7,9 @@
>  # - DPDK_CHECKPATCH_CODESPELL
>  # - DPDK_CHECKPATCH_LINE_LENGTH
>  # - DPDK_CHECKPATCH_OPTIONS
> -. $(dirname $(readlink -e $0))/load-devel-config
> +. $(dirname $(readlink -f $0))/load-devel-config
>
> -VALIDATE_NEW_API=$(dirname $(readlink -e $0))/check-symbol-change.sh
> +VALIDATE_NEW_API=$(dirname $(readlink -f $0))/check-symbol-change.sh
>
>  # Enable codespell by default. This can be overwritten from a config file.
>  # Codespell can also be enabled by setting DPDK_CHECKPATCH_CODESPELL to a valid path
> @@ -66,7 +66,7 @@ check_forbidden_additions() { # <patch>
>                 -v EXPRESSIONS="rte_panic\\\( rte_exit\\\(" \
>                 -v RET_ON_FAIL=1 \
>                 -v MESSAGE='Using rte_panic/rte_exit' \
> -               -f $(dirname $(readlink -e $0))/check-forbidden-tokens.awk \
> +               -f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
>                 "$1" || res=1
>
>         # svg figures must be included with wildcard extension
> @@ -75,7 +75,7 @@ check_forbidden_additions() { # <patch>
>                 -v EXPRESSIONS='::[[:space:]]*[^[:space:]]*\\.svg' \
>                 -v RET_ON_FAIL=1 \
>                 -v MESSAGE='Using explicit .svg extension instead of .*' \
> -               -f $(dirname $(readlink -e $0))/check-forbidden-tokens.awk \
> +               -f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
>                 "$1" || res=1
>
>         return $res
> diff --git a/devtools/get-maintainer.sh b/devtools/get-maintainer.sh
> index b9160486a..85740f5af 100755
> --- a/devtools/get-maintainer.sh
> +++ b/devtools/get-maintainer.sh
> @@ -5,7 +5,7 @@
>
>  # Load config options:
>  # - DPDK_GETMAINTAINER_PATH
> -. $(dirname $(readlink -e $0))/load-devel-config
> +. $(dirname $(readlink -f $0))/load-devel-config
>
>  options="--no-git-fallback"
>  options="$options --no-rolestats"
> diff --git a/devtools/load-devel-config b/devtools/load-devel-config
> index 4f43cb352..380c79db4 100644
> --- a/devtools/load-devel-config
> +++ b/devtools/load-devel-config
> @@ -6,7 +6,7 @@ test ! -r /etc/dpdk/devel.config ||
>  test ! -r ~/.config/dpdk/devel.config ||
>          . ~/.config/dpdk/devel.config
>  # from local file
> -test ! -r $(dirname $(readlink -m $0))/../.develconfig ||
> -        . $(dirname $(readlink -m $0))/../.develconfig
> +test ! -r $(dirname $(readlink -f $0))/../.develconfig ||
> +        . $(dirname $(readlink -f $0))/../.develconfig
>
>  # The config files must export variables in the shell style
> diff --git a/devtools/test-build.sh b/devtools/test-build.sh
> index 9b50bf73d..3c029ce31 100755
> --- a/devtools/test-build.sh
> +++ b/devtools/test-build.sh
> @@ -28,7 +28,7 @@ default_path=$PATH
>  # - LIBSSO_SNOW3G_PATH
>  # - LIBSSO_KASUMI_PATH
>  # - LIBSSO_ZUC_PATH
> -. $(dirname $(readlink -e $0))/load-devel-config
> +. $(dirname $(readlink -f $0))/load-devel-config
>
>  print_usage () {
>         echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] ...]]"
> @@ -57,6 +57,10 @@ print_help () {
>         END_OF_HELP
>  }
>
> +[ -z $MAKE ] && command -v gmake > /dev/null && MAKE=gmake
> +[ -z $MAKE ] && command -v make > /dev/null && MAKE=make
> +[ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1
> +
>  J=$DPDK_MAKE_JOBS
>  short=false
>  unset verbose
> @@ -90,7 +94,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT
>  # notify result on exit
>  trap on_exit EXIT
>
> -cd $(dirname $(readlink -m $0))/..
> +cd $(dirname $(readlink -f $0))/..
>
>  reset_env ()
>  {
> @@ -127,83 +131,83 @@ config () # <directory> <target> <options>
>         fi
>         if [ ! -e $1/.config ] || $reconfig ; then
>                 echo "================== Configure $1"
> -               make T=$2 O=$1 config
> +               ${MAKE} T=$2 O=$1 config
>
>                 echo 'Customize configuration'
>                 # Built-in options (lowercase)
>                 ! echo $3 | grep -q '+default' || \
> -               sed -ri 's,(RTE_MACHINE=")native,\1default,' $1/.config
> +               sed -ri="" 's,(RTE_MACHINE=")native,\1default,' $1/.config
>                 echo $3 | grep -q '+next' || \
> -               sed -ri           's,(NEXT_ABI=)y,\1n,' $1/.config
> +               sed -ri=""           's,(NEXT_ABI=)y,\1n,' $1/.config
>                 ! echo $3 | grep -q '+shared' || \
> -               sed -ri         's,(SHARED_LIB=)n,\1y,' $1/.config
> +               sed -ri=""         's,(SHARED_LIB=)n,\1y,' $1/.config
>                 ! echo $3 | grep -q '+debug' || ( \
> -               sed -ri  's,(RTE_LOG_DP_LEVEL=).*,\1RTE_LOG_DEBUG,' $1/.config
> -               sed -ri           's,(_DEBUG.*=)n,\1y,' $1/.config
> -               sed -ri            's,(_STAT.*=)n,\1y,' $1/.config
> -               sed -ri 's,(TEST_PMD_RECORD_.*=)n,\1y,' $1/.config )
> +               sed -ri=""  's,(RTE_LOG_DP_LEVEL=).*,\1RTE_LOG_DEBUG,' $1/.config
> +               sed -ri=""           's,(_DEBUG.*=)n,\1y,' $1/.config
> +               sed -ri=""            's,(_STAT.*=)n,\1y,' $1/.config
> +               sed -ri="" 's,(TEST_PMD_RECORD_.*=)n,\1y,' $1/.config )
>
>                 # Automatic configuration
>                 test "$DPDK_DEP_NUMA" != n || \
> -               sed -ri             's,(NUMA.*=)y,\1n,' $1/.config
> -               sed -ri    's,(LIBRTE_IEEE1588=)n,\1y,' $1/.config
> -               sed -ri             's,(BYPASS=)n,\1y,' $1/.config
> +               sed -ri=""             's,(NUMA.*=)y,\1n,' $1/.config
> +               sed -ri=""    's,(LIBRTE_IEEE1588=)n,\1y,' $1/.config
> +               sed -ri=""             's,(BYPASS=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_ARCHIVE" != y || \
> -               sed -ri       's,(RESOURCE_TAR=)n,\1y,' $1/.config
> +               sed -ri=""       's,(RESOURCE_TAR=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_ISAL" != y || \
> -               sed -ri           's,(PMD_ISAL=)n,\1y,' $1/.config
> +               sed -ri=""           's,(PMD_ISAL=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_MLX" != y || \
> -               sed -ri           's,(MLX._PMD=)n,\1y,' $1/.config
> +               sed -ri=""           's,(MLX._PMD=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_SZE" != y || \
> -               sed -ri       's,(PMD_SZEDATA2=)n,\1y,' $1/.config
> +               sed -ri=""       's,(PMD_SZEDATA2=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_ZLIB" != y || \
> -               sed -ri          's,(BNX2X_PMD=)n,\1y,' $1/.config
> +               sed -ri=""          's,(BNX2X_PMD=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_ZLIB" != y || \
> -               sed -ri           's,(PMD_ZLIB=)n,\1y,' $1/.config
> +               sed -ri=""           's,(PMD_ZLIB=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_ZLIB" != y || \
> -               sed -ri   's,(COMPRESSDEV_TEST=)n,\1y,' $1/.config
> +               sed -ri=""   's,(COMPRESSDEV_TEST=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_PCAP" != y || \
> -               sed -ri               's,(PCAP=)n,\1y,' $1/.config
> +               sed -ri=""               's,(PCAP=)n,\1y,' $1/.config
>                 test -z "$ARMV8_CRYPTO_LIB_PATH" || \
> -               sed -ri   's,(PMD_ARMV8_CRYPTO=)n,\1y,' $1/.config
> +               sed -ri=""   's,(PMD_ARMV8_CRYPTO=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_IPSEC_MB" != y || \
> -               sed -ri       's,(PMD_AESNI_MB=)n,\1y,' $1/.config
> +               sed -ri=""       's,(PMD_AESNI_MB=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_IPSEC_MB" != y || \
> -               sed -ri      's,(PMD_AESNI_GCM=)n,\1y,' $1/.config
> +               sed -ri=""      's,(PMD_AESNI_GCM=)n,\1y,' $1/.config
>                 test -z "$LIBSSO_SNOW3G_PATH" || \
> -               sed -ri         's,(PMD_SNOW3G=)n,\1y,' $1/.config
> +               sed -ri=""         's,(PMD_SNOW3G=)n,\1y,' $1/.config
>                 test -z "$LIBSSO_KASUMI_PATH" || \
> -               sed -ri         's,(PMD_KASUMI=)n,\1y,' $1/.config
> +               sed -ri=""         's,(PMD_KASUMI=)n,\1y,' $1/.config
>                 test -z "$LIBSSO_ZUC_PATH" || \
> -               sed -ri            's,(PMD_ZUC=)n,\1y,' $1/.config
> +               sed -ri=""            's,(PMD_ZUC=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_SSL" != y || \
> -               sed -ri            's,(PMD_CCP=)n,\1y,' $1/.config
> +               sed -ri=""            's,(PMD_CCP=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_SSL" != y || \
> -               sed -ri        's,(PMD_OPENSSL=)n,\1y,' $1/.config
> +               sed -ri=""        's,(PMD_OPENSSL=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_SSL" != y || \
> -               sed -ri            's,(QAT_SYM=)n,\1y,' $1/.config
> +               sed -ri=""            's,(QAT_SYM=)n,\1y,' $1/.config
>                 test -z "$FLEXRAN_SDK" || \
> -               sed -ri     's,(BBDEV_TURBO_SW=)n,\1y,' $1/.config
> -               sed -ri           's,(SCHED_.*=)n,\1y,' $1/.config
> +               sed -ri=""     's,(BBDEV_TURBO_SW=)n,\1y,' $1/.config
> +               sed -ri=""           's,(SCHED_.*=)n,\1y,' $1/.config
>                 test -z "$LIBMUSDK_PATH" || \
> -               sed -ri   's,(PMD_MVSAM_CRYPTO=)n,\1y,' $1/.config
> +               sed -ri=""   's,(PMD_MVSAM_CRYPTO=)n,\1y,' $1/.config
>                 test -z "$LIBMUSDK_PATH" || \
> -               sed -ri          's,(MVPP2_PMD=)n,\1y,' $1/.config
> +               sed -ri=""          's,(MVPP2_PMD=)n,\1y,' $1/.config
>                 test -z "$LIBMUSDK_PATH" || \
> -               sed -ri         's,(MVNETA_PMD=)n,\1y,' $1/.config
> +               sed -ri=""         's,(MVNETA_PMD=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_ELF" != y || \
> -               sed -ri            's,(BPF_ELF=)n,\1y,' $1/.config
> +               sed -ri=""            's,(BPF_ELF=)n,\1y,' $1/.config
>                 test "$DPDK_DEP_JSON" != y || \
> -               sed -ri          's,(TELEMETRY=)n,\1y,' $1/.config
> +               sed -ri=""          's,(TELEMETRY=)n,\1y,' $1/.config
>                 build_config_hook $1 $2 $3
>
>                 # Explicit enabler/disabler (uppercase)
>                 for option in $(echo $3 | sed 's,[~+], &,g') ; do
>                         pattern=$(echo $option | cut -c2-)
>                         if echo $option | grep -q '^~' ; then
> -                               sed -ri "s,($pattern=)y,\1n," $1/.config
> +                               sed -ri="" "s,($pattern=)y,\1n," $1/.config
>                         elif echo $option | grep -q '^+' ; then
> -                               sed -ri "s,($pattern=)n,\1y," $1/.config
> +                               sed -ri="" "s,($pattern=)n,\1y," $1/.config
>                         fi
>                 done
>         fi
> @@ -220,22 +224,22 @@ for conf in $configs ; do
>         # reload config with DPDK_TARGET set
>         DPDK_TARGET=$target
>         reset_env
> -       . $(dirname $(readlink -e $0))/load-devel-config
> +       . $(dirname $(readlink -f $0))/load-devel-config
>
>         options=$(echo $conf | sed 's,[^~+]*,,')
>         dir=$conf
>         config $dir $target $options
>
>         echo "================== Build $dir"
> -       make -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \
> +       ${MAKE} -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \
>                 EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose O=$dir
>         ! $short || break
>         echo "================== Build examples for $dir"
>         export RTE_SDK=$(pwd)
>         export RTE_TARGET=$dir
> -       make -j$J -sC examples \
> +       ${MAKE} -j$J -sC examples \
>                 EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \
> -               O=$(readlink -m $dir/examples)
> +               O=$(readlink -f $dir)/examples
>         unset RTE_TARGET
>         echo "################## $dir done."
>         unset dir
> @@ -244,9 +248,9 @@ done
>  if ! $short ; then
>         mkdir -p .check
>         echo "================== Build doxygen HTML API"
> -       make doc-api-html >/dev/null 2>.check/doc.txt
> +       ${MAKE} doc-api-html >/dev/null 2>.check/doc.txt
>         echo "================== Build sphinx HTML guides"
> -       make doc-guides-html >/dev/null 2>>.check/doc.txt
> +       ${MAKE} doc-guides-html >/dev/null 2>>.check/doc.txt
>         echo "================== Check docs"
>         diff -u /dev/null .check/doc.txt
>  fi
> diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
> index 138436d93..f64e19d38 100755
> --- a/devtools/validate-abi.sh
> +++ b/devtools/validate-abi.sh
> @@ -181,7 +181,7 @@ case "${dst}" in
>         /*) ;;
>         *) dst=${PWD}/${dst} ;;
>  esac
> -dpdkroot=$(readlink -e $(dirname $0)/..)
> +dpdkroot=$(readlink -f $(dirname $0)/..)
>
>  if [ -e "${dst}" -a "$force" = 0 ]; then
>         echo "The ${dst} directory is not empty. Remove it, use another"
> --
> 2.11.0
>

Reviewed-by: David Marchand <david.marchand@redhat.com>

-- 
David Marchand

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] eal: resort symbols in EXPERIMENTAL section
  @ 2019-07-26 13:54  0%         ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-07-26 13:54 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon; +Cc: Stephen Hemminger, dev

On Thu, Jun 20, 2019 at 7:23 PM David Marchand
<david.marchand@redhat.com> wrote:
>
>
>
> On Fri, Jun 14, 2019 at 5:32 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>> On 6/14/2019 8:44 AM, David Marchand wrote:
>> > On Fri, Jun 14, 2019 at 9:39 AM Thomas Monjalon <thomas@monjalon.net> wrote:
>> >
>> >> 06/04/2019 05:30, Stephen Hemminger:
>> >>> The symbols in the EXPERIMENTAL were close to alphabetic
>> >>> order but running sort showed several mistakes.
>> >>>
>> >>> This has no impact on code, API, ABI or otherwise.
>> >>> Purely for humans.
>> >>>
>> >>> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>> >>
>> >> I don't think it's worth adding a layer of git history for this sort.
>> >> I would prefer to leave it as is.
>> >>
>> >>
>> > If this is about preferrence, I would prefer we have those symbols sorted
>> > per versions that introduced them ;-).
>> > Much easier to check and see if they are candidates for entering stable ABI.
>> >
>>
>> Not bad idea, +1 from my side J
>
>
> Here is what it looks like:
> https://github.com/david-marchand/dpdk/commit/cab0d75ea6bdc7782566d7aad6718b9f5fa784f7

Sent the patch rebased on master.
https://patchwork.dpdk.org/patch/57172/


-- 
David Marchand

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [dpdk-announce] You're Invited: DPDK Userspace, Sept. 19-20, Bordeaux, France
@ 2019-07-24 22:22  4% Jill Lovato
  0 siblings, 0 replies; 200+ results
From: Jill Lovato @ 2019-07-24 22:22 UTC (permalink / raw)
  To: announce

DPDK Community,

We invite you to attend the upcoming DPDK Userspace
<https://events.linuxfoundation.org/events/dpdk-userspace-2019-bordeaux/>
event, happening September 19-20 in Bordeaux, France.

DPDK Userspace, the community’s flagship event which brings together users
and developers, is going on the road and headed to in Bordeaux, France.

This year’s agenda will focus on 4 topics:

        - new APIs (mbuf, Ethernet, IPsec, regex, DMA, PRNG)

        - algorithms (performance, lock-free, virtio failover, QoS)

        - use cases (storage, NFV, Docker, Kubernetes, Alibaba)

        - community process (CI, tooling, ABI stability)

Join us in France to learn about the future of data plane acceleration.
More details are included below, including the event agenda and how to
register.

AGENDA:

https://events.linuxfoundation.org/events/dpdk-userspace-2019-bordeaux/program/schedule/

SEPTEMBER 19

08:00: Registration

09:00: Introduction

09:30: Dynamic mbuf - Thomas Monjalon, Mellanox

10:00: Which Standard for Ethernet Statistics? - Thomas Monjalon, Mellanox

10:30: MORNING BREAK

10:45: Recent Advances in DPDK IPSec - Konastantin Ananiev, Intel

11:15: DPDK Regex Device - Shahaf Shuler, Mellanox

11:45: Adding Eventdev support in IP-secgw and other apps - Hemant Agrawal,
NXP

12:00: Accelerating Memory Copy with the DMA Copy Library - Jiayu Hu, Intel

12:30: LUNCH

13:45: DPDK Thread-Safe High Performance Pseudo-Random Number Generation -
Mattias Rooblom, Ericsson

14:15: Better Development with Robots - Aaron Conole, RedHat

14:30: DPDK Community Updates - John McNamara, Intel

15:00 Community Survey Analysis and Conclusion - Honnappa Nagarahalli, Arm

15:15: DPD.org Services, Latest and Future Planned Improvements - Ali
Alnubani, Mellanox

15:45: AFTERNOON BREAK

16:15: Introduction to the New DPDK Vulnerabilities Management Process -
Maxime Coquelin

16:30: DPDK LTS Update - Kevin Traynor, RedHat

17:00 Does DPDK Need a Stable ABI? - Stephen Hemminger, Microsoft & Ray
Kinsells, Intel

18:00: COCKTAIL RECEPTION

SEPTEMBER 20

9:00: Integrating RCU Library with Data Structures - Honnappa Nagarahalli,
Arm

9:30: Current Sorry State of c11 Code and Suggestions for Fix It - Phil
Yang, Arm

10:00 Arm64 WFE Mechanism and Use Cases in DPDK - Gavin Hu, Arm

10:30 : MORNING BREAK

11:00 DPDK Build System Status and Plans - Bruce Richardson, Intel

11:15: What is Wrong with Existing Packet Capture (and How to Fix It) -
Stephen Hemminger, Microsoft

11:30: Virtion-net Failover in DPDK - Jen Freimann, RedHat

12:00: DPDK-Accelerated Partial Offload for Fine-Grained HQoS - Rosen Xu,
Intel

12:30 LUNCH

14:00 Higher Guaranteed Performance for DPDK Threads via New Power Library
Changes - David Hunt, Intel

14:30: Measure Software Performance of Data Plane Applications - Harry van
Haaren, Intel

15:00: rte Flow at Large-Scale in Production is Really Happening - Alex
Rosenabum, Mellanox

15:30: AFTERNOON BREAK

16:00 DPDK Expands Into Storage Domain - Darek Stojaczyk & Fiona Trahe,
Intel

16:30: Docker VNFs and Packet Throughput Using Lib 1 Net and DPDK - Anthony
Fee, Emutex

16:45: State of DPDK in Network Service Mesh - Frederick Kautz, Doc.ai

17:00: Conclusion

17:30: Permanent Exhibition Tour at La Cite du Vin

REGISTER TODAY

DPDK Userspace 2019 is complimentary to attend. To register, visit this link
<https://www.cvent.com/events/dpdk-userspace-2019-bordeaux/registration-2399e1cbffd14eb9bb834f307925522a.aspx?_ga=2.125206282.1212887052.1563230168-1943177193.1548103697&fqp=true>
.

Please send any questions to events@dpdk.org and we hope to see many of you
in Bordeaux!




-- 
*Jill Lovato*
Senior PR Manager
The Linux Foundation
jlovato@linuxfoundation.org
Phone: +1.503.703.8268

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] pci: fix missing pci bus with shared library build
  @ 2019-07-24  8:56  3%             ` Bruce Richardson
  0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-07-24  8:56 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Thomas Monjalon, dev

On Tue, Jul 23, 2019 at 11:11:14AM -0700, Stephen Hemminger wrote:
> On Tue, 23 Jul 2019 13:30:33 +0100
> Bruce Richardson <bruce.richardson@intel.com> wrote:
> 
> > On Mon, Jul 22, 2019 at 11:53:26AM -0700, Stephen Hemminger wrote:
> > > On Mon, 22 Jul 2019 19:31:08 +0200
> > > Thomas Monjalon <thomas@monjalon.net> wrote:
> > >   
> > > > 22/07/2019 19:13, Stephen Hemminger:  
> > > > > Thomas Monjalon <thomas@monjalon.net> wrote:    
> > > > > > Are the constructors run on dlopen of the bus driver?    
> > > > > 
> > > > > Yes, constructors are run on dlopen.
> > > > > But application should not have to ask DPDK to dlopen the bus devices.
> > > > > 
> > > > > The core principle is that dynamic build of DPDK should act the same as old
> > > > > statically linked DPDK. Otherwise, the user experience is even worse, and all
> > > > > the example documentation is wrong.    
> > > > 
> > > > OK, this is where I wanted to bring the discussion.
> > > > You are arguing against a design which is in DPDK from some early days.
> > > > So this is an interesting discussion to have.
> > > > Do we want to change the "plugin model" we have?
> > > > Or do we want to simply drop this model (dlopen calls)
> > > > and replace it with strong dynamic linking?
> > > > 
> > > >   
> > > 
> > > What I think should happen (and isn't is):
> > > 
> > > 1. The PCI bus library is linked with --whole-archive, and --no-as-needed.
> > >    This causes constructor to be called and register the bus.
> > >   
> > 
> > This should be applied to the whole of the bus drivers, not just the PCI
> > bus.
> > 
> > > 2. As part of the build process all the PCI drivers pmdinfo would get
> > >    constructed into a table of vendor/device to PMD shared library name.
> > > 
> > > 3. PMD's are linked as --whole-archive, and --as-needed.
> > >   
> > 
> > I'm not sure I agree with this change to always link in all the PMDs. It
> > prevents an app from being used with just a subset of the drivers needed.
> > 
> > > 4. New code in PCI probe which looks for existing entries (static or -d)
> > >    for devices. If device is still not found it refers to the table of PMD's
> > >    (from #2) and calls dlopen for that device (and adds it to static table).
> > > 
> > > This would allow examples and customer applications to Just Work without
> > > having to know the PMD that is present. It would also solve the problem
> > > that currently if applications is linked with -ldpdk linker script then
> > > all PMD's get pulled into the application address space.
> > >   
> > 
> > In all this you seem to be assuming that the drivers are not picked up at
> > runtime from the RTE_EAL_PMD_PATH. In real world cases where a user is
> > building an app, and not developing DPDK itself, the DPDK libraries should
> > be installed in /usr(/local)/lib64 and the drivers in
> > .../lib64/dpdk/dpdk-19.08. In that case, the bus drivers and the PMD
> > drivers are all loaded at runtime for each app, without having any
> > dependency on having a specific one be present, allowing a user to remove
> > any drivers unnecessary for the current hardware.
> > 
> > Did you try installing DPDK using "ninja install" or "make install" before
> > running any apps using it?
> > 
> > /Bruce
> 
> I was using "make install-runtime" into a local chroot directory like
> a distribution package builder does.
> 
> 
> There are multiple use cases:
> 1. Developer build DPDK and application together on one machine (and running on another).
>    Or software appliance being built on one machine and run in many environments.
>    Also cross builds are like this.
> 
Sure, but the expectation here is that the resultant build is installed in
system locations, or a known location. As part of the build EAL_PMD_PATH
needs to be set to the final driver location and then the driver loading
issue requiring "-d" flag goes away.

> 2. Distribution building a package (and installing in standard library locations /lib etc).
> 
No issue here, since package building is not going to be a problem and when
installed the drivers are all picked up from the EAL_PMD_PATH.

> 3. Demo machine where build is local and native.
> 
> DPDK seems to always focus on #3 which is least interesting for real production.

You are missing our primary target use-case for the future -
* developer builds application using distro-supplied DPDK.

Individual developers building their own DPDK alongside their app should be
a thing of the past. DPDK needs to be come like other libraries e.g. zlib,
openssl, where app developers just pick it up from their linux distro and
not feel the need to roll their own.

Yes, there will be cases where things are more memory constrained etc. and
this model won't work, but despite this, it should be our primary target.
To get there, though, there is still work to be done, e.g. in increasing
ABI compatibility to allow easier adoption by distros, etc.

/Bruce

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2] ethdev: avoid usage of uninit device info in bad port case
  2019-07-23 13:39  0%       ` Thomas Monjalon
@ 2019-07-23 18:45  0%         ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-07-23 18:45 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, Ferruh Yigit, stable

23/07/2019 15:39, Thomas Monjalon:
> 23/07/2019 15:34, Andrew Rybchenko:
> > On 7/23/19 4:14 PM, Thomas Monjalon wrote:
> > > 23/07/2019 14:11, Andrew Rybchenko:
> > >> rte_eth_dev_info_get() returns void and caller does know if the function
> > >> does its job or not. Changing of the return value to int would be
> > >> API/ABI breakage which requires deprecation process and cannot be
> > >> backported to stable branches. For now, make sure that device info is
> > >> initialized even in the case of invalid port ID.
> > >>
> > >> Fixes: a30268e9a2d0 ("ethdev: reset whole dev info structure before filling")
> > >> Cc: stable@dpdk.org
> > >>
> > >> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
> 
> Acked-by: Thomas Monjalon <thomas@monjalon.net>

Applied, thanks



^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2] ethdev: avoid usage of uninit device info in bad port case
  2019-07-23 13:34  0%     ` Andrew Rybchenko
@ 2019-07-23 13:39  0%       ` Thomas Monjalon
  2019-07-23 18:45  0%         ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-07-23 13:39 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, Ferruh Yigit, stable

23/07/2019 15:34, Andrew Rybchenko:
> On 7/23/19 4:14 PM, Thomas Monjalon wrote:
> > 23/07/2019 14:11, Andrew Rybchenko:
> >> rte_eth_dev_info_get() returns void and caller does know if the function
> >> does its job or not. Changing of the return value to int would be
> >> API/ABI breakage which requires deprecation process and cannot be
> >> backported to stable branches. For now, make sure that device info is
> >> initialized even in the case of invalid port ID.
> >>
> >> Fixes: a30268e9a2d0 ("ethdev: reset whole dev info structure before filling")
> >> Cc: stable@dpdk.org
> >>
> >> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
> >> ---
> >> --- a/lib/librte_ethdev/rte_ethdev.c
> >> +++ b/lib/librte_ethdev/rte_ethdev.c
> >> +	/*
> >> +	 * Init dev_info before port_id check since caller does not have
> >> +	 * return status and does not know if get is successful or not.
> >> +	 */
> >> +	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
> > If someone was using a canary to detect failure, it will be resetted.
> 
> I've not thought about such ways to check. I would expected check
> for not NULL device or driver_name. It is not defined behaviour of
> the function to not touch dev_info in the case of bad port ID.
> 
> > Why is it urgent to have this workaround?
> 
> Nothing really urgent, but I still think that it is a right fix to be
> applied and backported to stable branches.
> I really met calls with invalid port ID and it took some time
> to understand where uninitialized data come from.
> 
> > Can we wait one more release for the definitive fix with error code?
> 
> No strong opinion, but definitive fix will not be backported.

You're right.
Acked-by: Thomas Monjalon <thomas@monjalon.net>




^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2] ethdev: avoid usage of uninit device info in bad port case
  2019-07-23 13:14  0%   ` Thomas Monjalon
@ 2019-07-23 13:34  0%     ` Andrew Rybchenko
  2019-07-23 13:39  0%       ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-07-23 13:34 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Ferruh Yigit, stable

On 7/23/19 4:14 PM, Thomas Monjalon wrote:
> 23/07/2019 14:11, Andrew Rybchenko:
>> rte_eth_dev_info_get() returns void and caller does know if the function
>> does its job or not. Changing of the return value to int would be
>> API/ABI breakage which requires deprecation process and cannot be
>> backported to stable branches. For now, make sure that device info is
>> initialized even in the case of invalid port ID.
>>
>> Fixes: a30268e9a2d0 ("ethdev: reset whole dev info structure before filling")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
>> ---
>> --- a/lib/librte_ethdev/rte_ethdev.c
>> +++ b/lib/librte_ethdev/rte_ethdev.c
>> +	/*
>> +	 * Init dev_info before port_id check since caller does not have
>> +	 * return status and does not know if get is successful or not.
>> +	 */
>> +	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
> If someone was using a canary to detect failure, it will be resetted.

I've not thought about such ways to check. I would expected check
for not NULL device or driver_name. It is not defined behaviour of
the function to not touch dev_info in the case of bad port ID.

> Why is it urgent to have this workaround?

Nothing really urgent, but I still think that it is a right fix to be
applied and backported to stable branches.
I really met calls with invalid port ID and it took some time
to understand where uninitialized data come from.

> Can we wait one more release for the definitive fix with error code?

No strong opinion, but definitive fix will not be backported.

>> +
>>   	RTE_ETH_VALID_PORTID_OR_RET(port_id);
>>   	dev = &rte_eth_devices[port_id];
>>   
>> -	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
>>   	dev_info->rx_desc_lim = lim;
>>   	dev_info->tx_desc_lim = lim;
>>   	dev_info->device = dev->device;
>>


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v2] ethdev: avoid usage of uninit device info in bad port case
  2019-07-23 12:11  3% ` [dpdk-dev] [PATCH v2] " Andrew Rybchenko
@ 2019-07-23 13:14  0%   ` Thomas Monjalon
  2019-07-23 13:34  0%     ` Andrew Rybchenko
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-07-23 13:14 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, Ferruh Yigit, stable

23/07/2019 14:11, Andrew Rybchenko:
> rte_eth_dev_info_get() returns void and caller does know if the function
> does its job or not. Changing of the return value to int would be
> API/ABI breakage which requires deprecation process and cannot be
> backported to stable branches. For now, make sure that device info is
> initialized even in the case of invalid port ID.
> 
> Fixes: a30268e9a2d0 ("ethdev: reset whole dev info structure before filling")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> +	/*
> +	 * Init dev_info before port_id check since caller does not have
> +	 * return status and does not know if get is successful or not.
> +	 */
> +	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));

If someone was using a canary to detect failure, it will be resetted.
Why is it urgent to have this workaround?
Can we wait one more release for the definitive fix with error code?

> +
>  	RTE_ETH_VALID_PORTID_OR_RET(port_id);
>  	dev = &rte_eth_devices[port_id];
>  
> -	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
>  	dev_info->rx_desc_lim = lim;
>  	dev_info->tx_desc_lim = lim;
>  	dev_info->device = dev->device;






^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] ethdev: avoid usage of uninit device info in bad port case
  2019-07-23 12:16  3%   ` Andrew Rybchenko
@ 2019-07-23 12:50  0%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-07-23 12:50 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: Ferruh Yigit, dev, stable

23/07/2019 14:16, Andrew Rybchenko:
> On 7/23/19 1:40 PM, Ferruh Yigit wrote:
> > On 7/23/2019 10:13 AM, Andrew Rybchenko wrote:
> >> rte_eth_dev_info_get() returns void and caller does know if the function
> >> does its job or not. Changing of the return value to int would be
> >> API/ABI breakage which requires deprecation process and cannot be
> >> backported to stable branches. For now, make sure that device info is
> >> initialized even in the case of invalid port ID.
> > +1 to return a status from function for long term.
> 
> Thomas, what do you think? Should we finally fix it?
> I think it is almost harmless API/ABI breakage.
> If yes, I'll send deprecation notice to do it in v19.11.

Yes, generally speaking we should not have any void return in API.




^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] ethdev: avoid usage of uninit device info in bad port case
  2019-07-23 10:40  0% ` Ferruh Yigit
@ 2019-07-23 12:16  3%   ` Andrew Rybchenko
  2019-07-23 12:50  0%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-07-23 12:16 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon; +Cc: dev, stable

On 7/23/19 1:40 PM, Ferruh Yigit wrote:
> On 7/23/2019 10:13 AM, Andrew Rybchenko wrote:
>> rte_eth_dev_info_get() returns void and caller does know if the function
>> does its job or not. Changing of the return value to int would be
>> API/ABI breakage which requires deprecation process and cannot be
>> backported to stable branches. For now, make sure that device info is
>> initialized even in the case of invalid port ID.
> +1 to return a status from function for long term.

Thomas, what do you think? Should we finally fix it?
I think it is almost harmless API/ABI breakage.
If yes, I'll send deprecation notice to do it in v19.11.

> But someone looks below code can think we are doing an unnecessary memset for
> the error case, and will fix it :)
> What do you think adding a comment to prevent this?

See v2.

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v2] ethdev: avoid usage of uninit device info in bad port case
  2019-07-23  9:13  3% [dpdk-dev] [PATCH] ethdev: avoid usage of uninit device info in bad port case Andrew Rybchenko
  2019-07-23 10:40  0% ` Ferruh Yigit
@ 2019-07-23 12:11  3% ` Andrew Rybchenko
  2019-07-23 13:14  0%   ` Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-07-23 12:11 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit; +Cc: dev, stable

rte_eth_dev_info_get() returns void and caller does know if the function
does its job or not. Changing of the return value to int would be
API/ABI breakage which requires deprecation process and cannot be
backported to stable branches. For now, make sure that device info is
initialized even in the case of invalid port ID.

Fixes: a30268e9a2d0 ("ethdev: reset whole dev info structure before filling")
Cc: stable@dpdk.org

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_ethdev/rte_ethdev.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 64191737c..17d183e1f 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2552,10 +2552,15 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 		.nb_mtu_seg_max = UINT16_MAX,
 	};
 
+	/*
+	 * Init dev_info before port_id check since caller does not have
+	 * return status and does not know if get is successful or not.
+	 */
+	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
+
 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
 	dev = &rte_eth_devices[port_id];
 
-	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 	dev_info->rx_desc_lim = lim;
 	dev_info->tx_desc_lim = lim;
 	dev_info->device = dev->device;
-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v8 3/5] kni: add app specific mempool create & free routine
  2019-07-23 10:50  0%     ` Andrew Rybchenko
@ 2019-07-23 11:01  0%       ` Vamsi Krishna Attunuru
  0 siblings, 0 replies; 200+ results
From: Vamsi Krishna Attunuru @ 2019-07-23 11:01 UTC (permalink / raw)
  To: Andrew Rybchenko, dev
  Cc: thomas, Jerin Jacob Kollanukkaran, olivier.matz, ferruh.yigit,
	anatoly.burakov, Kiran Kumar Kokkilagadda



> -----Original Message-----
> From: Andrew Rybchenko <arybchenko@solarflare.com>
> Sent: Tuesday, July 23, 2019 4:20 PM
> To: Vamsi Krishna Attunuru <vattunuru@marvell.com>; dev@dpdk.org
> Cc: thomas@monjalon.net; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> olivier.matz@6wind.com; ferruh.yigit@intel.com; anatoly.burakov@intel.com;
> Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
> Subject: Re: [dpdk-dev] [PATCH v8 3/5] kni: add app specific mempool create &
> free routine
> 
> On 7/23/19 8:38 AM, vattunuru@marvell.com wrote:
> > From: Vamsi Attunuru <vattunuru@marvell.com>
> >
> > When KNI operates in IOVA = VA mode, it requires mbuf memory to be
> > physically contiguous to ensure KNI kernel module could translate IOVA
> > addresses properly. Patch adds a KNI specific mempool create routine
> > to populate the KNI packet mbuf pool with memory objects that are
> > being on a page.
> >
> > KNI applications need to use this mempool create & free routines so
> > that mbuf related requirements in IOVA = VA mode are handled inside
> > those routines based on the enabled mode.
> >
> > Updated the release notes with these new routine details.
> >
> > Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
> > Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
> > ---
> >   doc/guides/rel_notes/release_19_08.rst |  6 ++++
> >   examples/kni/main.c                    |  6 +++-
> >   lib/librte_kni/Makefile                |  1 +
> >   lib/librte_kni/meson.build             |  1 +
> >   lib/librte_kni/rte_kni.c               | 59 ++++++++++++++++++++++++++++++++++
> >   lib/librte_kni/rte_kni.h               | 49 ++++++++++++++++++++++++++++
> >   lib/librte_kni/rte_kni_version.map     |  2 ++
> >   7 files changed, 123 insertions(+), 1 deletion(-)
> >
> > diff --git a/doc/guides/rel_notes/release_19_08.rst
> > b/doc/guides/rel_notes/release_19_08.rst
> > index 0a3f840..bd01e99 100644
> > --- a/doc/guides/rel_notes/release_19_08.rst
> > +++ b/doc/guides/rel_notes/release_19_08.rst
> > @@ -281,6 +281,12 @@ API Changes
> >     offload flag from the library. The application must set this flag if it is
> >     supported by the platform and application wishes to use it.
> >
> > +* kni: ``rte_kni_pktmbuf_pool_create`` ``rte_kni_pktmbuf_pool_free``
> > +functions
> > +  were introduced for KNI applications for creating & freeing packet pool.
> > +  Since IOVA=VA mode was added in KNI, packet pool's mbuf memory
> > +should be
> > +  physically contiguous for the KNI kernel module to work in IOVA=VA
> > +mode,
> > +  this requirment was taken care in the kni packet pool creation fucntions.
> > +
> >
> >   ABI Changes
> >   -----------
> > diff --git a/examples/kni/main.c b/examples/kni/main.c index
> > 4710d71..3b9c067 100644
> > --- a/examples/kni/main.c
> > +++ b/examples/kni/main.c
> > @@ -975,7 +975,7 @@ main(int argc, char** argv)
> >   		rte_exit(EXIT_FAILURE, "Could not parse input parameters\n");
> >
> >   	/* Create the mbuf pool */
> > -	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
> > +	pktmbuf_pool = rte_kni_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
> >   		MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
> >   	if (pktmbuf_pool == NULL) {
> >   		rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool\n"); @@
> > -1043,6 +1043,10 @@ main(int argc, char** argv)
> >   			continue;
> >   		kni_free_kni(port);
> >   	}
> > +
> > +	if (pktmbuf_pool)
> 
> Typically pointer is compared to NULL, but it is not required here anyway, since
> rte_mempool_free() handles NULL perfectly itself.

Ack

> 
> > +		rte_kni_pktmbuf_pool_free(pktmbuf_pool);
> > +
> >   	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
> >   		if (kni_port_params_array[i]) {
> >   			rte_free(kni_port_params_array[i]);
> 
> <...>
> 
> > diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h index
> > 5699a64..7f11927 100644
> > --- a/lib/librte_kni/rte_kni.h
> > +++ b/lib/librte_kni/rte_kni.h
> > @@ -20,6 +20,7 @@
> >   #include <rte_pci.h>
> >   #include <rte_memory.h>
> >   #include <rte_mempool.h>
> > +#include <rte_mbuf_pool_ops.h>
> 
> I don't understand why it is included here.
> 
included to fix compilation of rte_kni.c post this patch changes,  could be included in rte_kni.c though.

> >   #include <rte_ether.h>
> >
> >   #include <rte_kni_common.h>
> >
> 
> <...>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v8 3/5] kni: add app specific mempool create & free routine
  2019-07-23  5:38  3%   ` [dpdk-dev] [PATCH v8 3/5] kni: add app specific mempool create & free routine vattunuru
@ 2019-07-23 10:50  0%     ` Andrew Rybchenko
  2019-07-23 11:01  0%       ` Vamsi Krishna Attunuru
  0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-07-23 10:50 UTC (permalink / raw)
  To: vattunuru, dev
  Cc: thomas, jerinj, olivier.matz, ferruh.yigit, anatoly.burakov, kirankumark

On 7/23/19 8:38 AM, vattunuru@marvell.com wrote:
> From: Vamsi Attunuru <vattunuru@marvell.com>
>
> When KNI operates in IOVA = VA mode, it requires mbuf memory
> to be physically contiguous to ensure KNI kernel module could
> translate IOVA addresses properly. Patch adds a KNI specific
> mempool create routine to populate the KNI packet mbuf pool
> with memory objects that are being on a page.
>
> KNI applications need to use this mempool create & free routines
> so that mbuf related requirements in IOVA = VA mode are handled
> inside those routines based on the enabled mode.
>
> Updated the release notes with these new routine details.
>
> Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
> Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
> ---
>   doc/guides/rel_notes/release_19_08.rst |  6 ++++
>   examples/kni/main.c                    |  6 +++-
>   lib/librte_kni/Makefile                |  1 +
>   lib/librte_kni/meson.build             |  1 +
>   lib/librte_kni/rte_kni.c               | 59 ++++++++++++++++++++++++++++++++++
>   lib/librte_kni/rte_kni.h               | 49 ++++++++++++++++++++++++++++
>   lib/librte_kni/rte_kni_version.map     |  2 ++
>   7 files changed, 123 insertions(+), 1 deletion(-)
>
> diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
> index 0a3f840..bd01e99 100644
> --- a/doc/guides/rel_notes/release_19_08.rst
> +++ b/doc/guides/rel_notes/release_19_08.rst
> @@ -281,6 +281,12 @@ API Changes
>     offload flag from the library. The application must set this flag if it is
>     supported by the platform and application wishes to use it.
>   
> +* kni: ``rte_kni_pktmbuf_pool_create`` ``rte_kni_pktmbuf_pool_free`` functions
> +  were introduced for KNI applications for creating & freeing packet pool.
> +  Since IOVA=VA mode was added in KNI, packet pool's mbuf memory should be
> +  physically contiguous for the KNI kernel module to work in IOVA=VA mode,
> +  this requirment was taken care in the kni packet pool creation fucntions.
> +
>   
>   ABI Changes
>   -----------
> diff --git a/examples/kni/main.c b/examples/kni/main.c
> index 4710d71..3b9c067 100644
> --- a/examples/kni/main.c
> +++ b/examples/kni/main.c
> @@ -975,7 +975,7 @@ main(int argc, char** argv)
>   		rte_exit(EXIT_FAILURE, "Could not parse input parameters\n");
>   
>   	/* Create the mbuf pool */
> -	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
> +	pktmbuf_pool = rte_kni_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
>   		MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
>   	if (pktmbuf_pool == NULL) {
>   		rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool\n");
> @@ -1043,6 +1043,10 @@ main(int argc, char** argv)
>   			continue;
>   		kni_free_kni(port);
>   	}
> +
> +	if (pktmbuf_pool)

Typically pointer is compared to NULL, but it is not required here
anyway, since rte_mempool_free() handles NULL perfectly itself.

> +		rte_kni_pktmbuf_pool_free(pktmbuf_pool);
> +
>   	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
>   		if (kni_port_params_array[i]) {
>   			rte_free(kni_port_params_array[i]);

<...>

> diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
> index 5699a64..7f11927 100644
> --- a/lib/librte_kni/rte_kni.h
> +++ b/lib/librte_kni/rte_kni.h
> @@ -20,6 +20,7 @@
>   #include <rte_pci.h>
>   #include <rte_memory.h>
>   #include <rte_mempool.h>
> +#include <rte_mbuf_pool_ops.h>

I don't understand why it is included here.

>   #include <rte_ether.h>
>   
>   #include <rte_kni_common.h>
>

<...>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] ethdev: avoid usage of uninit device info in bad port case
  2019-07-23  9:13  3% [dpdk-dev] [PATCH] ethdev: avoid usage of uninit device info in bad port case Andrew Rybchenko
@ 2019-07-23 10:40  0% ` Ferruh Yigit
  2019-07-23 12:16  3%   ` Andrew Rybchenko
  2019-07-23 12:11  3% ` [dpdk-dev] [PATCH v2] " Andrew Rybchenko
  1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-07-23 10:40 UTC (permalink / raw)
  To: Andrew Rybchenko, Thomas Monjalon; +Cc: dev, stable

On 7/23/2019 10:13 AM, Andrew Rybchenko wrote:
> rte_eth_dev_info_get() returns void and caller does know if the function
> does its job or not. Changing of the return value to int would be
> API/ABI breakage which requires deprecation process and cannot be
> backported to stable branches. For now, make sure that device info is
> initialized even in the case of invalid port ID.

+1 to return a status from function for long term.

But someone looks below code can think we are doing an unnecessary memset for
the error case, and will fix it :)
What do you think adding a comment to prevent this?

> 
> Fixes: a30268e9a2d0 ("ethdev: reset whole dev info structure before filling")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>  lib/librte_ethdev/rte_ethdev.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index 64191737c..97b093edc 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -2552,10 +2552,11 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
>  		.nb_mtu_seg_max = UINT16_MAX,
>  	};
>  
> +	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
> +
>  	RTE_ETH_VALID_PORTID_OR_RET(port_id);
>  	dev = &rte_eth_devices[port_id];
>  
> -	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
>  	dev_info->rx_desc_lim = lim;
>  	dev_info->tx_desc_lim = lim;
>  	dev_info->device = dev->device;
> 


^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH] ethdev: avoid usage of uninit device info in bad port case
@ 2019-07-23  9:13  3% Andrew Rybchenko
  2019-07-23 10:40  0% ` Ferruh Yigit
  2019-07-23 12:11  3% ` [dpdk-dev] [PATCH v2] " Andrew Rybchenko
  0 siblings, 2 replies; 200+ results
From: Andrew Rybchenko @ 2019-07-23  9:13 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit; +Cc: dev, stable

rte_eth_dev_info_get() returns void and caller does know if the function
does its job or not. Changing of the return value to int would be
API/ABI breakage which requires deprecation process and cannot be
backported to stable branches. For now, make sure that device info is
initialized even in the case of invalid port ID.

Fixes: a30268e9a2d0 ("ethdev: reset whole dev info structure before filling")
Cc: stable@dpdk.org

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_ethdev/rte_ethdev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 64191737c..97b093edc 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2552,10 +2552,11 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 		.nb_mtu_seg_max = UINT16_MAX,
 	};
 
+	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
+
 	RTE_ETH_VALID_PORTID_OR_RET(port_id);
 	dev = &rte_eth_devices[port_id];
 
-	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 	dev_info->rx_desc_lim = lim;
 	dev_info->tx_desc_lim = lim;
 	dev_info->device = dev->device;
-- 
2.17.1


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v8 1/3] eal/arm64: add 128-bit atomic compare exchange
  2019-07-23  5:57  2% ` [dpdk-dev] [PATCH v7 " Phil Yang
@ 2019-07-23  7:05  2%   ` jerinj
  2019-08-14  8:27  2%     ` [dpdk-dev] [PATCH v9 " Phil Yang
  0 siblings, 1 reply; 200+ results
From: jerinj @ 2019-07-23  7:05 UTC (permalink / raw)
  To: dev, Thomas Monjalon, Jerin Jacob, Gavin Hu, Jan Viktorin,
	Bruce Richardson, Konstantin Ananyev
  Cc: Phil Yang, Honnappa Nagarahalli

From: Phil Yang <phil.yang@arm.com>

Add 128-bit atomic compare exchange on aarch64.

Suggested-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
---

v8:
Fixed "WARNING:LONG_LINE: line over 80 characters" warnings with latest kernel
checkpatch.pl

v7:
1. Adjust code comment.

v6:
1. Put the RTE_ARM_FEATURE_ATOMICS flag into EAL group. (Jerin Jocob)
2. Keep rte_stack_lf_stubs.h doing nothing. (Gage Eads)
3. Fixed 32 bit build issue.

v5:
1. Enable RTE_ARM_FEATURE_ATOMICS on octeontx2 in default. (Jerin Jocob)
2. Record the reason of introducing "rte_stack_lf_stubs.h" in git
commit.
(Jerin, Jocob)
3. Fixed a conditional MACRO error in rte_atomic128_cmp_exchange. (Jerin
Jocob)

v4:
1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions.
(Jerin Jocob)
2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin
Jocob)
3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage
Eads/Jerin Jocob)

v3:
1. Avoid duplication code with macro. (Jerin Jocob)
2. Make invalid memory order to strongest barrier. (Jerin Jocob)
3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
4. Fix 32-bit x86 builds issue. (Gage Eads)
5. Correct documentation issues in UT. (Gage Eads)

v2:
Initial version.

 config/arm/meson.build                        |   2 +
 config/common_base                            |   3 +
 config/defconfig_arm64-octeontx2-linuxapp-gcc |   1 +
 config/defconfig_arm64-thunderx2-linuxapp-gcc |   1 +
 .../common/include/arch/arm/rte_atomic_64.h   | 163 ++++++++++++++++++
 .../common/include/arch/x86/rte_atomic_64.h   |  12 --
 .../common/include/generic/rte_atomic.h       |  17 +-
 7 files changed, 186 insertions(+), 13 deletions(-)

diff --git a/config/arm/meson.build b/config/arm/meson.build
index 979018e16..9f2827140 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -71,11 +71,13 @@ flags_thunderx2_extra = [
 	['RTE_CACHE_LINE_SIZE', 64],
 	['RTE_MAX_NUMA_NODES', 2],
 	['RTE_MAX_LCORE', 256],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_USE_C11_MEM_MODEL', true]]
 flags_octeontx2_extra = [
 	['RTE_MACHINE', '"octeontx2"'],
 	['RTE_MAX_NUMA_NODES', 1],
 	['RTE_MAX_LCORE', 24],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_EAL_IGB_UIO', false],
 	['RTE_USE_C11_MEM_MODEL', true]]
 
diff --git a/config/common_base b/config/common_base
index 8ef75c203..205448013 100644
--- a/config/common_base
+++ b/config/common_base
@@ -82,6 +82,9 @@ CONFIG_RTE_MAX_LCORE=128
 CONFIG_RTE_MAX_NUMA_NODES=8
 CONFIG_RTE_MAX_HEAPS=32
 CONFIG_RTE_MAX_MEMSEG_LISTS=64
+
+# Use ARM LSE ATOMIC instructions
+CONFIG_RTE_ARM_FEATURE_ATOMICS=n
 # each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
 # or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
 CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
diff --git a/config/defconfig_arm64-octeontx2-linuxapp-gcc b/config/defconfig_arm64-octeontx2-linuxapp-gcc
index f20da2442..7687dbec8 100644
--- a/config/defconfig_arm64-octeontx2-linuxapp-gcc
+++ b/config/defconfig_arm64-octeontx2-linuxapp-gcc
@@ -9,6 +9,7 @@ CONFIG_RTE_MACHINE="octeontx2"
 CONFIG_RTE_CACHE_LINE_SIZE=128
 CONFIG_RTE_MAX_NUMA_NODES=1
 CONFIG_RTE_MAX_LCORE=24
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
 
 # Doesn't support NUMA
 CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
index cc5c64ba0..af4a89c48 100644
--- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
+++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
@@ -9,3 +9,4 @@ CONFIG_RTE_MACHINE="thunderx2"
 CONFIG_RTE_CACHE_LINE_SIZE=64
 CONFIG_RTE_MAX_NUMA_NODES=2
 CONFIG_RTE_MAX_LCORE=256
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 97060e444..14d869bc9 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2015 Cavium, Inc
+ * Copyright(c) 2019 Arm Limited
  */
 
 #ifndef _RTE_ATOMIC_ARM64_H_
@@ -14,6 +15,9 @@ extern "C" {
 #endif
 
 #include "generic/rte_atomic.h"
+#include <rte_branch_prediction.h>
+#include <rte_compat.h>
+#include <rte_debug.h>
 
 #define dsb(opt) asm volatile("dsb " #opt : : : "memory")
 #define dmb(opt) asm volatile("dmb " #opt : : : "memory")
@@ -40,6 +44,165 @@ extern "C" {
 
 #define rte_cio_rmb() dmb(oshld)
 
+/*------------------------ 128 bit atomic operations -------------------------*/
+
+#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
+#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
+					  (mo) == __ATOMIC_SEQ_CST)
+
+#define __MO_LOAD(mo)  (__HAS_ACQ((mo)) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED)
+#define __MO_STORE(mo) (__HAS_RLS((mo)) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
+static __rte_noinline rte_int128_t                                          \
+cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
+		rte_int128_t updated)                                       \
+{                                                                           \
+	/* caspX instructions register pair must start from even-numbered
+	 * register at operand 1.
+	 * So, specify registers for local variables here.
+	 */                                                                 \
+	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];            \
+	register uint64_t x1 __asm("x1") = (uint64_t)old.val[1];            \
+	register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0];        \
+	register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1];        \
+	asm volatile(                                                       \
+		op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]"   \
+		: [old0] "+r" (x0),                                         \
+		[old1] "+r" (x1)                                            \
+		: [upd0] "r" (x2),                                          \
+		[upd1] "r" (x3),                                            \
+		[dst] "r" (dst)                                             \
+		: "memory");                                                \
+	old.val[0] = x0;                                                    \
+	old.val[1] = x1;                                                    \
+	return old;                                                         \
+}
+
+__ATOMIC128_CAS_OP(__rte_cas_relaxed, "casp")
+__ATOMIC128_CAS_OP(__rte_cas_acquire, "caspa")
+__ATOMIC128_CAS_OP(__rte_cas_release, "caspl")
+__ATOMIC128_CAS_OP(__rte_cas_acq_rel, "caspal")
+#else
+#define __ATOMIC128_LDX_OP(ldx_op_name, op_string)                          \
+static inline rte_int128_t                                                  \
+ldx_op_name(const rte_int128_t *src)                                        \
+{                                                                           \
+	rte_int128_t ret;                                                   \
+	asm volatile(                                                       \
+			op_string " %0, %1, %2"                             \
+			: "=&r" (ret.val[0]),                               \
+			  "=&r" (ret.val[1])                                \
+			: "Q" (src->val[0])                                 \
+			: "memory");                                        \
+	return ret;                                                         \
+}
+
+__ATOMIC128_LDX_OP(__rte_ldx_relaxed, "ldxp")
+__ATOMIC128_LDX_OP(__rte_ldx_acquire, "ldaxp")
+
+#define __ATOMIC128_STX_OP(stx_op_name, op_string)                          \
+static inline uint32_t                                                      \
+stx_op_name(rte_int128_t *dst, const rte_int128_t src)                      \
+{                                                                           \
+	uint32_t ret;                                                       \
+	asm volatile(                                                       \
+			op_string " %w0, %1, %2, %3"                        \
+			: "=&r" (ret)                                       \
+			: "r" (src.val[0]),                                 \
+			  "r" (src.val[1]),                                 \
+			  "Q" (dst->val[0])                                 \
+			: "memory");                                        \
+	/* Return 0 on success, 1 on failure */                             \
+	return ret;                                                         \
+}
+
+__ATOMIC128_STX_OP(__rte_stx_relaxed, "stxp")
+__ATOMIC128_STX_OP(__rte_stx_release, "stlxp")
+#endif
+
+static inline int __rte_experimental
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+				rte_int128_t *exp,
+				const rte_int128_t *src,
+				unsigned int weak,
+				int success,
+				int failure)
+{
+	/* Always do strong CAS */
+	RTE_SET_USED(weak);
+	/* Ignore memory ordering for failure, memory order for
+	 * success must be stronger or equal
+	 */
+	RTE_SET_USED(failure);
+	/* Find invalid memory order */
+	RTE_ASSERT(success == __ATOMIC_RELAXED
+			|| success == __ATOMIC_ACQUIRE
+			|| success == __ATOMIC_RELEASE
+			|| success == __ATOMIC_ACQ_REL
+			|| success == __ATOMIC_SEQ_CST);
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+	rte_int128_t expected = *exp;
+	rte_int128_t desired = *src;
+	rte_int128_t old;
+
+	if (success == __ATOMIC_RELAXED)
+		old = __rte_cas_relaxed(dst, expected, desired);
+	else if (success == __ATOMIC_ACQUIRE)
+		old = __rte_cas_acquire(dst, expected, desired);
+	else if (success == __ATOMIC_RELEASE)
+		old = __rte_cas_release(dst, expected, desired);
+	else
+		old = __rte_cas_acq_rel(dst, expected, desired);
+#else
+	int ldx_mo = __MO_LOAD(success);
+	int stx_mo = __MO_STORE(success);
+	uint32_t ret = 1;
+	register rte_int128_t expected = *exp;
+	register rte_int128_t desired = *src;
+	register rte_int128_t old;
+
+	/* ldx128 can not guarantee atomic,
+	 * Must write back src or old to verify atomicity of ldx128;
+	 */
+	do {
+		if (ldx_mo == __ATOMIC_RELAXED)
+			old = __rte_ldx_relaxed(dst);
+		else
+			old = __rte_ldx_acquire(dst);
+
+		if (likely(old.int128 == expected.int128)) {
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, desired);
+			else
+				ret = __rte_stx_release(dst, desired);
+		} else {
+			/* In the failure case (since 'weak' is ignored and only
+			 * weak == 0 is implemented), expected should contain
+			 * the atomically read value of dst. This means, 'old'
+			 * needs to be stored back to ensure it was read
+			 * atomically.
+			 */
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, old);
+			else
+				ret = __rte_stx_release(dst, old);
+		}
+	} while (unlikely(ret));
+#endif
+
+	/* Unconditionally updating expected removes
+	 * an 'if' statement.
+	 * expected should already be in register if
+	 * not in the cache.
+	 */
+	*exp = old;
+
+	return (old.int128 == expected.int128);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index e087c6c32..12171296b 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -212,18 +212,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
-/**
- * 128-bit integer structure.
- */
-RTE_STD_C11
-typedef struct {
-	RTE_STD_C11
-	union {
-		uint64_t val[2];
-		__extension__ __int128 int128;
-	};
-} __rte_aligned(16) rte_int128_t;
-
 __rte_experimental
 static inline int
 rte_atomic128_cmp_exchange(rte_int128_t *dst,
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 24ff7dcae..e6ab15a97 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
+/**
+ * 128-bit integer structure.
+ */
+RTE_STD_C11
+typedef struct {
+	RTE_STD_C11
+	union {
+		uint64_t val[2];
+#ifdef RTE_ARCH_64
+		__extension__ __int128 int128;
+#endif
+	};
+} __rte_aligned(16) rte_int128_t;
+
 #ifdef __DOXYGEN__
 
 /**
@@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
  *     *exp = *dst
  * @endcode
  *
- * @note This function is currently only available for the x86-64 platform.
+ * @note This function is currently available for the x86-64 and aarch64
+ * platforms.
  *
  * @note The success and failure arguments must be one of the __ATOMIC_* values
  * defined in the C++11 standard. For details on their behavior, refer to the
-- 
2.22.0


^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v7 1/3] eal/arm64: add 128-bit atomic compare exchange
                     ` (3 preceding siblings ...)
  2019-07-22 16:22  2% ` [dpdk-dev] [PATCH v6 " Phil Yang
@ 2019-07-23  5:57  2% ` Phil Yang
  2019-07-23  7:05  2%   ` [dpdk-dev] [PATCH v8 " jerinj
  4 siblings, 1 reply; 200+ results
From: Phil Yang @ 2019-07-23  5:57 UTC (permalink / raw)
  To: dev
  Cc: thomas, jerinj, gage.eads, hemant.agrawal, Honnappa.Nagarahalli,
	gavin.hu, nd

Add 128-bit atomic compare exchange on aarch64.

Suggested-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>

---
v7:
1. Adjust code comment.

v6:
1. Put the RTE_ARM_FEATURE_ATOMICS flag into EAL group. (Jerin Jocob)
2. Keep rte_stack_lf_stubs.h doing nothing. (Gage Eads)
3. Fixed 32 bit build issue.

v5:
1. Enable RTE_ARM_FEATURE_ATOMICS on octeontx2 in default. (Jerin Jocob)
2. Record the reason of introducing "rte_stack_lf_stubs.h" in git commit.
(Jerin, Jocob)
3. Fixed a conditional MACRO error in rte_atomic128_cmp_exchange. (Jerin
Jocob)

v4:
1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions. (Jerin Jocob)
2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin Jocob)
3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage Eads/Jerin Jocob)

v3:
1. Avoid duplication code with macro. (Jerin Jocob)
2. Make invalid memory order to strongest barrier. (Jerin Jocob)
3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
4. Fix 32-bit x86 builds issue. (Gage Eads)
5. Correct documentation issues in UT. (Gage Eads)

v2:
Initial version.

 config/arm/meson.build                             |   2 +
 config/common_base                                 |   3 +
 config/defconfig_arm64-octeontx2-linuxapp-gcc      |   1 +
 config/defconfig_arm64-thunderx2-linuxapp-gcc      |   1 +
 .../common/include/arch/arm/rte_atomic_64.h        | 162 +++++++++++++++++++++
 .../common/include/arch/x86/rte_atomic_64.h        |  12 --
 lib/librte_eal/common/include/generic/rte_atomic.h |  17 ++-
 7 files changed, 185 insertions(+), 13 deletions(-)

diff --git a/config/arm/meson.build b/config/arm/meson.build
index 979018e..9f28271 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -71,11 +71,13 @@ flags_thunderx2_extra = [
 	['RTE_CACHE_LINE_SIZE', 64],
 	['RTE_MAX_NUMA_NODES', 2],
 	['RTE_MAX_LCORE', 256],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_USE_C11_MEM_MODEL', true]]
 flags_octeontx2_extra = [
 	['RTE_MACHINE', '"octeontx2"'],
 	['RTE_MAX_NUMA_NODES', 1],
 	['RTE_MAX_LCORE', 24],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_EAL_IGB_UIO', false],
 	['RTE_USE_C11_MEM_MODEL', true]]
 
diff --git a/config/common_base b/config/common_base
index 8ef75c2..2054480 100644
--- a/config/common_base
+++ b/config/common_base
@@ -82,6 +82,9 @@ CONFIG_RTE_MAX_LCORE=128
 CONFIG_RTE_MAX_NUMA_NODES=8
 CONFIG_RTE_MAX_HEAPS=32
 CONFIG_RTE_MAX_MEMSEG_LISTS=64
+
+# Use ARM LSE ATOMIC instructions
+CONFIG_RTE_ARM_FEATURE_ATOMICS=n
 # each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
 # or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
 CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
diff --git a/config/defconfig_arm64-octeontx2-linuxapp-gcc b/config/defconfig_arm64-octeontx2-linuxapp-gcc
index f20da24..7687dbe 100644
--- a/config/defconfig_arm64-octeontx2-linuxapp-gcc
+++ b/config/defconfig_arm64-octeontx2-linuxapp-gcc
@@ -9,6 +9,7 @@ CONFIG_RTE_MACHINE="octeontx2"
 CONFIG_RTE_CACHE_LINE_SIZE=128
 CONFIG_RTE_MAX_NUMA_NODES=1
 CONFIG_RTE_MAX_LCORE=24
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
 
 # Doesn't support NUMA
 CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
index cc5c64b..af4a89c 100644
--- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
+++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
@@ -9,3 +9,4 @@ CONFIG_RTE_MACHINE="thunderx2"
 CONFIG_RTE_CACHE_LINE_SIZE=64
 CONFIG_RTE_MAX_NUMA_NODES=2
 CONFIG_RTE_MAX_LCORE=256
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 97060e4..a040d69 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2015 Cavium, Inc
+ * Copyright(c) 2019 Arm Limited
  */
 
 #ifndef _RTE_ATOMIC_ARM64_H_
@@ -14,6 +15,9 @@ extern "C" {
 #endif
 
 #include "generic/rte_atomic.h"
+#include <rte_branch_prediction.h>
+#include <rte_compat.h>
+#include <rte_debug.h>
 
 #define dsb(opt) asm volatile("dsb " #opt : : : "memory")
 #define dmb(opt) asm volatile("dmb " #opt : : : "memory")
@@ -40,6 +44,164 @@ extern "C" {
 
 #define rte_cio_rmb() dmb(oshld)
 
+/*------------------------ 128 bit atomic operations -------------------------*/
+
+#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
+#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
+					  (mo) == __ATOMIC_SEQ_CST)
+
+#define __MO_LOAD(mo)  (__HAS_ACQ((mo)) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED)
+#define __MO_STORE(mo) (__HAS_RLS((mo)) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
+static __rte_noinline rte_int128_t                                          \
+cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
+		rte_int128_t updated)                                               \
+{                                                                           \
+	/* caspX instructions register pair must start from even-numbered
+	 * register at operand 1.
+	 * So, specify registers for local variables here.
+	 */                                                                     \
+	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];                \
+	register uint64_t x1 __asm("x1") = (uint64_t)old.val[1];                \
+	register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0];            \
+	register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1];            \
+	asm volatile(                                                           \
+			op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]"       \
+			: [old0] "+r" (x0),                                             \
+			  [old1] "+r" (x1)                                              \
+			: [upd0] "r" (x2),                                              \
+			  [upd1] "r" (x3),                                              \
+			  [dst] "r" (dst)                                               \
+			: "memory");                                                    \
+	old.val[0] = x0;                                                        \
+	old.val[1] = x1;                                                        \
+	return old;                                                             \
+}
+
+__ATOMIC128_CAS_OP(__rte_cas_relaxed, "casp")
+__ATOMIC128_CAS_OP(__rte_cas_acquire, "caspa")
+__ATOMIC128_CAS_OP(__rte_cas_release, "caspl")
+__ATOMIC128_CAS_OP(__rte_cas_acq_rel, "caspal")
+#else
+#define __ATOMIC128_LDX_OP(ldx_op_name, op_string)                          \
+static inline rte_int128_t                                                  \
+ldx_op_name(const rte_int128_t *src)                                        \
+{                                                                           \
+	rte_int128_t ret;                                                       \
+	asm volatile(                                                           \
+			op_string " %0, %1, %2"                                         \
+			: "=&r" (ret.val[0]),                                           \
+			  "=&r" (ret.val[1])                                            \
+			: "Q" (src->val[0])                                             \
+			: "memory");                                                    \
+	return ret;                                                             \
+}
+
+__ATOMIC128_LDX_OP(__rte_ldx_relaxed, "ldxp")
+__ATOMIC128_LDX_OP(__rte_ldx_acquire, "ldaxp")
+
+#define __ATOMIC128_STX_OP(stx_op_name, op_string)                          \
+static inline uint32_t                                                      \
+stx_op_name(rte_int128_t *dst, const rte_int128_t src)                      \
+{                                                                           \
+	uint32_t ret;                                                           \
+	asm volatile(                                                           \
+			op_string " %w0, %1, %2, %3"                                    \
+			: "=&r" (ret)                                                   \
+			: "r" (src.val[0]),                                             \
+			  "r" (src.val[1]),                                             \
+			  "Q" (dst->val[0])                                             \
+			: "memory");                                                    \
+	/* Return 0 on success, 1 on failure */                                 \
+	return ret;                                                             \
+}
+
+__ATOMIC128_STX_OP(__rte_stx_relaxed, "stxp")
+__ATOMIC128_STX_OP(__rte_stx_release, "stlxp")
+#endif
+
+static inline int __rte_experimental
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+				rte_int128_t *exp,
+				const rte_int128_t *src,
+				unsigned int weak,
+				int success,
+				int failure)
+{
+	/* Always do strong CAS */
+	RTE_SET_USED(weak);
+	/* Ignore memory ordering for failure, memory order for
+	 * success must be stronger or equal
+	 */
+	RTE_SET_USED(failure);
+	/* Find invalid memory order */
+	RTE_ASSERT(success == __ATOMIC_RELAXED
+			|| success == __ATOMIC_ACQUIRE
+			|| success == __ATOMIC_RELEASE
+			|| success == __ATOMIC_ACQ_REL
+			|| success == __ATOMIC_SEQ_CST);
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+	rte_int128_t expected = *exp;
+	rte_int128_t desired = *src;
+	rte_int128_t old;
+
+	if (success == __ATOMIC_RELAXED)
+		old = __rte_cas_relaxed(dst, expected, desired);
+	else if (success == __ATOMIC_ACQUIRE)
+		old = __rte_cas_acquire(dst, expected, desired);
+	else if (success == __ATOMIC_RELEASE)
+		old = __rte_cas_release(dst, expected, desired);
+	else
+		old = __rte_cas_acq_rel(dst, expected, desired);
+#else
+	int ldx_mo = __MO_LOAD(success);
+	int stx_mo = __MO_STORE(success);
+	uint32_t ret = 1;
+	register rte_int128_t expected = *exp;
+	register rte_int128_t desired = *src;
+	register rte_int128_t old;
+
+	/* ldx128 can not guarantee atomic,
+	 * Must write back src or old to verify atomicity of ldx128;
+	 */
+	do {
+		if (ldx_mo == __ATOMIC_RELAXED)
+			old = __rte_ldx_relaxed(dst);
+		else
+			old = __rte_ldx_acquire(dst);
+
+		if (likely(old.int128 == expected.int128)) {
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, desired);
+			else
+				ret = __rte_stx_release(dst, desired);
+		} else {
+			/* In the failure case (since 'weak' is ignored and only
+			 * weak == 0 is implemented), expected should contain the
+			 * atomically read value of dst. This means, 'old' needs
+			 * to be stored back to ensure it was read atomically.
+			 */
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, old);
+			else
+				ret = __rte_stx_release(dst, old);
+		}
+	} while (unlikely(ret));
+#endif
+
+	/* Unconditionally updating expected removes
+	 * an 'if' statement.
+	 * expected should already be in register if
+	 * not in the cache.
+	 */
+	*exp = old;
+
+	return (old.int128 == expected.int128);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index e087c6c..1217129 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -212,18 +212,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
-/**
- * 128-bit integer structure.
- */
-RTE_STD_C11
-typedef struct {
-	RTE_STD_C11
-	union {
-		uint64_t val[2];
-		__extension__ __int128 int128;
-	};
-} __rte_aligned(16) rte_int128_t;
-
 __rte_experimental
 static inline int
 rte_atomic128_cmp_exchange(rte_int128_t *dst,
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 24ff7dc..e6ab15a 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
+/**
+ * 128-bit integer structure.
+ */
+RTE_STD_C11
+typedef struct {
+	RTE_STD_C11
+	union {
+		uint64_t val[2];
+#ifdef RTE_ARCH_64
+		__extension__ __int128 int128;
+#endif
+	};
+} __rte_aligned(16) rte_int128_t;
+
 #ifdef __DOXYGEN__
 
 /**
@@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
  *     *exp = *dst
  * @endcode
  *
- * @note This function is currently only available for the x86-64 platform.
+ * @note This function is currently available for the x86-64 and aarch64
+ * platforms.
  *
  * @note The success and failure arguments must be one of the __ATOMIC_* values
  * defined in the C++11 standard. For details on their behavior, refer to the
-- 
2.7.4


^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v8 3/5] kni: add app specific mempool create & free routine
  @ 2019-07-23  5:38  3%   ` vattunuru
  2019-07-23 10:50  0%     ` Andrew Rybchenko
    1 sibling, 1 reply; 200+ results
From: vattunuru @ 2019-07-23  5:38 UTC (permalink / raw)
  To: dev
  Cc: thomas, jerinj, olivier.matz, ferruh.yigit, anatoly.burakov,
	arybchenko, kirankumark, Vamsi Attunuru

From: Vamsi Attunuru <vattunuru@marvell.com>

When KNI operates in IOVA = VA mode, it requires mbuf memory
to be physically contiguous to ensure KNI kernel module could
translate IOVA addresses properly. Patch adds a KNI specific
mempool create routine to populate the KNI packet mbuf pool
with memory objects that are being on a page.

KNI applications need to use this mempool create & free routines
so that mbuf related requirements in IOVA = VA mode are handled
inside those routines based on the enabled mode.

Updated the release notes with these new routine details.

Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
---
 doc/guides/rel_notes/release_19_08.rst |  6 ++++
 examples/kni/main.c                    |  6 +++-
 lib/librte_kni/Makefile                |  1 +
 lib/librte_kni/meson.build             |  1 +
 lib/librte_kni/rte_kni.c               | 59 ++++++++++++++++++++++++++++++++++
 lib/librte_kni/rte_kni.h               | 49 ++++++++++++++++++++++++++++
 lib/librte_kni/rte_kni_version.map     |  2 ++
 7 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 0a3f840..bd01e99 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -281,6 +281,12 @@ API Changes
   offload flag from the library. The application must set this flag if it is
   supported by the platform and application wishes to use it.
 
+* kni: ``rte_kni_pktmbuf_pool_create`` ``rte_kni_pktmbuf_pool_free`` functions
+  were introduced for KNI applications for creating & freeing packet pool.
+  Since IOVA=VA mode was added in KNI, packet pool's mbuf memory should be
+  physically contiguous for the KNI kernel module to work in IOVA=VA mode,
+  this requirment was taken care in the kni packet pool creation fucntions.
+
 
 ABI Changes
 -----------
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 4710d71..3b9c067 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -975,7 +975,7 @@ main(int argc, char** argv)
 		rte_exit(EXIT_FAILURE, "Could not parse input parameters\n");
 
 	/* Create the mbuf pool */
-	pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
+	pktmbuf_pool = rte_kni_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
 		MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
 	if (pktmbuf_pool == NULL) {
 		rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool\n");
@@ -1043,6 +1043,10 @@ main(int argc, char** argv)
 			continue;
 		kni_free_kni(port);
 	}
+
+	if (pktmbuf_pool)
+		rte_kni_pktmbuf_pool_free(pktmbuf_pool);
+
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
 		if (kni_port_params_array[i]) {
 			rte_free(kni_port_params_array[i]);
diff --git a/lib/librte_kni/Makefile b/lib/librte_kni/Makefile
index ab15d10..5e3dd01 100644
--- a/lib/librte_kni/Makefile
+++ b/lib/librte_kni/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 # library name
 LIB = librte_kni.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing
 CFLAGS += -I$(RTE_SDK)/drivers/bus/pci
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev
diff --git a/lib/librte_kni/meson.build b/lib/librte_kni/meson.build
index fd46f87..e357445 100644
--- a/lib/librte_kni/meson.build
+++ b/lib/librte_kni/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 if not is_linux or not dpdk_conf.get('RTE_ARCH_64')
 	build = false
 	reason = 'only supported on 64-bit linux'
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index ae17075..897a5bb 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -687,6 +687,65 @@ kni_allocate_mbufs(struct rte_kni *kni)
 	}
 }
 
+struct rte_mempool *
+rte_kni_pktmbuf_pool_create(const char *name, unsigned int n,
+	unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
+	int socket_id)
+{
+	struct rte_pktmbuf_pool_private mbp_priv;
+	const char *mp_ops_name;
+	struct rte_mempool *mp;
+	unsigned int elt_size;
+	int ret;
+
+	if (RTE_ALIGN(priv_size, RTE_MBUF_PRIV_ALIGN) != priv_size) {
+		RTE_LOG(ERR, MBUF, "mbuf priv_size=%u is not aligned\n",
+			priv_size);
+		rte_errno = EINVAL;
+		return NULL;
+	}
+	elt_size = sizeof(struct rte_mbuf) + (unsigned int)priv_size +
+		(unsigned int)data_room_size;
+	mbp_priv.mbuf_data_room_size = data_room_size;
+	mbp_priv.mbuf_priv_size = priv_size;
+
+	mp = rte_mempool_create_empty(name, n, elt_size, cache_size,
+		 sizeof(struct rte_pktmbuf_pool_private), socket_id, 0);
+	if (mp == NULL)
+		return NULL;
+
+	mp_ops_name = rte_mbuf_best_mempool_ops();
+	ret = rte_mempool_set_ops_byname(mp, mp_ops_name, NULL);
+	if (ret != 0) {
+		RTE_LOG(ERR, MBUF, "error setting mempool handler\n");
+		rte_mempool_free(mp);
+		rte_errno = -ret;
+		return NULL;
+	}
+	rte_pktmbuf_pool_init(mp, &mbp_priv);
+
+	if (rte_eal_iova_mode() == RTE_IOVA_VA)
+		ret = rte_mempool_populate_from_pg_sz_chunks(mp);
+	else
+		ret = rte_mempool_populate_default(mp);
+
+	if (ret < 0) {
+		rte_mempool_free(mp);
+		rte_errno = -ret;
+		return NULL;
+	}
+
+	rte_mempool_obj_iter(mp, rte_pktmbuf_init, NULL);
+
+	return mp;
+}
+
+void
+rte_kni_pktmbuf_pool_free(struct rte_mempool *mp)
+{
+	rte_mempool_free(mp);
+}
+
 struct rte_kni *
 rte_kni_get(const char *name)
 {
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 5699a64..7f11927 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -20,6 +20,7 @@
 #include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_mempool.h>
+#include <rte_mbuf_pool_ops.h>
 #include <rte_ether.h>
 
 #include <rte_kni_common.h>
@@ -184,6 +185,54 @@ unsigned rte_kni_tx_burst(struct rte_kni *kni, struct rte_mbuf **mbufs,
 		unsigned num);
 
 /**
+ * Create a kni packet mbuf pool.
+ *
+ * This function creates and initializes a packet mbuf pool for KNI applications
+ * It calls the required mempool populate routine based on the IOVA mode.
+ *
+ * @param name
+ *   The name of the mbuf pool.
+ * @param n
+ *   The number of elements in the mbuf pool. The optimum size (in terms
+ *   of memory usage) for a mempool is when n is a power of two minus one:
+ *   n = (2^q - 1).
+ * @param cache_size
+ *   Size of the per-core object cache. See rte_mempool_create() for
+ *   details.
+ * @param priv_size
+ *   Size of application private are between the rte_mbuf structure
+ *   and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
+ * @param data_room_size
+ *   Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
+ * @param socket_id
+ *   The socket identifier where the memory should be allocated. The
+ *   value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
+ *   reserved zone.
+ * @return
+ *   The pointer to the new allocated mempool, on success. NULL on error
+ *   with rte_errno set appropriately. Possible rte_errno values include:
+ *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ *    - E_RTE_SECONDARY - function was called from a secondary process instance
+ *    - EINVAL - cache size provided is too large, or priv_size is not aligned.
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a memzone with the same name already exists
+ *    - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+__rte_experimental
+struct rte_mempool *rte_kni_pktmbuf_pool_create(const char *name,
+		unsigned int n, unsigned int cache_size, uint16_t priv_size,
+		uint16_t data_room_size, int socket_id);
+
+/**
+ * Free the given packet mempool.
+ *
+ * @param mp
+ *  The mempool pointer.
+ */
+__rte_experimental
+void rte_kni_pktmbuf_pool_free(struct rte_mempool *mp);
+
+/**
  * Get the KNI context of its name.
  *
  * @param name
diff --git a/lib/librte_kni/rte_kni_version.map b/lib/librte_kni/rte_kni_version.map
index c877dc6..aba9728 100644
--- a/lib/librte_kni/rte_kni_version.map
+++ b/lib/librte_kni/rte_kni_version.map
@@ -20,4 +20,6 @@ EXPERIMENTAL {
 	global:
 
 	rte_kni_update_link;
+	rte_kni_pktmbuf_pool_create;
+	rte_kni_pktmbuf_pool_free;
 };
-- 
2.8.4


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] app/testpmd: support QinQ strip offload
  2019-07-22 17:03  0%           ` Iremonger, Bernard
@ 2019-07-22 17:16  0%             ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-07-22 17:16 UTC (permalink / raw)
  To: Iremonger, Bernard, viveksharma, dev; +Cc: intoviveksharma

On 7/22/2019 6:03 PM, Iremonger, Bernard wrote:
> Hi Ferruh,
> 
> <snip>
> 
>>>>>> Subject: Re: [dpdk-dev] [PATCH] app/testpmd: support QinQ strip
>>>>>> offload
>>>>>>
>>>>>> On 7/17/2019 8:45 AM, viveksharma@marvell.com wrote:
>>>>>>> From: Vivek Sharma <viveksharma@marvell.com>
>>>>>>>
>>>>>>> Support QinQ strip RX offload configuration through testpmd
>>>>>>> command line and boot time arguments.
>>>>>>
>>>>>> For the testpmd command part, unfortunately there are two set of
>>>>>> commands for same purpose, the new ones are (lets both port and
>>>> queue
>>>>>> level):
>>>>>> "port config <port_id> rx_offload ..."
>>>>>> "port (port_id) rxq (queue_id) rx_offload ..."
>>>>>> "port config (port_id) tx_offload ..."
>>>>>> "port (port_id) txq (queue_id) tx_offload ..."
>>>>>>
>>>>>> These are better implementation comparing the old one:
>>>>>> "port config all ..."
>>>>>>
>>>>>> Would you mind sending a patch to remove "port config all ..."
>>>>>> variant of setting offloads?
>>>>>> And you can make your changes to the new commands above.
>>>>>
>>>>> Is it ok to remove "port config all ..." commands as they may be in
>>>>> use by
>>>> the community?
>>>>
>>>> Since there is a command that replaces the removed functionality I
>>>> think it is OK.
>>>>
>>>> Also I am not sure what level of backward compatibility we should
>>>> provide for testpmd commands.
>>>
>>> It might be better to leave "port config all ..." commands  as they are for
>> now and provide a separate patchset for the new style port setting offloads
>> commands.
>>>
>>> If they are to be removed there should at least  be something to announce
>> this in the release notes.  There is a deprecation process which is used for the
>> rest of the code, why not follow that process.
>>
>> Deprecation process is for ABI/API changes.
>>
>> I can see testpmd commands also a kind of user interface, but this is a test
>> application at the end, deprecation process can be overkill here.
>> Although +1 to be cautious on command consistency and keep some level of
>> stability on them.
> 
>>>>>> For the application argument, ``--enable-hw-vlan-extend``, instead
>>>>>> of adding a parameter of each offload argument, (and event it is
>>>>>> not clear if it is only for Rx or Tx), have a "--rx-offloads"
>>>>>> argument and feed
>>>> the list via this, like:
>>>>>> "--rx-ofloads=disable-crc-strip,enable-rx-timestamp"
>>>>>>
>>>>>>
>>>>>>
>>>>>> And lastly for the  "vlan set ..." update, I think "qinq" was
>>>>>> already defined but it was calling 'vlan_extend_set()', now you are
>>>>>> changing it and making it call 'rx_vlan_qinq_strip_set()', I think
>>>>>> this is OK, but can you please update the 'cmd_help_long_parsed()'
>> accordingly?
>>>>>
>>>>> 'vlan_extend_set()'  and 'rx_vlan_qinq_strip_set()'  are different
>>>> commands.
>>>>> vlan_extend_set()  is for adding the second vlan  and
>>>> rx_vlan_qinq_strip_set() is for removing the second vlan.
>>>>
>>>> yes they are different, I think nobody said they are same.
>>>> What is the concern here, can you please detail more?
>>>
>>> In the previous paragraph, you mentioned that "I think "qinq" was
>>> already defined but it was calling 'vlan_extend_set()', now you are
>>> changing  it and making it call 'rx_vlan_qinq_strip_set()' "
>>>
>>> vlan_extend_set() is not being changed, rx_vlan_qinq_strip_set() is being
>> added.
>>
>> Before this patch,
>> "vlan set qinq" calls 'vlan_extend_set()'
>>
>> After patch,
>> "vlan set qinq" calls 'rx_vlan_qinq_strip_set()'
> 
>> And again after this patch,
>> "vlan set extend" added and which calls 'vlan_extend_set()'
>>
>> so the patch looks like adding "vlan set extend" command, but practically it
>> does fix "vlan set qinq", I said "I think this is OK" and asked for help string &
>> documentation update accordingly.
>>
>> I hope it is clear now.
> 
> Yes, I see what you mean now (well spotted). 
> Previously the "qinq" keyword mapped to extend now it maps to qinq_strip. It would be better to leave the function of the "qinq" keyword as it was add a "qinqstrip" keyword instead of adding the "extend" keyword.
> 
>>>>>> And in original 'cmd_help_long_parsed()' for 'vlan set ...", it
>>>>>> doesn't need to have separate lines for "strip, filter & qinq", can
>>>>>> you please merge them, and later the 'extend' one?
>>>>>> Than change needs to be documented on "testpmd_funcs.rst"
>>>>>>
>>>>>>
>>>>>> And as a last thing, can you please send this as multiple patches:
>>>>>> 1) Command line change for setting qinq offload
>>>>>> 2) Application argument change
>>>>>> 3) "vlan set " related changes
>>>>>>
>>>>>>>
>>>>>>> Signed-off-by: Vivek Sharma <viveksharma@marvell.com>
>>>>>>
>>>>>
>>>>> Regards,
>>>>>
>>>>> Bernard
>>>>>
>>> In my opinion this patch was fine for the "port config all ..." style
>> commands.
>>
>> Duplication is bad, it is bad to have two different ways to do same thing.
>> I am not sure if Vivek is aware of duplicated functions but explicitly prefers to
>> update old versions.
>> I suggest lets stop improving these ones and get rid of them asap.
> 
> Testpmd is widely used so removing commands without notice will  probably not go down too well with the community.

We can make sure release notes is updated for removed commands and what is
replacing them, also can have same thing in the commit log, these can help user.

But I am dubious to follow deprecation process for testpmd commands.

>  
>> Also as you can see commit log doesn't mention from "vlan set ..." changes at
>> all, that is why I asked for splitting this into 3 patches for 3 separate thing it
>> does.
> 
> Ok,  it should describe the "vlan set ...." changes.
> 
>>> A separate patch set should be submitted for the new style setting offloads
>> commands.
>>>
>>> Regards,
>>>
>>> Bernard
>>>
> 
> Regards,
> 
> Bernard
> 


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] app/testpmd: support QinQ strip offload
  2019-07-22 15:40  3%         ` Ferruh Yigit
@ 2019-07-22 17:03  0%           ` Iremonger, Bernard
  2019-07-22 17:16  0%             ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Iremonger, Bernard @ 2019-07-22 17:03 UTC (permalink / raw)
  To: Yigit, Ferruh, viveksharma, dev; +Cc: intoviveksharma

Hi Ferruh,

<snip>

> >>>> Subject: Re: [dpdk-dev] [PATCH] app/testpmd: support QinQ strip
> >>>> offload
> >>>>
> >>>> On 7/17/2019 8:45 AM, viveksharma@marvell.com wrote:
> >>>>> From: Vivek Sharma <viveksharma@marvell.com>
> >>>>>
> >>>>> Support QinQ strip RX offload configuration through testpmd
> >>>>> command line and boot time arguments.
> >>>>
> >>>> For the testpmd command part, unfortunately there are two set of
> >>>> commands for same purpose, the new ones are (lets both port and
> >> queue
> >>>> level):
> >>>> "port config <port_id> rx_offload ..."
> >>>> "port (port_id) rxq (queue_id) rx_offload ..."
> >>>> "port config (port_id) tx_offload ..."
> >>>> "port (port_id) txq (queue_id) tx_offload ..."
> >>>>
> >>>> These are better implementation comparing the old one:
> >>>> "port config all ..."
> >>>>
> >>>> Would you mind sending a patch to remove "port config all ..."
> >>>> variant of setting offloads?
> >>>> And you can make your changes to the new commands above.
> >>>
> >>> Is it ok to remove "port config all ..." commands as they may be in
> >>> use by
> >> the community?
> >>
> >> Since there is a command that replaces the removed functionality I
> >> think it is OK.
> >>
> >> Also I am not sure what level of backward compatibility we should
> >> provide for testpmd commands.
> >
> > It might be better to leave "port config all ..." commands  as they are for
> now and provide a separate patchset for the new style port setting offloads
> commands.
> >
> > If they are to be removed there should at least  be something to announce
> this in the release notes.  There is a deprecation process which is used for the
> rest of the code, why not follow that process.
> 
> Deprecation process is for ABI/API changes.
> 
> I can see testpmd commands also a kind of user interface, but this is a test
> application at the end, deprecation process can be overkill here.
> Although +1 to be cautious on command consistency and keep some level of
> stability on them.

> >>>> For the application argument, ``--enable-hw-vlan-extend``, instead
> >>>> of adding a parameter of each offload argument, (and event it is
> >>>> not clear if it is only for Rx or Tx), have a "--rx-offloads"
> >>>> argument and feed
> >> the list via this, like:
> >>>> "--rx-ofloads=disable-crc-strip,enable-rx-timestamp"
> >>>>
> >>>>
> >>>>
> >>>> And lastly for the  "vlan set ..." update, I think "qinq" was
> >>>> already defined but it was calling 'vlan_extend_set()', now you are
> >>>> changing it and making it call 'rx_vlan_qinq_strip_set()', I think
> >>>> this is OK, but can you please update the 'cmd_help_long_parsed()'
> accordingly?
> >>>
> >>> 'vlan_extend_set()'  and 'rx_vlan_qinq_strip_set()'  are different
> >> commands.
> >>> vlan_extend_set()  is for adding the second vlan  and
> >> rx_vlan_qinq_strip_set() is for removing the second vlan.
> >>
> >> yes they are different, I think nobody said they are same.
> >> What is the concern here, can you please detail more?
> >
> > In the previous paragraph, you mentioned that "I think "qinq" was
> > already defined but it was calling 'vlan_extend_set()', now you are
> > changing  it and making it call 'rx_vlan_qinq_strip_set()' "
> >
> > vlan_extend_set() is not being changed, rx_vlan_qinq_strip_set() is being
> added.
> 
> Before this patch,
> "vlan set qinq" calls 'vlan_extend_set()'
> 
> After patch,
> "vlan set qinq" calls 'rx_vlan_qinq_strip_set()'

> And again after this patch,
> "vlan set extend" added and which calls 'vlan_extend_set()'
> 
> so the patch looks like adding "vlan set extend" command, but practically it
> does fix "vlan set qinq", I said "I think this is OK" and asked for help string &
> documentation update accordingly.
> 
> I hope it is clear now.

Yes, I see what you mean now (well spotted). 
Previously the "qinq" keyword mapped to extend now it maps to qinq_strip. It would be better to leave the function of the "qinq" keyword as it was add a "qinqstrip" keyword instead of adding the "extend" keyword.

> >>>> And in original 'cmd_help_long_parsed()' for 'vlan set ...", it
> >>>> doesn't need to have separate lines for "strip, filter & qinq", can
> >>>> you please merge them, and later the 'extend' one?
> >>>> Than change needs to be documented on "testpmd_funcs.rst"
> >>>>
> >>>>
> >>>> And as a last thing, can you please send this as multiple patches:
> >>>> 1) Command line change for setting qinq offload
> >>>> 2) Application argument change
> >>>> 3) "vlan set " related changes
> >>>>
> >>>>>
> >>>>> Signed-off-by: Vivek Sharma <viveksharma@marvell.com>
> >>>>
> >>>
> >>> Regards,
> >>>
> >>> Bernard
> >>>
> > In my opinion this patch was fine for the "port config all ..." style
> commands.
> 
> Duplication is bad, it is bad to have two different ways to do same thing.
> I am not sure if Vivek is aware of duplicated functions but explicitly prefers to
> update old versions.
> I suggest lets stop improving these ones and get rid of them asap.

Testpmd is widely used so removing commands without notice will  probably not go down too well with the community.
 
> Also as you can see commit log doesn't mention from "vlan set ..." changes at
> all, that is why I asked for splitting this into 3 patches for 3 separate thing it
> does.

Ok,  it should describe the "vlan set ...." changes.

> > A separate patch set should be submitted for the new style setting offloads
> commands.
> >
> > Regards,
> >
> > Bernard
> >

Regards,

Bernard

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v6 1/3] eal/arm64: add 128-bit atomic compare exchange
                     ` (2 preceding siblings ...)
  2019-07-22 13:06  2% ` [dpdk-dev] [PATCH v5 " Phil Yang
@ 2019-07-22 16:22  2% ` Phil Yang
  2019-07-23  5:57  2% ` [dpdk-dev] [PATCH v7 " Phil Yang
  4 siblings, 0 replies; 200+ results
From: Phil Yang @ 2019-07-22 16:22 UTC (permalink / raw)
  To: dev
  Cc: thomas, jerinj, gage.eads, hemant.agrawal, Honnappa.Nagarahalli,
	gavin.hu, nd

Add 128-bit atomic compare exchange on aarch64.

Suggested-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>

---
v6:
1. Put the RTE_ARM_FEATURE_ATOMICS flag into EAL group. (Jerin Jocob)
2. Keep rte_stack_lf_stubs.h doing nothing. (Gage Eads)
3. Fixed 32 bit build issue.

v5:
1. Enable RTE_ARM_FEATURE_ATOMICS on octeontx2 in default. (Jerin Jocob)
2. Record the reason of introducing "rte_stack_lf_stubs.h" in git commit.
(Jerin, Jocob)
3. Fixed a conditional MACRO error in rte_atomic128_cmp_exchange. (Jerin
Jocob)

v4:
1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions. (Jerin Jocob)
2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin Jocob)
3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage Eads/Jerin Jocob)

v3:
1. Avoid duplication code with macro. (Jerin Jocob)
2. Make invalid memory order to strongest barrier. (Jerin Jocob)
3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
4. Fix 32-bit x86 builds issue. (Gage Eads)
5. Correct documentation issues in UT. (Gage Eads)

v2:
Initial version.

 config/arm/meson.build                             |   2 +
 config/common_base                                 |   2 +
 config/defconfig_arm64-octeontx2-linuxapp-gcc      |   1 +
 config/defconfig_arm64-thunderx2-linuxapp-gcc      |   1 +
 .../common/include/arch/arm/rte_atomic_64.h        | 162 +++++++++++++++++++++
 .../common/include/arch/x86/rte_atomic_64.h        |  12 --
 lib/librte_eal/common/include/generic/rte_atomic.h |  17 ++-
 7 files changed, 184 insertions(+), 13 deletions(-)

diff --git a/config/arm/meson.build b/config/arm/meson.build
index 979018e..9f28271 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -71,11 +71,13 @@ flags_thunderx2_extra = [
 	['RTE_CACHE_LINE_SIZE', 64],
 	['RTE_MAX_NUMA_NODES', 2],
 	['RTE_MAX_LCORE', 256],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_USE_C11_MEM_MODEL', true]]
 flags_octeontx2_extra = [
 	['RTE_MACHINE', '"octeontx2"'],
 	['RTE_MAX_NUMA_NODES', 1],
 	['RTE_MAX_LCORE', 24],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_EAL_IGB_UIO', false],
 	['RTE_USE_C11_MEM_MODEL', true]]
 
diff --git a/config/common_base b/config/common_base
index 8ef75c2..de6d1e0 100644
--- a/config/common_base
+++ b/config/common_base
@@ -82,6 +82,8 @@ CONFIG_RTE_MAX_LCORE=128
 CONFIG_RTE_MAX_NUMA_NODES=8
 CONFIG_RTE_MAX_HEAPS=32
 CONFIG_RTE_MAX_MEMSEG_LISTS=64
+# Use LSE ATOMIC instructions
+CONFIG_RTE_ARM_FEATURE_ATOMICS=n
 # each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
 # or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
 CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
diff --git a/config/defconfig_arm64-octeontx2-linuxapp-gcc b/config/defconfig_arm64-octeontx2-linuxapp-gcc
index f20da24..7687dbe 100644
--- a/config/defconfig_arm64-octeontx2-linuxapp-gcc
+++ b/config/defconfig_arm64-octeontx2-linuxapp-gcc
@@ -9,6 +9,7 @@ CONFIG_RTE_MACHINE="octeontx2"
 CONFIG_RTE_CACHE_LINE_SIZE=128
 CONFIG_RTE_MAX_NUMA_NODES=1
 CONFIG_RTE_MAX_LCORE=24
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
 
 # Doesn't support NUMA
 CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
index cc5c64b..af4a89c 100644
--- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
+++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
@@ -9,3 +9,4 @@ CONFIG_RTE_MACHINE="thunderx2"
 CONFIG_RTE_CACHE_LINE_SIZE=64
 CONFIG_RTE_MAX_NUMA_NODES=2
 CONFIG_RTE_MAX_LCORE=256
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 97060e4..a040d69 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2015 Cavium, Inc
+ * Copyright(c) 2019 Arm Limited
  */
 
 #ifndef _RTE_ATOMIC_ARM64_H_
@@ -14,6 +15,9 @@ extern "C" {
 #endif
 
 #include "generic/rte_atomic.h"
+#include <rte_branch_prediction.h>
+#include <rte_compat.h>
+#include <rte_debug.h>
 
 #define dsb(opt) asm volatile("dsb " #opt : : : "memory")
 #define dmb(opt) asm volatile("dmb " #opt : : : "memory")
@@ -40,6 +44,164 @@ extern "C" {
 
 #define rte_cio_rmb() dmb(oshld)
 
+/*------------------------ 128 bit atomic operations -------------------------*/
+
+#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
+#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
+					  (mo) == __ATOMIC_SEQ_CST)
+
+#define __MO_LOAD(mo)  (__HAS_ACQ((mo)) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED)
+#define __MO_STORE(mo) (__HAS_RLS((mo)) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
+static __rte_noinline rte_int128_t                                          \
+cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
+		rte_int128_t updated)                                               \
+{                                                                           \
+	/* caspX instructions register pair must start from even-numbered
+	 * register at operand 1.
+	 * So, specify registers for local variables here.
+	 */                                                                     \
+	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];                \
+	register uint64_t x1 __asm("x1") = (uint64_t)old.val[1];                \
+	register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0];            \
+	register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1];            \
+	asm volatile(                                                           \
+			op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]"       \
+			: [old0] "+r" (x0),                                             \
+			  [old1] "+r" (x1)                                              \
+			: [upd0] "r" (x2),                                              \
+			  [upd1] "r" (x3),                                              \
+			  [dst] "r" (dst)                                               \
+			: "memory");                                                    \
+	old.val[0] = x0;                                                        \
+	old.val[1] = x1;                                                        \
+	return old;                                                             \
+}
+
+__ATOMIC128_CAS_OP(__rte_cas_relaxed, "casp")
+__ATOMIC128_CAS_OP(__rte_cas_acquire, "caspa")
+__ATOMIC128_CAS_OP(__rte_cas_release, "caspl")
+__ATOMIC128_CAS_OP(__rte_cas_acq_rel, "caspal")
+#else
+#define __ATOMIC128_LDX_OP(ldx_op_name, op_string)                          \
+static inline rte_int128_t                                                  \
+ldx_op_name(const rte_int128_t *src)                                        \
+{                                                                           \
+	rte_int128_t ret;                                                       \
+	asm volatile(                                                           \
+			op_string " %0, %1, %2"                                         \
+			: "=&r" (ret.val[0]),                                           \
+			  "=&r" (ret.val[1])                                            \
+			: "Q" (src->val[0])                                             \
+			: "memory");                                                    \
+	return ret;                                                             \
+}
+
+__ATOMIC128_LDX_OP(__rte_ldx_relaxed, "ldxp")
+__ATOMIC128_LDX_OP(__rte_ldx_acquire, "ldaxp")
+
+#define __ATOMIC128_STX_OP(stx_op_name, op_string)                          \
+static inline uint32_t                                                      \
+stx_op_name(rte_int128_t *dst, const rte_int128_t src)                      \
+{                                                                           \
+	uint32_t ret;                                                           \
+	asm volatile(                                                           \
+			op_string " %w0, %1, %2, %3"                                    \
+			: "=&r" (ret)                                                   \
+			: "r" (src.val[0]),                                             \
+			  "r" (src.val[1]),                                             \
+			  "Q" (dst->val[0])                                             \
+			: "memory");                                                    \
+	/* Return 0 on success, 1 on failure */                                 \
+	return ret;                                                             \
+}
+
+__ATOMIC128_STX_OP(__rte_stx_relaxed, "stxp")
+__ATOMIC128_STX_OP(__rte_stx_release, "stlxp")
+#endif
+
+static inline int __rte_experimental
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+				rte_int128_t *exp,
+				const rte_int128_t *src,
+				unsigned int weak,
+				int success,
+				int failure)
+{
+	/* Always do strong CAS */
+	RTE_SET_USED(weak);
+	/* Ignore memory ordering for failure, memory order for
+	 * success must be stronger or equal
+	 */
+	RTE_SET_USED(failure);
+	/* Find invalid memory order */
+	RTE_ASSERT(success == __ATOMIC_RELAXED
+			|| success == __ATOMIC_ACQUIRE
+			|| success == __ATOMIC_RELEASE
+			|| success == __ATOMIC_ACQ_REL
+			|| success == __ATOMIC_SEQ_CST);
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+	rte_int128_t expected = *exp;
+	rte_int128_t desired = *src;
+	rte_int128_t old;
+
+	if (success == __ATOMIC_RELAXED)
+		old = __rte_cas_relaxed(dst, expected, desired);
+	else if (success == __ATOMIC_ACQUIRE)
+		old = __rte_cas_acquire(dst, expected, desired);
+	else if (success == __ATOMIC_RELEASE)
+		old = __rte_cas_release(dst, expected, desired);
+	else
+		old = __rte_cas_acq_rel(dst, expected, desired);
+#else
+	int ldx_mo = __MO_LOAD(success);
+	int stx_mo = __MO_STORE(success);
+	uint32_t ret = 1;
+	register rte_int128_t expected = *exp;
+	register rte_int128_t desired = *src;
+	register rte_int128_t old;
+
+	/* ldx128 can not guarantee atomic,
+	 * Must write back src or old to verify atomicity of ldx128;
+	 */
+	do {
+		if (ldx_mo == __ATOMIC_RELAXED)
+			old = __rte_ldx_relaxed(dst);
+		else
+			old = __rte_ldx_acquire(dst);
+
+		if (likely(old.int128 == expected.int128)) {
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, desired);
+			else
+				ret = __rte_stx_release(dst, desired);
+		} else {
+			/* In the failure case (since 'weak' is ignored and only
+			 * weak == 0 is implemented), expected should contain the
+			 * atomically read value of dst. This means, 'old' needs
+			 * to be stored back to ensure it was read atomically.
+			 */
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, old);
+			else
+				ret = __rte_stx_release(dst, old);
+		}
+	} while (unlikely(ret));
+#endif
+
+	/* Unconditionally updating expected removes
+	 * an 'if' statement.
+	 * expected should already be in register if
+	 * not in the cache.
+	 */
+	*exp = old;
+
+	return (old.int128 == expected.int128);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index e087c6c..1217129 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -212,18 +212,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
-/**
- * 128-bit integer structure.
- */
-RTE_STD_C11
-typedef struct {
-	RTE_STD_C11
-	union {
-		uint64_t val[2];
-		__extension__ __int128 int128;
-	};
-} __rte_aligned(16) rte_int128_t;
-
 __rte_experimental
 static inline int
 rte_atomic128_cmp_exchange(rte_int128_t *dst,
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 24ff7dc..e6ab15a 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
+/**
+ * 128-bit integer structure.
+ */
+RTE_STD_C11
+typedef struct {
+	RTE_STD_C11
+	union {
+		uint64_t val[2];
+#ifdef RTE_ARCH_64
+		__extension__ __int128 int128;
+#endif
+	};
+} __rte_aligned(16) rte_int128_t;
+
 #ifdef __DOXYGEN__
 
 /**
@@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
  *     *exp = *dst
  * @endcode
  *
- * @note This function is currently only available for the x86-64 platform.
+ * @note This function is currently available for the x86-64 and aarch64
+ * platforms.
  *
  * @note The success and failure arguments must be one of the __ATOMIC_* values
  * defined in the C++11 standard. For details on their behavior, refer to the
-- 
2.7.4


^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [PATCH] app/testpmd: support QinQ strip offload
  @ 2019-07-22 15:40  3%         ` Ferruh Yigit
  2019-07-22 17:03  0%           ` Iremonger, Bernard
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-07-22 15:40 UTC (permalink / raw)
  To: Iremonger, Bernard, viveksharma, dev; +Cc: intoviveksharma

On 7/22/2019 3:55 PM, Iremonger, Bernard wrote:
> Hi Ferruh,
> 
>> -----Original Message-----
>> From: Yigit, Ferruh
>> Sent: Monday, July 22, 2019 3:27 PM
>> To: Iremonger, Bernard <bernard.iremonger@intel.com>;
>> viveksharma@marvell.com; dev@dpdk.org
>> Cc: intoviveksharma@gmail.com
>> Subject: Re: [dpdk-dev] [PATCH] app/testpmd: support QinQ strip offload
>>
>> On 7/22/2019 1:04 PM, Iremonger, Bernard wrote:
>>> Hi Ferruh,
>>>
>>>> -----Original Message-----
>>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
>>>> Sent: Friday, July 19, 2019 5:53 PM
>>>> To: viveksharma@marvell.com; dev@dpdk.org
>>>> Cc: intoviveksharma@gmail.com
>>>> Subject: Re: [dpdk-dev] [PATCH] app/testpmd: support QinQ strip
>>>> offload
>>>>
>>>> On 7/17/2019 8:45 AM, viveksharma@marvell.com wrote:
>>>>> From: Vivek Sharma <viveksharma@marvell.com>
>>>>>
>>>>> Support QinQ strip RX offload configuration through testpmd command
>>>>> line and boot time arguments.
>>>>
>>>> For the testpmd command part, unfortunately there are two set of
>>>> commands for same purpose, the new ones are (lets both port and
>> queue
>>>> level):
>>>> "port config <port_id> rx_offload ..."
>>>> "port (port_id) rxq (queue_id) rx_offload ..."
>>>> "port config (port_id) tx_offload ..."
>>>> "port (port_id) txq (queue_id) tx_offload ..."
>>>>
>>>> These are better implementation comparing the old one:
>>>> "port config all ..."
>>>>
>>>> Would you mind sending a patch to remove "port config all ..."
>>>> variant of setting offloads?
>>>> And you can make your changes to the new commands above.
>>>
>>> Is it ok to remove "port config all ..." commands as they may be in use by
>> the community?
>>
>> Since there is a command that replaces the removed functionality I think it is
>> OK.
>>
>> Also I am not sure what level of backward compatibility we should provide
>> for testpmd commands.
> 
> It might be better to leave "port config all ..." commands  as they are for now and provide a separate patchset for the new style port setting offloads commands.
> 
> If they are to be removed there should at least  be something to announce this in the release notes.  There is a deprecation process which is used for the rest of the code, why not follow that process.

Deprecation process is for ABI/API changes.

I can see testpmd commands also a kind of user interface, but this is a test
application at the end, deprecation process can be overkill here.
Although +1 to be cautious on command consistency and keep some level of
stability on them.

> 
>>>> For the application argument, ``--enable-hw-vlan-extend``, instead of
>>>> adding a parameter of each offload argument, (and event it is not
>>>> clear if it is only for Rx or Tx), have a "--rx-offloads" argument and feed
>> the list via this, like:
>>>> "--rx-ofloads=disable-crc-strip,enable-rx-timestamp"
>>>>
>>>>
>>>>
>>>> And lastly for the  "vlan set ..." update, I think "qinq" was already
>>>> defined but it was calling 'vlan_extend_set()', now you are changing
>>>> it and making it call 'rx_vlan_qinq_strip_set()', I think this is OK,
>>>> but can you please update the 'cmd_help_long_parsed()' accordingly?
>>>
>>> 'vlan_extend_set()'  and 'rx_vlan_qinq_strip_set()'  are different
>> commands.
>>> vlan_extend_set()  is for adding the second vlan  and
>> rx_vlan_qinq_strip_set() is for removing the second vlan.
>>
>> yes they are different, I think nobody said they are same.
>> What is the concern here, can you please detail more?
> 
> In the previous paragraph, you mentioned that 
> "I think "qinq" was already defined but it was calling 'vlan_extend_set()', now you are changing
>  it and making it call 'rx_vlan_qinq_strip_set()' "
> 
> vlan_extend_set() is not being changed, rx_vlan_qinq_strip_set() is being added.

Before this patch,
"vlan set qinq" calls 'vlan_extend_set()'

After patch,
"vlan set qinq" calls 'rx_vlan_qinq_strip_set()'

And again after this patch,
"vlan set extend" added and which calls 'vlan_extend_set()'

so the patch looks like adding "vlan set extend" command, but practically it
does fix "vlan set qinq", I said "I think this is OK" and asked for help string
& documentation update accordingly.

I hope it is clear now.

> 
>>>> And in original 'cmd_help_long_parsed()' for 'vlan set ...", it
>>>> doesn't need to have separate lines for "strip, filter & qinq", can
>>>> you please merge them, and later the 'extend' one?
>>>> Than change needs to be documented on "testpmd_funcs.rst"
>>>>
>>>>
>>>> And as a last thing, can you please send this as multiple patches:
>>>> 1) Command line change for setting qinq offload
>>>> 2) Application argument change
>>>> 3) "vlan set " related changes
>>>>
>>>>>
>>>>> Signed-off-by: Vivek Sharma <viveksharma@marvell.com>
>>>>
>>>
>>> Regards,
>>>
>>> Bernard
>>>
> In my opinion this patch was fine for the "port config all ..." style commands.

Duplication is bad, it is bad to have two different ways to do same thing.
I am not sure if Vivek is aware of duplicated functions but explicitly prefers
to update old versions.
I suggest lets stop improving these ones and get rid of them asap.

Also as you can see commit log doesn't mention from "vlan set ..." changes at
all, that is why I asked for splitting this into 3 patches for 3 separate thing
it does.

> 
> A separate patch set should be submitted for the new style setting offloads commands.
> 
> Regards,
> 
> Bernard
> 


^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [PATCH v5 1/3] eal/arm64: add 128-bit atomic compare exchange
      2019-07-22  8:44  2% ` [dpdk-dev] [PATCH v4 " Phil Yang
@ 2019-07-22 13:06  2% ` Phil Yang
  2019-07-22 16:22  2% ` [dpdk-dev] [PATCH v6 " Phil Yang
  2019-07-23  5:57  2% ` [dpdk-dev] [PATCH v7 " Phil Yang
  4 siblings, 0 replies; 200+ results
From: Phil Yang @ 2019-07-22 13:06 UTC (permalink / raw)
  To: dev
  Cc: thomas, jerinj, gage.eads, hemant.agrawal, Honnappa.Nagarahalli,
	gavin.hu, nd

Add 128-bit atomic compare exchange on aarch64.

Suggested-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>

---
v5:
1. Enable RTE_ARM_FEATURE_ATOMICS on octeontx2 in default. (Jerin Jocob)
2. Record the reason of introducing "rte_stack_lf_stubs.h" in git commit.
(Jerin, Jocob)
3. Fixed a conditional MACRO error in rte_atomic128_cmp_exchange. (Jerin
Jocob)

v4:
1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions. (Jerin Jocob)
2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin Jocob)
3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage Eads/Jerin Jocob)

v3:
1. Avoid duplication code with macro. (Jerin Jocob)
2. Make invalid memory order to strongest barrier. (Jerin Jocob)
3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
4. Fix 32-bit x86 builds issue. (Gage Eads)
5. Correct documentation issues in UT. (Gage Eads)

v2:
Initial version.

 config/arm/meson.build                             |   2 +
 config/common_base                                 |   5 +
 config/defconfig_arm64-octeontx2-linuxapp-gcc      |   3 +
 config/defconfig_arm64-thunderx2-linuxapp-gcc      |   1 +
 .../common/include/arch/arm/rte_atomic_64.h        | 162 +++++++++++++++++++++
 .../common/include/arch/x86/rte_atomic_64.h        |  12 --
 lib/librte_eal/common/include/generic/rte_atomic.h |  17 ++-
 7 files changed, 189 insertions(+), 13 deletions(-)

diff --git a/config/arm/meson.build b/config/arm/meson.build
index 979018e..1f5f471 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -68,6 +68,7 @@ flags_thunderx_extra = [
 	['RTE_USE_C11_MEM_MODEL', false]]
 flags_thunderx2_extra = [
 	['RTE_MACHINE', '"thunderx2"'],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_CACHE_LINE_SIZE', 64],
 	['RTE_MAX_NUMA_NODES', 2],
 	['RTE_MAX_LCORE', 256],
@@ -76,6 +77,7 @@ flags_octeontx2_extra = [
 	['RTE_MACHINE', '"octeontx2"'],
 	['RTE_MAX_NUMA_NODES', 1],
 	['RTE_MAX_LCORE', 24],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_EAL_IGB_UIO', false],
 	['RTE_USE_C11_MEM_MODEL', true]]
 
diff --git a/config/common_base b/config/common_base
index 8ef75c2..16dea5a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -1067,3 +1067,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile ARM LSE ATOMIC instructions
+#
+CONFIG_RTE_ARM_FEATURE_ATOMICS=n
diff --git a/config/defconfig_arm64-octeontx2-linuxapp-gcc b/config/defconfig_arm64-octeontx2-linuxapp-gcc
index f20da24..a6508e8 100644
--- a/config/defconfig_arm64-octeontx2-linuxapp-gcc
+++ b/config/defconfig_arm64-octeontx2-linuxapp-gcc
@@ -19,3 +19,6 @@ CONFIG_RTE_EAL_IGB_UIO=n
 
 # Max supported NIX LFs
 CONFIG_RTE_MAX_VFIO_GROUPS=128
+
+# arm64 LSE ATOMIC support
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
index cc5c64b..17b6dec 100644
--- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
+++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
@@ -6,6 +6,7 @@
 
 CONFIG_RTE_MACHINE="thunderx2"
 
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
 CONFIG_RTE_CACHE_LINE_SIZE=64
 CONFIG_RTE_MAX_NUMA_NODES=2
 CONFIG_RTE_MAX_LCORE=256
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 97060e4..a040d69 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2015 Cavium, Inc
+ * Copyright(c) 2019 Arm Limited
  */
 
 #ifndef _RTE_ATOMIC_ARM64_H_
@@ -14,6 +15,9 @@ extern "C" {
 #endif
 
 #include "generic/rte_atomic.h"
+#include <rte_branch_prediction.h>
+#include <rte_compat.h>
+#include <rte_debug.h>
 
 #define dsb(opt) asm volatile("dsb " #opt : : : "memory")
 #define dmb(opt) asm volatile("dmb " #opt : : : "memory")
@@ -40,6 +44,164 @@ extern "C" {
 
 #define rte_cio_rmb() dmb(oshld)
 
+/*------------------------ 128 bit atomic operations -------------------------*/
+
+#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
+#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
+					  (mo) == __ATOMIC_SEQ_CST)
+
+#define __MO_LOAD(mo)  (__HAS_ACQ((mo)) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED)
+#define __MO_STORE(mo) (__HAS_RLS((mo)) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
+static __rte_noinline rte_int128_t                                          \
+cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
+		rte_int128_t updated)                                               \
+{                                                                           \
+	/* caspX instructions register pair must start from even-numbered
+	 * register at operand 1.
+	 * So, specify registers for local variables here.
+	 */                                                                     \
+	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];                \
+	register uint64_t x1 __asm("x1") = (uint64_t)old.val[1];                \
+	register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0];            \
+	register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1];            \
+	asm volatile(                                                           \
+			op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]"       \
+			: [old0] "+r" (x0),                                             \
+			  [old1] "+r" (x1)                                              \
+			: [upd0] "r" (x2),                                              \
+			  [upd1] "r" (x3),                                              \
+			  [dst] "r" (dst)                                               \
+			: "memory");                                                    \
+	old.val[0] = x0;                                                        \
+	old.val[1] = x1;                                                        \
+	return old;                                                             \
+}
+
+__ATOMIC128_CAS_OP(__rte_cas_relaxed, "casp")
+__ATOMIC128_CAS_OP(__rte_cas_acquire, "caspa")
+__ATOMIC128_CAS_OP(__rte_cas_release, "caspl")
+__ATOMIC128_CAS_OP(__rte_cas_acq_rel, "caspal")
+#else
+#define __ATOMIC128_LDX_OP(ldx_op_name, op_string)                          \
+static inline rte_int128_t                                                  \
+ldx_op_name(const rte_int128_t *src)                                        \
+{                                                                           \
+	rte_int128_t ret;                                                       \
+	asm volatile(                                                           \
+			op_string " %0, %1, %2"                                         \
+			: "=&r" (ret.val[0]),                                           \
+			  "=&r" (ret.val[1])                                            \
+			: "Q" (src->val[0])                                             \
+			: "memory");                                                    \
+	return ret;                                                             \
+}
+
+__ATOMIC128_LDX_OP(__rte_ldx_relaxed, "ldxp")
+__ATOMIC128_LDX_OP(__rte_ldx_acquire, "ldaxp")
+
+#define __ATOMIC128_STX_OP(stx_op_name, op_string)                          \
+static inline uint32_t                                                      \
+stx_op_name(rte_int128_t *dst, const rte_int128_t src)                      \
+{                                                                           \
+	uint32_t ret;                                                           \
+	asm volatile(                                                           \
+			op_string " %w0, %1, %2, %3"                                    \
+			: "=&r" (ret)                                                   \
+			: "r" (src.val[0]),                                             \
+			  "r" (src.val[1]),                                             \
+			  "Q" (dst->val[0])                                             \
+			: "memory");                                                    \
+	/* Return 0 on success, 1 on failure */                                 \
+	return ret;                                                             \
+}
+
+__ATOMIC128_STX_OP(__rte_stx_relaxed, "stxp")
+__ATOMIC128_STX_OP(__rte_stx_release, "stlxp")
+#endif
+
+static inline int __rte_experimental
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+				rte_int128_t *exp,
+				const rte_int128_t *src,
+				unsigned int weak,
+				int success,
+				int failure)
+{
+	/* Always do strong CAS */
+	RTE_SET_USED(weak);
+	/* Ignore memory ordering for failure, memory order for
+	 * success must be stronger or equal
+	 */
+	RTE_SET_USED(failure);
+	/* Find invalid memory order */
+	RTE_ASSERT(success == __ATOMIC_RELAXED
+			|| success == __ATOMIC_ACQUIRE
+			|| success == __ATOMIC_RELEASE
+			|| success == __ATOMIC_ACQ_REL
+			|| success == __ATOMIC_SEQ_CST);
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+	rte_int128_t expected = *exp;
+	rte_int128_t desired = *src;
+	rte_int128_t old;
+
+	if (success == __ATOMIC_RELAXED)
+		old = __rte_cas_relaxed(dst, expected, desired);
+	else if (success == __ATOMIC_ACQUIRE)
+		old = __rte_cas_acquire(dst, expected, desired);
+	else if (success == __ATOMIC_RELEASE)
+		old = __rte_cas_release(dst, expected, desired);
+	else
+		old = __rte_cas_acq_rel(dst, expected, desired);
+#else
+	int ldx_mo = __MO_LOAD(success);
+	int stx_mo = __MO_STORE(success);
+	uint32_t ret = 1;
+	register rte_int128_t expected = *exp;
+	register rte_int128_t desired = *src;
+	register rte_int128_t old;
+
+	/* ldx128 can not guarantee atomic,
+	 * Must write back src or old to verify atomicity of ldx128;
+	 */
+	do {
+		if (ldx_mo == __ATOMIC_RELAXED)
+			old = __rte_ldx_relaxed(dst);
+		else
+			old = __rte_ldx_acquire(dst);
+
+		if (likely(old.int128 == expected.int128)) {
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, desired);
+			else
+				ret = __rte_stx_release(dst, desired);
+		} else {
+			/* In the failure case (since 'weak' is ignored and only
+			 * weak == 0 is implemented), expected should contain the
+			 * atomically read value of dst. This means, 'old' needs
+			 * to be stored back to ensure it was read atomically.
+			 */
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, old);
+			else
+				ret = __rte_stx_release(dst, old);
+		}
+	} while (unlikely(ret));
+#endif
+
+	/* Unconditionally updating expected removes
+	 * an 'if' statement.
+	 * expected should already be in register if
+	 * not in the cache.
+	 */
+	*exp = old;
+
+	return (old.int128 == expected.int128);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index e087c6c..1217129 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -212,18 +212,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
-/**
- * 128-bit integer structure.
- */
-RTE_STD_C11
-typedef struct {
-	RTE_STD_C11
-	union {
-		uint64_t val[2];
-		__extension__ __int128 int128;
-	};
-} __rte_aligned(16) rte_int128_t;
-
 __rte_experimental
 static inline int
 rte_atomic128_cmp_exchange(rte_int128_t *dst,
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 24ff7dc..e6ab15a 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
+/**
+ * 128-bit integer structure.
+ */
+RTE_STD_C11
+typedef struct {
+	RTE_STD_C11
+	union {
+		uint64_t val[2];
+#ifdef RTE_ARCH_64
+		__extension__ __int128 int128;
+#endif
+	};
+} __rte_aligned(16) rte_int128_t;
+
 #ifdef __DOXYGEN__
 
 /**
@@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
  *     *exp = *dst
  * @endcode
  *
- * @note This function is currently only available for the x86-64 platform.
+ * @note This function is currently available for the x86-64 and aarch64
+ * platforms.
  *
  * @note The success and failure arguments must be one of the __ATOMIC_* values
  * defined in the C++11 standard. For details on their behavior, refer to the
-- 
2.7.4


^ permalink raw reply	[relevance 2%]

* [dpdk-dev] [PATCH v4 1/3] eal/arm64: add 128-bit atomic compare exchange
    @ 2019-07-22  8:44  2% ` Phil Yang
  2019-07-22 13:06  2% ` [dpdk-dev] [PATCH v5 " Phil Yang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: Phil Yang @ 2019-07-22  8:44 UTC (permalink / raw)
  To: dev
  Cc: thomas, jerinj, gage.eads, hemant.agrawal, Honnappa.Nagarahalli,
	gavin.hu, nd

Add 128-bit atomic compare exchange on aarch64.

Suggested-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>

---
V4:
1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions. (Jerin Jocob)
2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin Jocob)
3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage Eads/Jerin Jocob)

v3:
1. Avoid duplication code with macro. (Jerin Jocob)
2. Make invalid memory order to strongest barrier. (Jerin Jocob)
3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
4. Fix 32-bit x86 builds issue. (Gage Eads)
5. Correct documentation issues in UT. (Gage Eads)

v2:
Initial version.

 config/arm/meson.build                             |   1 +
 config/common_base                                 |   5 +
 config/defconfig_arm64-thunderx2-linuxapp-gcc      |   1 +
 .../common/include/arch/arm/rte_atomic_64.h        | 162 +++++++++++++++++++++
 .../common/include/arch/x86/rte_atomic_64.h        |  12 --
 lib/librte_eal/common/include/generic/rte_atomic.h |  17 ++-
 6 files changed, 185 insertions(+), 13 deletions(-)

diff --git a/config/arm/meson.build b/config/arm/meson.build
index 979018e..a88f21e 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -68,6 +68,7 @@ flags_thunderx_extra = [
 	['RTE_USE_C11_MEM_MODEL', false]]
 flags_thunderx2_extra = [
 	['RTE_MACHINE', '"thunderx2"'],
+	['RTE_ARM_FEATURE_ATOMICS', true],
 	['RTE_CACHE_LINE_SIZE', 64],
 	['RTE_MAX_NUMA_NODES', 2],
 	['RTE_MAX_LCORE', 256],
diff --git a/config/common_base b/config/common_base
index 8ef75c2..8862495 100644
--- a/config/common_base
+++ b/config/common_base
@@ -1067,3 +1067,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile ARM LSE ATOMIC instructions statically
+#
+CONFIG_RTE_ARM_FEATURE_ATOMICS=n
diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
index cc5c64b..17b6dec 100644
--- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
+++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
@@ -6,6 +6,7 @@
 
 CONFIG_RTE_MACHINE="thunderx2"
 
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
 CONFIG_RTE_CACHE_LINE_SIZE=64
 CONFIG_RTE_MAX_NUMA_NODES=2
 CONFIG_RTE_MAX_LCORE=256
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 97060e4..88b7ff4 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2015 Cavium, Inc
+ * Copyright(c) 2019 Arm Limited
  */
 
 #ifndef _RTE_ATOMIC_ARM64_H_
@@ -14,6 +15,9 @@ extern "C" {
 #endif
 
 #include "generic/rte_atomic.h"
+#include <rte_branch_prediction.h>
+#include <rte_compat.h>
+#include <rte_debug.h>
 
 #define dsb(opt) asm volatile("dsb " #opt : : : "memory")
 #define dmb(opt) asm volatile("dmb " #opt : : : "memory")
@@ -40,6 +44,164 @@ extern "C" {
 
 #define rte_cio_rmb() dmb(oshld)
 
+/*------------------------ 128 bit atomic operations -------------------------*/
+
+#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
+#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
+					  (mo) == __ATOMIC_SEQ_CST)
+
+#define __MO_LOAD(mo)  (__HAS_ACQ((mo)) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED)
+#define __MO_STORE(mo) (__HAS_RLS((mo)) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
+static __rte_noinline rte_int128_t                                          \
+cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
+		rte_int128_t updated)                                               \
+{                                                                           \
+	/* caspX instructions register pair must start from even-numbered
+	 * register at operand 1.
+	 * So, specify registers for local variables here.
+	 */                                                                     \
+	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];                \
+	register uint64_t x1 __asm("x1") = (uint64_t)old.val[1];                \
+	register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0];            \
+	register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1];            \
+	asm volatile(                                                           \
+			op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]"       \
+			: [old0] "+r" (x0),                                             \
+			  [old1] "+r" (x1)                                              \
+			: [upd0] "r" (x2),                                              \
+			  [upd1] "r" (x3),                                              \
+			  [dst] "r" (dst)                                               \
+			: "memory");                                                    \
+	old.val[0] = x0;                                                        \
+	old.val[1] = x1;                                                        \
+	return old;                                                             \
+}
+
+__ATOMIC128_CAS_OP(__rte_cas_relaxed, "casp")
+__ATOMIC128_CAS_OP(__rte_cas_acquire, "caspa")
+__ATOMIC128_CAS_OP(__rte_cas_release, "caspl")
+__ATOMIC128_CAS_OP(__rte_cas_acq_rel, "caspal")
+#else
+#define __ATOMIC128_LDX_OP(ldx_op_name, op_string)                          \
+static inline rte_int128_t                                                  \
+ldx_op_name(const rte_int128_t *src)                                        \
+{                                                                           \
+	rte_int128_t ret;                                                       \
+	asm volatile(                                                           \
+			op_string " %0, %1, %2"                                         \
+			: "=&r" (ret.val[0]),                                           \
+			  "=&r" (ret.val[1])                                            \
+			: "Q" (src->val[0])                                             \
+			: "memory");                                                    \
+	return ret;                                                             \
+}
+
+__ATOMIC128_LDX_OP(__rte_ldx_relaxed, "ldxp")
+__ATOMIC128_LDX_OP(__rte_ldx_acquire, "ldaxp")
+
+#define __ATOMIC128_STX_OP(stx_op_name, op_string)                          \
+static inline uint32_t                                                      \
+stx_op_name(rte_int128_t *dst, const rte_int128_t src)                      \
+{                                                                           \
+	uint32_t ret;                                                           \
+	asm volatile(                                                           \
+			op_string " %w0, %1, %2, %3"                                    \
+			: "=&r" (ret)                                                   \
+			: "r" (src.val[0]),                                             \
+			  "r" (src.val[1]),                                             \
+			  "Q" (dst->val[0])                                             \
+			: "memory");                                                    \
+	/* Return 0 on success, 1 on failure */                                 \
+	return ret;                                                             \
+}
+
+__ATOMIC128_STX_OP(__rte_stx_relaxed, "stxp")
+__ATOMIC128_STX_OP(__rte_stx_release, "stlxp")
+#endif
+
+static inline int __rte_experimental
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+				rte_int128_t *exp,
+				const rte_int128_t *src,
+				unsigned int weak,
+				int success,
+				int failure)
+{
+	/* Always do strong CAS */
+	RTE_SET_USED(weak);
+	/* Ignore memory ordering for failure, memory order for
+	 * success must be stronger or equal
+	 */
+	RTE_SET_USED(failure);
+	/* Find invalid memory order */
+	RTE_ASSERT(success == __ATOMIC_RELAXED
+			|| success == __ATOMIC_ACQUIRE
+			|| success == __ATOMIC_RELEASE
+			|| success == __ATOMIC_ACQ_REL
+			|| success == __ATOMIC_SEQ_CST);
+
+#ifdef __ARM_FEATURE_ATOMICS
+	rte_int128_t expected = *exp;
+	rte_int128_t desired = *src;
+	rte_int128_t old;
+
+	if (success == __ATOMIC_RELAXED)
+		old = __rte_cas_relaxed(dst, expected, desired);
+	else if (success == __ATOMIC_ACQUIRE)
+		old = __rte_cas_acquire(dst, expected, desired);
+	else if (success == __ATOMIC_RELEASE)
+		old = __rte_cas_release(dst, expected, desired);
+	else
+		old = __rte_cas_acq_rel(dst, expected, desired);
+#else
+	int ldx_mo = __MO_LOAD(success);
+	int stx_mo = __MO_STORE(success);
+	uint32_t ret = 1;
+	register rte_int128_t expected = *exp;
+	register rte_int128_t desired = *src;
+	register rte_int128_t old;
+
+	/* ldx128 can not guarantee atomic,
+	 * Must write back src or old to verify atomicity of ldx128;
+	 */
+	do {
+		if (ldx_mo == __ATOMIC_RELAXED)
+			old = __rte_ldx_relaxed(dst);
+		else
+			old = __rte_ldx_acquire(dst);
+
+		if (likely(old.int128 == expected.int128)) {
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, desired);
+			else
+				ret = __rte_stx_release(dst, desired);
+		} else {
+			/* In the failure case (since 'weak' is ignored and only
+			 * weak == 0 is implemented), expected should contain the
+			 * atomically read value of dst. This means, 'old' needs
+			 * to be stored back to ensure it was read atomically.
+			 */
+			if (stx_mo == __ATOMIC_RELAXED)
+				ret = __rte_stx_relaxed(dst, old);
+			else
+				ret = __rte_stx_release(dst, old);
+		}
+	} while (unlikely(ret));
+#endif
+
+	/* Unconditionally updating expected removes
+	 * an 'if' statement.
+	 * expected should already be in register if
+	 * not in the cache.
+	 */
+	*exp = old;
+
+	return (old.int128 == expected.int128);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index e087c6c..1217129 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -212,18 +212,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
-/**
- * 128-bit integer structure.
- */
-RTE_STD_C11
-typedef struct {
-	RTE_STD_C11
-	union {
-		uint64_t val[2];
-		__extension__ __int128 int128;
-	};
-} __rte_aligned(16) rte_int128_t;
-
 __rte_experimental
 static inline int
 rte_atomic128_cmp_exchange(rte_int128_t *dst,
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 24ff7dc..e6ab15a 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
+/**
+ * 128-bit integer structure.
+ */
+RTE_STD_C11
+typedef struct {
+	RTE_STD_C11
+	union {
+		uint64_t val[2];
+#ifdef RTE_ARCH_64
+		__extension__ __int128 int128;
+#endif
+	};
+} __rte_aligned(16) rte_int128_t;
+
 #ifdef __DOXYGEN__
 
 /**
@@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
  *     *exp = *dst
  * @endcode
  *
- * @note This function is currently only available for the x86-64 platform.
+ * @note This function is currently available for the x86-64 and aarch64
+ * platforms.
  *
  * @note The success and failure arguments must be one of the __ATOMIC_* values
  * defined in the C++11 standard. For details on their behavior, refer to the
-- 
2.7.4


^ permalink raw reply	[relevance 2%]

* Re: [dpdk-dev] [RFC] mark asym session-buffer non-reuseable
  2019-07-19 14:50  3%     ` Ayuj Verma
@ 2019-07-19 15:38  3%       ` Trahe, Fiona
  0 siblings, 0 replies; 200+ results
From: Trahe, Fiona @ 2019-07-19 15:38 UTC (permalink / raw)
  To: Ayuj Verma, Kusztal, ArkadiuszX, akhil.goyal
  Cc: Shally Verma, Sunila Sahu, Kanaka Durga Kotamarthy, dev, Trahe, Fiona

No need as API is still experimental.

Howver I'd suggest changing the subject to
"declare crypto asym xform immutable"
non-reusable is confusing as the session and xform will be re-used on all the ops associated with the session.

From: Ayuj Verma [mailto:ayverma@marvell.com]
Sent: Friday, July 19, 2019 3:51 PM
To: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; akhil.goyal@nxp.com
Cc: Trahe, Fiona <fiona.trahe@intel.com>; Shally Verma <shallyv@marvell.com>; Sunila Sahu <ssahu@marvell.com>; Kanaka Durga Kotamarthy <kkotamarthy@marvell.com>; dev@dpdk.org
Subject: Re: [RFC] mark asym session-buffer non-reuseable


Hi Akhil, Arek, Fiona,



Since this require changes in other Asym PMD( qat) apart from openssl (we plan to send changes for this),

so should we need to send any announcement on ABI breakage here before proposing patch v1?



Thanks and regards

Ayuj Verma

________________________________
From: Ayuj Verma
Sent: 18 July 2019 15:17:54
To: Kusztal, ArkadiuszX; akhil.goyal@nxp.com<mailto:akhil.goyal@nxp.com>
Cc: Trahe, Fiona; Shally Verma; Sunila Sahu; Kanaka Durga Kotamarthy; dev@dpdk.org<mailto:dev@dpdk.org>
Subject: Re: [RFC] mark asym session-buffer non-reuseable


Hi Arek,



Please see inline.



Thanks and regards

Ayuj Verma

________________________________
From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com<mailto:arkadiuszx.kusztal@intel.com>>
Sent: 17 July 2019 19:40
To: Ayuj Verma; akhil.goyal@nxp.com<mailto:akhil.goyal@nxp.com>
Cc: Trahe, Fiona; Shally Verma; Sunila Sahu; Kanaka Durga Kotamarthy; dev@dpdk.org<mailto:dev@dpdk.org>
Subject: RE: [RFC] mark asym session-buffer non-reuseable

Hi Ayuj,

> -----Original Message-----
> From: Ayuj Verma [mailto:ayverma@marvell.com]
> Sent: Wednesday, July 17, 2019 2:34 PM
> To: akhil.goyal@nxp.com<mailto:akhil.goyal@nxp.com>
> Cc: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com<mailto:arkadiuszx.kusztal@intel.com>>; Trahe, Fiona
> <fiona.trahe@intel.com<mailto:fiona.trahe@intel.com>>; shallyv@marvell.com<mailto:shallyv@marvell.com>; ssahu@marvell.com<mailto:ssahu@marvell.com>;
> kkotamarthy@marvell.com<mailto:kkotamarthy@marvell.com>; dev@dpdk.org<mailto:dev@dpdk.org>; Ayuj Verma
> <ayverma@marvell.com<mailto:ayverma@marvell.com>>
> Subject: [RFC] mark asym session-buffer non-reuseable
>
> This RFC proposes changes in asymmetric session usability of transform
> structure. In current implementation asym xform is seen as temporary entity
> that can be re-used by application once sessions are initialized with it.
>
> This enforces PMD to copy all key buffers during session setup time. Since
> life-time of sessions are small, so we can hold these buffers with session,
[AK] - what is you expected session lifetime? (2,3,50 packets?)
[Ayuj] In practical scenario like SSL, handshake will happen in some 10-15 packets.
> reducing memcpy time by marking these as read-only so that PMDs which
> doesn't require any manipulation of xform data can directly use these
> buffers in session configure.
>
> So, sending a proposal to mark xform as non-reusable till lifetime of session.
> This will help PMDs to reduce session setup time.
>
> Ayuj Verma (1):
>   lib/crypto: mark asym session-buffer non-reuseable
>
>  doc/guides/prog_guide/cryptodev_lib.rst  | 6 ++++++
> lib/librte_cryptodev/rte_cryptodev_pmd.h | 2 +-
>  2 files changed, 7 insertions(+), 1 deletion(-)
>
> --
> 1.8.3.1

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC] mark asym session-buffer non-reuseable
  @ 2019-07-19 14:50  3%     ` Ayuj Verma
  2019-07-19 15:38  3%       ` Trahe, Fiona
  0 siblings, 1 reply; 200+ results
From: Ayuj Verma @ 2019-07-19 14:50 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, akhil.goyal
  Cc: Trahe, Fiona, Shally Verma, Sunila Sahu, Kanaka Durga Kotamarthy, dev

Hi Akhil, Arek, Fiona,


Since this require changes in other Asym PMD( qat) apart from openssl (we plan to send changes for this),

so should we need to send any announcement on ABI breakage here before proposing patch v1?


Thanks and regards

Ayuj Verma

________________________________
From: Ayuj Verma
Sent: 18 July 2019 15:17:54
To: Kusztal, ArkadiuszX; akhil.goyal@nxp.com
Cc: Trahe, Fiona; Shally Verma; Sunila Sahu; Kanaka Durga Kotamarthy; dev@dpdk.org
Subject: Re: [RFC] mark asym session-buffer non-reuseable


Hi Arek,


Please see inline.


Thanks and regards

Ayuj Verma


________________________________
From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
Sent: 17 July 2019 19:40
To: Ayuj Verma; akhil.goyal@nxp.com
Cc: Trahe, Fiona; Shally Verma; Sunila Sahu; Kanaka Durga Kotamarthy; dev@dpdk.org
Subject: RE: [RFC] mark asym session-buffer non-reuseable

Hi Ayuj,

> -----Original Message-----
> From: Ayuj Verma [mailto:ayverma@marvell.com]
> Sent: Wednesday, July 17, 2019 2:34 PM
> To: akhil.goyal@nxp.com
> Cc: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; shallyv@marvell.com; ssahu@marvell.com;
> kkotamarthy@marvell.com; dev@dpdk.org; Ayuj Verma
> <ayverma@marvell.com>
> Subject: [RFC] mark asym session-buffer non-reuseable
>
> This RFC proposes changes in asymmetric session usability of transform
> structure. In current implementation asym xform is seen as temporary entity
> that can be re-used by application once sessions are initialized with it.
>
> This enforces PMD to copy all key buffers during session setup time. Since
> life-time of sessions are small, so we can hold these buffers with session,
[AK] - what is you expected session lifetime? (2,3,50 packets?)
[Ayuj] In practical scenario like SSL, handshake will happen in some 10-15 packets.
> reducing memcpy time by marking these as read-only so that PMDs which
> doesn’t require any manipulation of xform data can directly use these
> buffers in session configure.
>
> So, sending a proposal to mark xform as non-reusable till lifetime of session.
> This will help PMDs to reduce session setup time.
>
> Ayuj Verma (1):
>   lib/crypto: mark asym session-buffer non-reuseable
>
>  doc/guides/prog_guide/cryptodev_lib.rst  | 6 ++++++
> lib/librte_cryptodev/rte_cryptodev_pmd.h | 2 +-
>  2 files changed, 7 insertions(+), 1 deletion(-)
>
> --
> 1.8.3.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [EXT] [PATCH v3 1/3] eal/arm64: add 128-bit atomic compare exchange
  2019-07-19 12:35  0%       ` Jerin Jacob Kollanukkaran
@ 2019-07-19 13:56  0%         ` Phil Yang (Arm Technology China)
  0 siblings, 0 replies; 200+ results
From: Phil Yang (Arm Technology China) @ 2019-07-19 13:56 UTC (permalink / raw)
  To: jerinj, gage.eads, dev
  Cc: thomas, hemant.agrawal, Honnappa Nagarahalli,
	Gavin Hu (Arm Technology China),
	nd, nd

> -----Original Message-----
> From: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> Sent: Friday, July 19, 2019 8:35 PM
> To: Phil Yang (Arm Technology China) <Phil.Yang@arm.com>; dev@dpdk.org
> Cc: thomas@monjalon.net; hemant.agrawal@nxp.com; Honnappa
> Nagarahalli <Honnappa.Nagarahalli@arm.com>; Gavin Hu (Arm Technology
> China) <Gavin.Hu@arm.com>; nd <nd@arm.com>; gage.eads@intel.com; nd
> <nd@arm.com>
> Subject: RE: [EXT] [PATCH v3 1/3] eal/arm64: add 128-bit atomic compare
> exchange
> 
> > > > +#define RTE_HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) !=
> > > > +__ATOMIC_RELEASE) #define RTE_HAS_RLS(mo) ((mo) ==
> > > > __ATOMIC_RELEASE || \
> > > > +			 (mo) == __ATOMIC_ACQ_REL || \
> > > > +			 (mo) == __ATOMIC_SEQ_CST)
> > > > +
> > > > +#define RTE_MO_LOAD(mo)  (RTE_HAS_ACQ((mo)) \
> > > > +		? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED) #define
> > > > RTE_MO_STORE(mo)
> > > > +(RTE_HAS_RLS((mo)) \
> > > > +		? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
> > > > +
> > >
> > > The one starts with RTE_ are public symbols, If it is generic enough,
> > > Move to common layer so that every architecturse can use.
> > > If you think, otherwise make it internal
> >
> > Let's keep it internal. I will remove the 'RTE_' tag.
> 
> Probably change to __HAS_ACQ to avoid collision(just in case)

OK.

> 
> > >
> > >
> > >
> > > > +#ifdef __ARM_FEATURE_ATOMICS
> > >
> > > This define is added in gcc 9.1 and I believe for clang it is not supported
> yet.
> > > So old gcc and clang this will be undefined.
> > > I think, With meson + native build, we  can find the presence of
> > > ATOMIC support by running a.out. Not sure about make and cross build
> case.
> > > I don't want block this feature because of this, IMO, We can add this
> > > code with  existing __ARM_FEATURE_ATOMICS scheme and later find a
> > > method to enhance it. But please check how to fix it.
> >
> > OK.
> 
> After thinking on this a bit, I think,  in order to support old gcc(< gcc 9.1) and
> clang,
> We can introduce a config option, where, by default it is disabled and enable
> In specific config(where we know, lse is supported) and meson config.
> 
> i.e
> #if defined(__ARM_FEATURE_ATOMICS) ||
> defined(RTE_ARM_FEATURE_ATOMICS)

Cool

> 
> 
> >
> > >
> > > > +#define __ATOMIC128_CAS_OP(cas_op_name, op_string)
> \
> > > > +static inline rte_int128_t                                                  \
> > > > +cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
> > > > +		rte_int128_t updated)                                               \
> > > > +{                                                                           \
> > > > +	/* caspX instructions register pair must start from even-numbered
> > > > +	 * register at operand 1.
> > > > +	 * So, specify registers for local variables here.
> > > > +	 */                                                                     \
> > > > +	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];                \
> > >
> > > Since direct x0 register used in the code and
> > > cas_op_name() and rte_atomic128_cmp_exchange() is inline function,
> > > Based on parent function load, we may corrupt x0 register aka
> >
> > Since x0/x1 and x2/x3 are used a lot and often contain live values.
> > Maybe to change them to some relatively less frequently used registers
> like
> > x14/x15 and x16/x17 might help for this case?
> > According to the PCS (Procedure Call Standard), x14-x17 are also temporary
> > registers.
> 
> X14-x17 are temporary registers but since
> cas_op_name() and rte_atomic128_cmp_exchange() are inline functions,
> Based on the parent function register usage, it _may_ corrupt.

Just checked how Linux Kernel does similar things:
https://github.com/torvalds/linux/blob/master/arch/arm64/include/asm/atomic_lse.h#L19 

Same methods.

I will finish the benchmarking for the no_inline approach. If it has no significant performance loss, I think we can make it as no_inline.  

> 
> 
> >
> > > Break arm64 ABI. Not sure clobber list will help here or not?
> >
> > In my understanding, for the register variable, if it contains a live value in
> the
> > specified register, the compiler will move the live value into a free register.
> > Since x0~x3 are present in the input/output operands and x0/x1's value
> needs to
> > be restored to the variable 'old' as a return value.
> > So I didn't add them into the clobber list.
> 
> OK
> 
> >
> > > Making it as no_inline will help but not sure about the performance
> impact.
> > > May be you can check with compiler team.
> > >
> > > We burned our hands with this scheme, see
> > > 5b40ec6b966260e0ff66a8a2c689664f75d6a0e6 ("mempool/octeontx2: fix
> > > possible arm64 ABI break")
> > >
> > > Probably we can choose a scheme for rc2 and adjust as when we have
> > > complete clarity.
> > >
> > > >
> > > > +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
> > >
> > > There is nothing specific to x86 and arm64 here, Can we remove this
> #ifdef ?
> >
> > Without this constraint, it will break 32-bit x86 builds.
> > http://mails.dpdk.org/archives/test-report/2019-June/086586.html
> 
> OK . #ifdef RTE_ARCH_64 would help then.

OK.

> 
> >
> > >
> > > > +/**
> > > > + * 128-bit integer structure.
> > > > + */
> > > > +RTE_STD_C11
> > > > +typedef struct {
> > > > +	RTE_STD_C11
> > > > +	union {
> > > > +		uint64_t val[2];
> > > > +		__extension__ __int128 int128;
> 
> Instead of guarding  RTE_ARCH_64 on this complete structure,
> How about it only under
> #ifdef RTE_ARCH_64
> __extension__ __int128 int128;
> #endif
> So that it rte_int128_t will be available for 32bit as well.

Agree, it should be work. But I am not sure. 

Hi Gage,

How do you think about this? 

> 
> 
> > > > +	};
> > > > +} __rte_aligned(16) rte_int128_t;
> > > > +#endif
> > > > +
> > > >  #ifdef __DOXYGEN__

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [EXT] [PATCH v3 1/3] eal/arm64: add 128-bit atomic compare exchange
  2019-07-19 11:01  0%     ` Phil Yang (Arm Technology China)
@ 2019-07-19 12:35  0%       ` Jerin Jacob Kollanukkaran
  2019-07-19 13:56  0%         ` Phil Yang (Arm Technology China)
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-07-19 12:35 UTC (permalink / raw)
  To: Phil Yang (Arm Technology China), dev
  Cc: thomas, hemant.agrawal, Honnappa Nagarahalli,
	Gavin Hu (Arm Technology China),
	nd, gage.eads, nd

> > > +#define RTE_HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) !=
> > > +__ATOMIC_RELEASE) #define RTE_HAS_RLS(mo) ((mo) ==
> > > __ATOMIC_RELEASE || \
> > > +			 (mo) == __ATOMIC_ACQ_REL || \
> > > +			 (mo) == __ATOMIC_SEQ_CST)
> > > +
> > > +#define RTE_MO_LOAD(mo)  (RTE_HAS_ACQ((mo)) \
> > > +		? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED) #define
> > > RTE_MO_STORE(mo)
> > > +(RTE_HAS_RLS((mo)) \
> > > +		? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
> > > +
> >
> > The one starts with RTE_ are public symbols, If it is generic enough,
> > Move to common layer so that every architecturse can use.
> > If you think, otherwise make it internal
> 
> Let's keep it internal. I will remove the 'RTE_' tag.

Probably change to __HAS_ACQ to avoid collision(just in case)

> >
> >
> >
> > > +#ifdef __ARM_FEATURE_ATOMICS
> >
> > This define is added in gcc 9.1 and I believe for clang it is not supported yet.
> > So old gcc and clang this will be undefined.
> > I think, With meson + native build, we  can find the presence of
> > ATOMIC support by running a.out. Not sure about make and cross build case.
> > I don't want block this feature because of this, IMO, We can add this
> > code with  existing __ARM_FEATURE_ATOMICS scheme and later find a
> > method to enhance it. But please check how to fix it.
> 
> OK.

After thinking on this a bit, I think,  in order to support old gcc(< gcc 9.1) and clang,
We can introduce a config option, where, by default it is disabled and enable
In specific config(where we know, lse is supported) and meson config.

i.e
#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)


> 
> >
> > > +#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
> > > +static inline rte_int128_t                                                  \
> > > +cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
> > > +		rte_int128_t updated)                                               \
> > > +{                                                                           \
> > > +	/* caspX instructions register pair must start from even-numbered
> > > +	 * register at operand 1.
> > > +	 * So, specify registers for local variables here.
> > > +	 */                                                                     \
> > > +	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];                \
> >
> > Since direct x0 register used in the code and
> > cas_op_name() and rte_atomic128_cmp_exchange() is inline function,
> > Based on parent function load, we may corrupt x0 register aka
> 
> Since x0/x1 and x2/x3 are used a lot and often contain live values.
> Maybe to change them to some relatively less frequently used registers like
> x14/x15 and x16/x17 might help for this case?
> According to the PCS (Procedure Call Standard), x14-x17 are also temporary
> registers.

X14-x17 are temporary registers but since 
cas_op_name() and rte_atomic128_cmp_exchange() are inline functions,
Based on the parent function register usage, it _may_ corrupt.


> 
> > Break arm64 ABI. Not sure clobber list will help here or not?
> 
> In my understanding, for the register variable, if it contains a live value in the
> specified register, the compiler will move the live value into a free register.
> Since x0~x3 are present in the input/output operands and x0/x1's value needs to
> be restored to the variable 'old' as a return value.
> So I didn't add them into the clobber list.

OK

> 
> > Making it as no_inline will help but not sure about the performance impact.
> > May be you can check with compiler team.
> >
> > We burned our hands with this scheme, see
> > 5b40ec6b966260e0ff66a8a2c689664f75d6a0e6 ("mempool/octeontx2: fix
> > possible arm64 ABI break")
> >
> > Probably we can choose a scheme for rc2 and adjust as when we have
> > complete clarity.
> >
> > >
> > > +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
> >
> > There is nothing specific to x86 and arm64 here, Can we remove this #ifdef ?
> 
> Without this constraint, it will break 32-bit x86 builds.
> http://mails.dpdk.org/archives/test-report/2019-June/086586.html

OK . #ifdef RTE_ARCH_64 would help then.

> 
> >
> > > +/**
> > > + * 128-bit integer structure.
> > > + */
> > > +RTE_STD_C11
> > > +typedef struct {
> > > +	RTE_STD_C11
> > > +	union {
> > > +		uint64_t val[2];
> > > +		__extension__ __int128 int128;

Instead of guarding  RTE_ARCH_64 on this complete structure,
How about it only under
#ifdef RTE_ARCH_64
__extension__ __int128 int128;
#endif
So that it rte_int128_t will be available for 32bit as well.


> > > +	};
> > > +} __rte_aligned(16) rte_int128_t;
> > > +#endif
> > > +
> > >  #ifdef __DOXYGEN__

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [EXT] [PATCH v3 1/3] eal/arm64: add 128-bit atomic compare exchange
  2019-07-19  6:24  4%   ` [dpdk-dev] [EXT] " Jerin Jacob Kollanukkaran
@ 2019-07-19 11:01  0%     ` Phil Yang (Arm Technology China)
  2019-07-19 12:35  0%       ` Jerin Jacob Kollanukkaran
  0 siblings, 1 reply; 200+ results
From: Phil Yang (Arm Technology China) @ 2019-07-19 11:01 UTC (permalink / raw)
  To: jerinj, dev
  Cc: thomas, hemant.agrawal, Honnappa Nagarahalli,
	Gavin Hu (Arm Technology China),
	nd, gage.eads, nd

> -----Original Message-----
> From: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> Sent: Friday, July 19, 2019 2:25 PM
> To: Phil Yang (Arm Technology China) <Phil.Yang@arm.com>; dev@dpdk.org
> Cc: thomas@monjalon.net; hemant.agrawal@nxp.com; Honnappa
> Nagarahalli <Honnappa.Nagarahalli@arm.com>; Gavin Hu (Arm Technology
> China) <Gavin.Hu@arm.com>; nd <nd@arm.com>; gage.eads@intel.com
> Subject: RE: [EXT] [PATCH v3 1/3] eal/arm64: add 128-bit atomic compare
> exchange
> 
> > -----Original Message-----
> > From: Phil Yang <phil.yang@arm.com>
> > Sent: Friday, June 28, 2019 1:42 PM
> > To: dev@dpdk.org
> > Cc: thomas@monjalon.net; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>;
> > hemant.agrawal@nxp.com; Honnappa.Nagarahalli@arm.com;
> > gavin.hu@arm.com; nd@arm.com; gage.eads@intel.com
> > Subject: [EXT] [PATCH v3 1/3] eal/arm64: add 128-bit atomic compare
> > exchange
> >
> > External Email
> >
> > ----------------------------------------------------------------------
> > Add 128-bit atomic compare exchange on aarch64.
> >
> > Signed-off-by: Phil Yang <phil.yang@arm.com>
> > Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > ---
> > +#define RTE_HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) !=
> > +__ATOMIC_RELEASE) #define RTE_HAS_RLS(mo) ((mo) ==
> > __ATOMIC_RELEASE || \
> > +			 (mo) == __ATOMIC_ACQ_REL || \
> > +			 (mo) == __ATOMIC_SEQ_CST)
> > +
> > +#define RTE_MO_LOAD(mo)  (RTE_HAS_ACQ((mo)) \
> > +		? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED) #define
> > RTE_MO_STORE(mo)
> > +(RTE_HAS_RLS((mo)) \
> > +		? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
> > +
> 
> The one starts with RTE_ are public symbols, If it is generic enough,
> Move to common layer so that every architecturse can use.
> If you think, otherwise make it internal

Let's keep it internal. I will remove the 'RTE_' tag. 

> 
> 
> 
> > +#ifdef __ARM_FEATURE_ATOMICS
> 
> This define is added in gcc 9.1 and I believe for clang it is not supported yet.
> So old gcc and clang this will be undefined.
> I think, With meson + native build, we  can find the presence of
> ATOMIC support by running a.out. Not sure about make and cross build case.
> I don't want block this feature because of this, IMO, We can add this code
> with  existing __ARM_FEATURE_ATOMICS scheme and later find a method
> to enhance it. But please check how to fix it.

OK.

> 
> > +#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
> > +static inline rte_int128_t                                                  \
> > +cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
> > +		rte_int128_t updated)                                               \
> > +{                                                                           \
> > +	/* caspX instructions register pair must start from even-numbered
> > +	 * register at operand 1.
> > +	 * So, specify registers for local variables here.
> > +	 */                                                                     \
> > +	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];                \
> 
> Since direct x0 register used in the code and
> cas_op_name() and rte_atomic128_cmp_exchange() is inline function,
> Based on parent function load, we may corrupt x0 register aka

Since x0/x1 and x2/x3 are used a lot and often contain live values.
Maybe to change them to some relatively less frequently used registers like x14/x15 and x16/x17 might help for this case?
According to the PCS (Procedure Call Standard), x14-x17 are also temporary registers.

> Break arm64 ABI. Not sure clobber list will help here or not?

In my understanding, for the register variable, if it contains a live value in the specified register, the compiler will move the live value into a free register. 
Since x0~x3 are present in the input/output operands and x0/x1's value needs to be restored to the variable 'old' as a return value. 
So I didn't add them into the clobber list.

> Making it as no_inline will help but not sure about the performance impact.
> May be you can check with compiler team.
> 
> We burned our hands with this scheme, see
> 5b40ec6b966260e0ff66a8a2c689664f75d6a0e6 ("mempool/octeontx2: fix
> possible arm64 ABI break")
> 
> Probably we can choose a scheme for rc2 and adjust as when we have
> complete clarity.
> 
> > +	register uint64_t x1 __asm("x1") = (uint64_t)old.val[1];                \
> > +	register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0];            \
> > +	register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1];            \
> > +	asm volatile(                                                           \
> > +			op_string " %[old0], %[old1], %[upd0], %[upd1],
> > [%[dst]]"       \
> > +			: [old0] "+r" (x0),                                             \
> > +			  [old1] "+r" (x1)                                              \
> > +			: [upd0] "r" (x2),                                              \
> > +			  [upd1] "r" (x3),                                              \
> > +			  [dst] "r" (dst)                                               \
> > +			: "memory");                                                    \
> 
> Should n't we add x0,x1, x2, x3 in clobber list?

Same as above.

> 
> 
> >  static inline int __rte_experimental
> >  rte_atomic128_cmp_exchange(rte_int128_t *dst,
> >  			   rte_int128_t *exp,
> > diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h
> > b/lib/librte_eal/common/include/generic/rte_atomic.h
> > index 9958543..2355e50 100644
> > --- a/lib/librte_eal/common/include/generic/rte_atomic.h
> > +++ b/lib/librte_eal/common/include/generic/rte_atomic.h
> > @@ -1081,6 +1081,20 @@ static inline void
> > rte_atomic64_clear(rte_atomic64_t *v)
> >
> >  /*------------------------ 128 bit atomic operations -------------------------*/
> >
> > +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
> 
> There is nothing specific to x86 and arm64 here, Can we remove this #ifdef ?

Without this constraint, it will break 32-bit x86 builds.
http://mails.dpdk.org/archives/test-report/2019-June/086586.html 

> 
> > +/**
> > + * 128-bit integer structure.
> > + */
> > +RTE_STD_C11
> > +typedef struct {
> > +	RTE_STD_C11
> > +	union {
> > +		uint64_t val[2];
> > +		__extension__ __int128 int128;
> > +	};
> > +} __rte_aligned(16) rte_int128_t;
> > +#endif
> > +
> >  #ifdef __DOXYGEN__

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [EXT] [PATCH v3 1/3] eal/arm64: add 128-bit atomic compare exchange
  @ 2019-07-19  6:24  4%   ` Jerin Jacob Kollanukkaran
  2019-07-19 11:01  0%     ` Phil Yang (Arm Technology China)
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-07-19  6:24 UTC (permalink / raw)
  To: Phil Yang, dev
  Cc: thomas, hemant.agrawal, Honnappa.Nagarahalli, gavin.hu, nd, gage.eads

> -----Original Message-----
> From: Phil Yang <phil.yang@arm.com>
> Sent: Friday, June 28, 2019 1:42 PM
> To: dev@dpdk.org
> Cc: thomas@monjalon.net; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> hemant.agrawal@nxp.com; Honnappa.Nagarahalli@arm.com;
> gavin.hu@arm.com; nd@arm.com; gage.eads@intel.com
> Subject: [EXT] [PATCH v3 1/3] eal/arm64: add 128-bit atomic compare
> exchange
> 
> External Email
> 
> ----------------------------------------------------------------------
> Add 128-bit atomic compare exchange on aarch64.
> 
> Signed-off-by: Phil Yang <phil.yang@arm.com>
> Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> ---
> +#define RTE_HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) !=
> +__ATOMIC_RELEASE) #define RTE_HAS_RLS(mo) ((mo) ==
> __ATOMIC_RELEASE || \
> +			 (mo) == __ATOMIC_ACQ_REL || \
> +			 (mo) == __ATOMIC_SEQ_CST)
> +
> +#define RTE_MO_LOAD(mo)  (RTE_HAS_ACQ((mo)) \
> +		? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED) #define
> RTE_MO_STORE(mo)
> +(RTE_HAS_RLS((mo)) \
> +		? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
> +

The one starts with RTE_ are public symbols, If it is generic enough,
Move to common layer so that every architecturse can use.
If you think, otherwise make it internal 



> +#ifdef __ARM_FEATURE_ATOMICS

This define is added in gcc 9.1 and I believe for clang it is not supported yet.
So old gcc and clang this will be undefined.
I think, With meson + native build, we  can find the presence of 
ATOMIC support by running a.out. Not sure about make and cross build case.
I don't want block this feature because of this, IMO, We can add this code
with  existing __ARM_FEATURE_ATOMICS scheme and later find a method
to enhance it. But please check how to fix it.

> +#define __ATOMIC128_CAS_OP(cas_op_name, op_string)                          \
> +static inline rte_int128_t                                                  \
> +cas_op_name(rte_int128_t *dst, rte_int128_t old,                            \
> +		rte_int128_t updated)                                               \
> +{                                                                           \
> +	/* caspX instructions register pair must start from even-numbered
> +	 * register at operand 1.
> +	 * So, specify registers for local variables here.
> +	 */                                                                     \
> +	register uint64_t x0 __asm("x0") = (uint64_t)old.val[0];                \

Since direct x0 register used in the code and
cas_op_name() and rte_atomic128_cmp_exchange() is inline function,
Based on parent function load, we may corrupt x0 register aka
Break arm64 ABI. Not sure clobber list will help here or not?
Making it as no_inline will help but not sure about the performance impact.
May be you can check with compiler team. 

We burned our hands with this scheme, see
5b40ec6b966260e0ff66a8a2c689664f75d6a0e6 ("mempool/octeontx2: fix possible arm64 ABI break")

Probably we can choose a scheme for rc2 and adjust as when we have complete clarity.

> +	register uint64_t x1 __asm("x1") = (uint64_t)old.val[1];                \
> +	register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0];            \
> +	register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1];            \
> +	asm volatile(                                                           \
> +			op_string " %[old0], %[old1], %[upd0], %[upd1],
> [%[dst]]"       \
> +			: [old0] "+r" (x0),                                             \
> +			  [old1] "+r" (x1)                                              \
> +			: [upd0] "r" (x2),                                              \
> +			  [upd1] "r" (x3),                                              \
> +			  [dst] "r" (dst)                                               \
> +			: "memory");                                                    \

Should n't we add x0,x1, x2, x3 in clobber list?


>  static inline int __rte_experimental
>  rte_atomic128_cmp_exchange(rte_int128_t *dst,
>  			   rte_int128_t *exp,
> diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h
> b/lib/librte_eal/common/include/generic/rte_atomic.h
> index 9958543..2355e50 100644
> --- a/lib/librte_eal/common/include/generic/rte_atomic.h
> +++ b/lib/librte_eal/common/include/generic/rte_atomic.h
> @@ -1081,6 +1081,20 @@ static inline void
> rte_atomic64_clear(rte_atomic64_t *v)
> 
>  /*------------------------ 128 bit atomic operations -------------------------*/
> 
> +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)

There is nothing specific to x86 and arm64 here, Can we remove this #ifdef ?

> +/**
> + * 128-bit integer structure.
> + */
> +RTE_STD_C11
> +typedef struct {
> +	RTE_STD_C11
> +	union {
> +		uint64_t val[2];
> +		__extension__ __int128 int128;
> +	};
> +} __rte_aligned(16) rte_int128_t;
> +#endif
> +
>  #ifdef __DOXYGEN__

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [EXT] [PATCH v5 2/7] cryptodev: add cipher field to RSA op
  @ 2019-07-19  5:10  3%     ` Kusztal, ArkadiuszX
  0 siblings, 0 replies; 200+ results
From: Kusztal, ArkadiuszX @ 2019-07-19  5:10 UTC (permalink / raw)
  To: Shally Verma, dev
  Cc: akhil.goyal, Trahe, Fiona, Nowak, DamianX, Sunila Sahu,
	Ayuj Verma, Kanaka Durga Kotamarthy

> > ----------------------------------------------------------------------
> > Asymmetric nature of RSA algorithm suggest to use additional field for
> > output. In place operations still can be done by setting cipher and
> > message pointers with the same memory address.
> >
> > Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> > ---
> >  lib/librte_cryptodev/rte_crypto_asym.h | 43
> > ++++++++++++++++++++++++++++------
> >  1 file changed, 36 insertions(+), 7 deletions(-)
> >
> > diff --git a/lib/librte_cryptodev/rte_crypto_asym.h
> > b/lib/librte_cryptodev/rte_crypto_asym.h
> > index 02ec304..1d4ec80 100644
> > --- a/lib/librte_cryptodev/rte_crypto_asym.h
> > +++ b/lib/librte_cryptodev/rte_crypto_asym.h
> > @@ -395,21 +395,50 @@ struct rte_crypto_rsa_op_param {
> >
> >  	rte_crypto_param message;
> >  	/**<
> > -	 * Pointer to data
> > +	 * Pointer to input data
> >  	 * - to be encrypted for RSA public encrypt.
> > -	 * - to be decrypted for RSA private decrypt.
> >  	 * - to be signed for RSA sign generation.
> >  	 * - to be authenticated for RSA sign verification.
> > +	 *
> > +	 * Pointer to output data
> > +	 * - for RSA private decrypt.
> > +	 * In this case the underlying array should have been
> > +	 * allocated with enough memory to hold plaintext output
> > +	 * (i.e. must be at least RSA key size). The message.length
> > +	 * field should be 0 and will be overwritten by the PMD
> > +	 * with the decrypted length.
> > +	 *
> > +	 * All data is in Octet-string network byte order format.
> > +	 */
> As per Fiona feedback in another email, for PMD it does not matter what
> output buffer length is set to. All matters if it should be allocated large
> enough as per description in spec.
> Given that, there is no need to mention specifically, that length should be set
> to 0. App can leave it to anything as PMD don't care. It does not and should
> not check for any valid params here.
> Ditto is my feedback on cipher.length description below. There is no need to
> mention, it should be set to 0 specifically
> 
> If we agree, this change can be taken as part of next patch set. Current one
> can still go on.

I agree with Shally that it could be anything to work, but on the other hand I agree with Pablo and Fiona comment on future extensions and ABI breakage. Especially on so early level of API development. When we change this field in future that it can be random (which is possible) it will not break anything, but it would not work in the opposite direction.

> 
> Thanks
> Shally
> 
> 
> 
> > +
> > +	rte_crypto_param cipher;
> > +	/**<
> > +	 * Pointer to input data
> > +	 * - to be decrypted for RSA private decrypt.
> > +	 *
> > +	 * Pointer to output data
> > +	 * - for RSA public encrypt.
> > +	 * In this case the underlying array should have been allocated
> > +	 * with enough memory to hold ciphertext output (i.e. must be
> > +	 * at least RSA key size). The cipher.length field should
> > +	 * be 0 and will be overwritten by the PMD with the encrypted
> > length.
> > +	 *
> > +	 * All data is in Octet-string network byte order format.
> >  	 */
> >
> >  	rte_crypto_param sign;
> >  	/**<
> > -	 * Pointer to RSA signature data. If operation is RSA
> > -	 * sign @ref RTE_CRYPTO_ASYM_OP_SIGN, buffer will be
> > -	 * over-written with generated signature.
> > +	 * Pointer to input data
> > +	 * - to be verified for RSA public decrypt.
> > +	 *
> > +	 * Pointer to output data
> > +	 * - for RSA private encrypt.
> > +	 * In this case the underlying array should have been allocated
> > +	 * with enough memory to hold signature output (i.e. must be
> > +	 * at least RSA key size). The sign.length field should
> > +	 * be 0 and will be overwritten by the PMD with the signature length.
> >  	 *
> > -	 * Length of the signature data will be equal to the
> > -	 * RSA modulus length.
> > +	 * All data is in Octet-string network byte order format.
> >  	 */
> >
> >  	enum rte_crypto_rsa_padding_type pad;
> > --
> > 2.1.0


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2] mempool/octeontx2: fix possible ABI break with force inline
  2019-07-18  8:04  4%   ` Jerin Jacob Kollanukkaran
@ 2019-07-18 22:15  4%     ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-07-18 22:15 UTC (permalink / raw)
  To: Pavan Nikhilesh Bhagavatula
  Cc: dev, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram,
	Vamsi Krishna Attunuru

> > From: Pavan Nikhilesh <pbhagavatula@marvell.com>
> > 
> > Since direct register access is used in npa_lf_aura_op_alloc_bulk() use
> > __rte_noinline instead of __rte_always_inline to preserve ABI.
> > Based on the compiler npa_lf_aura_op_alloc_bulk might be inlined
> > differently which may lead to undefined behaviour due to handcoded asm.
> > 
> > Fixes: 29893042c29d ("mempool/octeontx2: fix clang build for arm64")
> > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> 
> Acked-by: Jerin Jacob <jerinj@marvell.com>

Applied, thanks



^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [EXT] Re: [PATCH] mempool/octeontx2: use noinline to preserve ABI
  2019-07-18 14:43  8% ` [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI Stephen Hemminger
@ 2019-07-18 14:49  7%   ` Pavan Nikhilesh Bhagavatula
  0 siblings, 0 replies; 200+ results
From: Pavan Nikhilesh Bhagavatula @ 2019-07-18 14:49 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram,
	Vamsi Krishna Attunuru, dev



>-----Original Message-----
>From: Stephen Hemminger <stephen@networkplumber.org>
>Sent: Thursday, July 18, 2019 8:13 PM
>To: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>
>Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar
>Dabilpuram <ndabilpuram@marvell.com>; Vamsi Krishna Attunuru
><vattunuru@marvell.com>; dev@dpdk.org
>Subject: [EXT] Re: [dpdk-dev] [PATCH] mempool/octeontx2: use
>noinline to preserve ABI
>
>External Email
>
>----------------------------------------------------------------------
>On Thu, 18 Jul 2019 00:10:13 +0530
><pbhagavatula@marvell.com> wrote:
>
>> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
>>
>> Since direct register access is used in npa_lf_aura_op_alloc_bulk()
>> use __rte_noinline to preserve ABI.
>>
>> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
>
>Huh? this is an internal function, and the driver is new to DPDK.
>We don't maintain ABI with external drivers or code bases.
>And ABI with code before it was upstream doesn't count either.

I was actually referring to arm64 ABI[1]
I think commit message in v2 describes it better http://patches.dpdk.org/patch/56703/

[1] http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf

Regards,
Pavan.

^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI
  2019-07-17 18:40  7% [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI pbhagavatula
  2019-07-18  5:53  4% ` Jerin Jacob Kollanukkaran
  2019-07-18  6:51  7% ` [dpdk-dev] [PATCH v2] mempool/octeontx2: fix possible ABI break with force inline pbhagavatula
@ 2019-07-18 14:43  8% ` Stephen Hemminger
  2019-07-18 14:49  7%   ` [dpdk-dev] [EXT] " Pavan Nikhilesh Bhagavatula
  2 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-07-18 14:43 UTC (permalink / raw)
  To: pbhagavatula; +Cc: jerinj, Nithin Dabilpuram, Vamsi Attunuru, dev

On Thu, 18 Jul 2019 00:10:13 +0530
<pbhagavatula@marvell.com> wrote:

> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
> 
> Since direct register access is used in npa_lf_aura_op_alloc_bulk()
> use __rte_noinline to preserve ABI.
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>

Huh? this is an internal function, and the driver is new to DPDK.
We don't maintain ABI with external drivers or code bases.
And ABI with code before it was upstream doesn't count either.

^ permalink raw reply	[relevance 8%]

* Re: [dpdk-dev] [EXT] [PATCH v3 04/11] test: add cipher field to RSA test
  @ 2019-07-18 12:44  3%         ` Trahe, Fiona
  0 siblings, 0 replies; 200+ results
From: Trahe, Fiona @ 2019-07-18 12:44 UTC (permalink / raw)
  To: Shally Verma, Kusztal, ArkadiuszX, dev; +Cc: akhil.goyal, Trahe, Fiona

Hi Shally, Arek,

> > > >
> > > > > -----Original Message-----
> > > > > From: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> > > > > Sent: Wednesday, July 17, 2019 12:23 AM
> > > > > To: dev@dpdk.org
> > > > > Cc: akhil.goyal@nxp.com; fiona.trahe@intel.com; Shally Verma
> > > > > <shallyv@marvell.com>; Arek Kusztal <arkadiuszx.kusztal@intel.com>
> > > > > Subject: [EXT] [PATCH v3 04/11] test: add cipher field to RSA test
> > > > >
> > > > > External Email
> > > > >
> > > > > ------------------------------------------------------------------
> > > > > --
> > > > > -- This patch adds cipher field to RSA test cases
> > > > >
> > > > > Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> > > > > ---
> > > > >  app/test/test_cryptodev_asym.c | 3 +++
> > > > >  1 file changed, 3 insertions(+)
> > > > >
> > > > > diff --git a/app/test/test_cryptodev_asym.c
> > > > > b/app/test/test_cryptodev_asym.c index 4dee164..8391545 100644
> > > > > --- a/app/test/test_cryptodev_asym.c
> > > > > +++ b/app/test/test_cryptodev_asym.c
> > > > > @@ -164,6 +164,7 @@ queue_ops_rsa_enc_dec(struct
> > > > > rte_cryptodev_asym_session *sess)
> > > > >  	uint8_t dev_id = ts_params->valid_devs[0];
> > > > >  	struct rte_crypto_op *op, *result_op;
> > > > >  	struct rte_crypto_asym_op *asym_op;
> > > > > +	uint8_t cipher_buf[TEST_DATA_SIZE] = {0};
> > > > >  	int ret, status = TEST_SUCCESS;
> > > > >
> > > > >  	/* Set up crypto op data structure */ @@ -180,6 +181,8 @@
> > > > > queue_ops_rsa_enc_dec(struct rte_cryptodev_asym_session *sess)
> > > > >  	asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT;
> > > > >
> > > > >  	asym_op->rsa.message.data = rsaplaintext.data;
> > > > > +	asym_op->rsa.cipher.data = cipher_buf;
> > > > > +	asym_op->rsa.cipher.length = 0;
> > > > [Shally] I think this should be initialized to length of buffer
> > > > available i.e. RSA Key size? PMD can override it with length of
> > > > actual data written at output, which has to be less than , equal to
> > RSA_key size.
> > > [AK] - its because API comments are ambiguous in this case and we have
> > > only one field describing array length.
> > > I would suggest to rephrase cipher field API comments from "length in
> > bytes
> > > 	 * of this field needs to be greater or equal to the length of
> > > 	 * corresponding RSA key in bytes"
> > > To "underlying array should have allocated enough memory to hold
> > > cipher output (bigger or equal to RSA key size". Then length could and
> > > I think should be zero or unspecified at this point.
> > > What do you think?
> >
> > [AK2] Something like that:
> > 	 * When RTE_CRYPTO_ASYM_OP_ENCRYPT op_type used underlying
> > array
> > 	 * should have been allocated with enough memory to hold cipher
> > 	 * output (bigger or equal to RSA key size).
> > The same for message field.
> [Shally] This description is okay. But still I would assume app to set length field of cipher buffer to actual
> allocated than 0. But I look forward to more feedback on this from others
[Fiona] I think the important thing is to be clear on when it's an input field and when an output and what the appl or PMD does in each case.
So my understanding is in ENCRYPT case it's an output field and DECRYPT it's an input.
SO how about - combining this with the changes already suggested to avoid repetition in patch 2:
Comment under rte_crypto_rsa_op_param.message:
Pointer to input data
 	 * - to be encrypted for RSA public encrypt.
 	 * - to be signed for RSA sign generation.
 	 * - to be authenticated for RSA sign verification.
Pointer to output data
               * - for RSA private decrypt.
                     In this case the underlying array should have been allocated with
                     enough memory to hold plaintext output (i.e. must be at least RSA key size).
                     The message.length field should be 0 and will be overwritten by the PMD
                     with the decrypted length.
All data is in Octet-string network byte order format.

Note 1: If API allows a length on decrypt, then what would the PMD use it for? Would it have to handle the case where it's less than key-size? In which case the appl is breaking the API and ignoring the previous comment. Or more than key-size - what does the PMD care - it just needs key-size. IF there was a case where PMD could produce more than keysize and would need to know if the buffer is big enough then we should allow this and say it's both an input (buffer-len) and an output (decrypted-message-len). But I don't think there's such a case. 

Note 2 : it's good practice for apps to zero all fields in all API structs, except those explicitly set, to allow for future API extensions without ABI breakage.

Comment under rte_crypto_rsa_op_param.cipher:
Pointer to input data
 	 * - to be decrypted for RSA private decrypt.
 	 
Pointer to output data
               * - for RSA public encrypt.
                     In this case the underlying array should have been allocated with
                     enough memory to hold ciphertext output (i.e. must be at least RSA key size).
                     The message.length field should be 0 and will be overwritten by the PMD
                     with the encrypted length.
All data is in Octet-string network byte order format.

@Shally - does above make sense?
If so we can update patches 2, 3 and 4 based on above.


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2] mempool/octeontx2: fix possible ABI break with force inline
  2019-07-18  6:51  7% ` [dpdk-dev] [PATCH v2] mempool/octeontx2: fix possible ABI break with force inline pbhagavatula
@ 2019-07-18  8:04  4%   ` Jerin Jacob Kollanukkaran
  2019-07-18 22:15  4%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-07-18  8:04 UTC (permalink / raw)
  To: Pavan Nikhilesh Bhagavatula, Nithin Kumar Dabilpuram,
	Vamsi Krishna Attunuru
  Cc: dev, Pavan Nikhilesh Bhagavatula, thomas

> -----Original Message-----
> From: pbhagavatula@marvell.com <pbhagavatula@marvell.com>
> Sent: Thursday, July 18, 2019 12:21 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar
> Dabilpuram <ndabilpuram@marvell.com>; Vamsi Krishna Attunuru
> <vattunuru@marvell.com>
> Cc: dev@dpdk.org; Pavan Nikhilesh Bhagavatula
> <pbhagavatula@marvell.com>
> Subject: [dpdk-dev][PATCH v2] mempool/octeontx2: fix possible ABI break
> with force inline
> 
> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
> 
> Since direct register access is used in npa_lf_aura_op_alloc_bulk() use
> __rte_noinline instead of __rte_always_inline to preserve ABI.
> Based on the compiler npa_lf_aura_op_alloc_bulk might be inlined
> differently which may lead to undefined behaviour due to handcoded asm.
> 
> Fixes: 29893042c29d ("mempool/octeontx2: fix clang build for arm64")
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>

Acked-by: Jerin Jacob <jerinj@marvell.com>

^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH v2] mempool/octeontx2: fix possible ABI break with force inline
  2019-07-17 18:40  7% [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI pbhagavatula
  2019-07-18  5:53  4% ` Jerin Jacob Kollanukkaran
@ 2019-07-18  6:51  7% ` pbhagavatula
  2019-07-18  8:04  4%   ` Jerin Jacob Kollanukkaran
  2019-07-18 14:43  8% ` [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI Stephen Hemminger
  2 siblings, 1 reply; 200+ results
From: pbhagavatula @ 2019-07-18  6:51 UTC (permalink / raw)
  To: jerinj, Nithin Dabilpuram, Vamsi Attunuru; +Cc: dev, Pavan Nikhilesh

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Since direct register access is used in npa_lf_aura_op_alloc_bulk()
use __rte_noinline instead of __rte_always_inline to preserve ABI.
Based on the compiler npa_lf_aura_op_alloc_bulk might be inlined
differently which may lead to undefined behaviour due to handcoded
asm.

Fixes: 29893042c29d ("mempool/octeontx2: fix clang build for arm64")
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 drivers/mempool/octeontx2/otx2_mempool_ops.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mempool/octeontx2/otx2_mempool_ops.c b/drivers/mempool/octeontx2/otx2_mempool_ops.c
index a60a77a4e..ff63be567 100644
--- a/drivers/mempool/octeontx2/otx2_mempool_ops.c
+++ b/drivers/mempool/octeontx2/otx2_mempool_ops.c
@@ -54,7 +54,7 @@ npa_lf_aura_op_search_alloc(const int64_t wdata, int64_t * const addr,
 	return 0;
 }
 
-static __rte_always_inline int
+static __rte_noinline int
 npa_lf_aura_op_alloc_bulk(const int64_t wdata, int64_t * const addr,
 			  unsigned int n, void **obj_table)
 {
-- 
2.17.1


^ permalink raw reply	[relevance 7%]

* Re: [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI
  2019-07-17 18:40  7% [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI pbhagavatula
@ 2019-07-18  5:53  4% ` Jerin Jacob Kollanukkaran
  2019-07-18  6:51  7% ` [dpdk-dev] [PATCH v2] mempool/octeontx2: fix possible ABI break with force inline pbhagavatula
  2019-07-18 14:43  8% ` [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI Stephen Hemminger
  2 siblings, 0 replies; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-07-18  5:53 UTC (permalink / raw)
  To: Pavan Nikhilesh Bhagavatula, Nithin Kumar Dabilpuram,
	Vamsi Krishna Attunuru
  Cc: dev, Pavan Nikhilesh Bhagavatula

> -----Original Message-----
> From: pbhagavatula@marvell.com <pbhagavatula@marvell.com>
> Sent: Thursday, July 18, 2019 12:10 AM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar
> Dabilpuram <ndabilpuram@marvell.com>; Vamsi Krishna Attunuru
> <vattunuru@marvell.com>
> Cc: dev@dpdk.org; Pavan Nikhilesh Bhagavatula
> <pbhagavatula@marvell.com>
> Subject: [dpdk-dev][PATCH] mempool/octeontx2: use noinline to preserve
> ABI
> 
> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
> 
> Since direct register access is used in npa_lf_aura_op_alloc_bulk() use
> __rte_noinline to preserve ABI.

# Please add Fixes:
# Please mention the current visible issue 
# If possible make git commit starts with fix ...


> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> ---
>  drivers/mempool/octeontx2/otx2_mempool_ops.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mempool/octeontx2/otx2_mempool_ops.c
> b/drivers/mempool/octeontx2/otx2_mempool_ops.c
> index a60a77a4e..ff63be567 100644
> --- a/drivers/mempool/octeontx2/otx2_mempool_ops.c
> +++ b/drivers/mempool/octeontx2/otx2_mempool_ops.c
> @@ -54,7 +54,7 @@ npa_lf_aura_op_search_alloc(const int64_t wdata,
> int64_t * const addr,
>  	return 0;
>  }
> 
> -static __rte_always_inline int
> +static __rte_noinline int
>  npa_lf_aura_op_alloc_bulk(const int64_t wdata, int64_t * const addr,
>  			  unsigned int n, void **obj_table)
>  {
> --
> 2.17.1


^ permalink raw reply	[relevance 4%]

* [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI
@ 2019-07-17 18:40  7% pbhagavatula
  2019-07-18  5:53  4% ` Jerin Jacob Kollanukkaran
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: pbhagavatula @ 2019-07-17 18:40 UTC (permalink / raw)
  To: jerinj, Nithin Dabilpuram, Vamsi Attunuru; +Cc: dev, Pavan Nikhilesh

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Since direct register access is used in npa_lf_aura_op_alloc_bulk()
use __rte_noinline to preserve ABI.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 drivers/mempool/octeontx2/otx2_mempool_ops.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mempool/octeontx2/otx2_mempool_ops.c b/drivers/mempool/octeontx2/otx2_mempool_ops.c
index a60a77a4e..ff63be567 100644
--- a/drivers/mempool/octeontx2/otx2_mempool_ops.c
+++ b/drivers/mempool/octeontx2/otx2_mempool_ops.c
@@ -54,7 +54,7 @@ npa_lf_aura_op_search_alloc(const int64_t wdata, int64_t * const addr,
 	return 0;
 }
 
-static __rte_always_inline int
+static __rte_noinline int
 npa_lf_aura_op_alloc_bulk(const int64_t wdata, int64_t * const addr,
 			  unsigned int n, void **obj_table)
 {
-- 
2.17.1


^ permalink raw reply	[relevance 7%]

* [dpdk-dev] [PATCH v10 0/2] new ring reset api and use it by hash
                     ` (2 preceding siblings ...)
  2019-07-12 15:54  3% ` [dpdk-dev] [PATCH v9 " Gavin Hu
@ 2019-07-16 19:23  3% ` Gavin Hu
  3 siblings, 0 replies; 200+ results
From: Gavin Hu @ 2019-07-16 19:23 UTC (permalink / raw)
  To: dev
  Cc: nd, thomas, jerinj, hemant.agrawal, nipun.gupta,
	Honnappa.Nagarahalli, gavin.hu, olivier.matz

V2:
- fix the coding style issue(commit message line too long)
V3:
- allow experimental API for meson build
V4: 
- include the ring perf test case enhancement patch in the series.
- replace ARRAY_SIZE with RTE_DIM.
- call memset to avoid clang compling complains.
V5:
- commit message tweaking for ring test case enhancement patch
- upper to lower for mails to make match/grep more easily
V6:
- make upper case for the user name to comply with the convention.
V7:
- leave the ring test case patch out as not closely linked to this series in logic
V8:
- the static inline function is removed from the rte_ring_version.map 
V9:
- change the static inline function into a standard function to keep an api/abi compat layer in the future
- add back the change to the rte_ring_version.map file
V10:
- remove the CC: lines as not in the data plane.

Gavin Hu (2):
  ring: add reset API to flush the ring when not in use
  hash: flush the rings instead of dequeuing one by one

 lib/librte_hash/Makefile             |  2 +-
 lib/librte_hash/meson.build          |  3 +++
 lib/librte_hash/rte_cuckoo_hash.c    | 11 ++++-------
 lib/librte_ring/rte_ring.c           |  7 +++++++
 lib/librte_ring/rte_ring.h           | 17 +++++++++++++++++
 lib/librte_ring/rte_ring_version.map |  7 +++++++
 6 files changed, 39 insertions(+), 8 deletions(-)

-- 
2.7.4


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  @ 2019-07-16 14:43  3%         ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-07-16 14:43 UTC (permalink / raw)
  To: Olivier Matz; +Cc: Jerin Jacob Kollanukkaran, dev

On Tue, 16 Jul 2019 11:39:50 +0200
Olivier Matz <olivier.matz@6wind.com> wrote:

> On Fri, Jul 12, 2019 at 12:23:19PM +0000, Jerin Jacob Kollanukkaran wrote:
> > > -----Original Message-----
> > > From: dev <dev-bounces@dpdk.org> On Behalf Of Olivier Matz
> > > Sent: Thursday, July 11, 2019 1:07 PM
> > > To: Stephen Hemminger <stephen@networkplumber.org>
> > > Cc: dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> > > 
> > > On Wed, Jul 10, 2019 at 10:49:17AM -0700, Stephen Hemminger wrote:  
> > > > On Wed, 10 Jul 2019 11:29:07 +0200
> > > > Olivier Matz <olivier.matz@6wind.com> wrote:
> > > >  
> > > > >  /**
> > > > >   * Indicate that the metadata field in the mbuf is in use.
> > > > > @@ -738,6 +741,8 @@ struct rte_mbuf {
> > > > >  	 */
> > > > >  	struct rte_mbuf_ext_shared_info *shinfo;
> > > > >
> > > > > +	uint64_t dynfield1; /**< Reserved for dynamic fields. */
> > > > > +	uint64_t dynfield2; /**< Reserved for dynamic fields. */  
> > 
> > Since the mbuf size is fixed, What is the downside of union scheme[1] vs upside of proposed scheme
> > 
> > [1] Example like:
> >         RTE_STD_C11
> >         union {
> >                 void *userdata;   /**< Can be used for external metadata */
> >                 uint64_t udata64; /**< Allow 8-byte userdata on 32-bit */
> >         };  
> 
> In the particular case of userdata, the union is not an issue, it
> just means that there are several ways to represent the same data.
> If needed, it is possible to register a union as a dynamic field.
> 
> In other case, like m->hash, having a union makes it impossible to
> use several features of the union at the same time. This would be
> solved by dynamic fields.
> 
> > # The fields like mbuf: hash.usr, used in variety  of use case together
> > Like libraries like distributor() and Eventdev using it. If we switch
> > to dynamic mbuf scheme, We wil take those field using rte_mbuf_dynfield_register()
> > on library init?  
> 
> If we decide that these fields must be converted to a dynamic field,
> yes, each library/application will call rte_mbuf_dynfield_register().
> 
> > # I see an upside of dynamic mbuf if we can add rte_mbuf_dynfield_unregister API.
> > But can we ever do that? Because it will be complex if we need introduce notification mechanism etc.  
> 
> An unregister mechanism seems hard to implement, or we can leave the
> hard part to the user: either ensure that no mbuf is in use anywhere, or
> that removing the dynamic field won't have any impact. But I'd prefer
> not introducing an unregistration function until we have a real use-case
> for it.
> 
> > # In the real world use case, if with union scheme, fastpath API can simply deference 
> > specific element (say mbuf->fieldx). With dynamic scheme, the offset need to store
> > in some other data structure  and de reference in fastpath before assessing the interested field.
> > Right?  
> 
> Yes, with dynamic fields, the offset is stored in a variable. A global
> variable (static to the file or module using it) does the job. This may
> have a small performance impact.
> 

Applications are already using userdata reusing that in a driver
would cause a worse disaster than breaking ABI.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] ***Spam*** Re: [RFC] mbuf: support dynamic fields and flags
  2019-07-16  9:49  0%   ` Olivier Matz
@ 2019-07-16 11:31  0%     ` Andrew Rybchenko
  0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-07-16 11:31 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

On 7/16/19 12:49 PM, Olivier Matz wrote:
> On Fri, Jul 12, 2019 at 05:54:57PM +0300, Andrew Rybchenko wrote:
>> On 10.07.2019 12:29, Olivier Matz wrote:
>>> Many features require to store data inside the mbuf. As the room in mbuf
>>> structure is limited, it is not possible to have a field for each
>>> feature. Also, changing fields in the mbuf structure can break the API
>>> or ABI.
>>>
>>> This commit addresses these issues, by enabling the dynamic registration
>>> of fields or flags:
>>>
>>> - a dynamic field is a named area in the rte_mbuf structure, with a
>>>     given size (>= 1 byte) and alignment constraint.
>>> - a dynamic flag is a named bit in the rte_mbuf structure.
>>>
>>> The typical use case is a PMD that registers space for an offload
>>> feature, when the application requests to enable this feature.  As
>>> the space in mbuf is limited, the space should only be reserved if it
>>> is going to be used (i.e when the application explicitly asks for it).
>>>
>>> The registration can be done at any moment, but it is not possible
>>> to unregister fields or flags for now.
>>>
>>> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
>> I like the idea.
>>
>> I think it would be very useful to measure performance impact. Since it is
>> core structure which is heavily used on datapath, performance impact is
>> required to make decision to go or not to go. If acceptable, more fields
>> can be converted to dynamic: timestamp, user data, sequence number,
>> timesync data etc.
> Agree. I'll try to do this in the coming days.
>
>> Rules on which fields should be static and which
>> dynamic are required. Timestamp, for example, is located in the first
>> cache line. Do we need a way prioritize some dynamic fields to be located
>> (if possible) in the first cache line? Or is it better simply move some
>> static
>> to the first cache line instead?
> There is a "flags" argument, which is designed for this purpose. Today,
> there is no room in the first cache line, but as soon as we remove
> something from it, we can add a flag to ask to register a dynamic field
> in the first cache line.
>
>> I think rules should be better defined and imposed, if possible, when
>> dynamic fields may be registered. Which entities are allowed to register
>> dynamic fields?
> I think there is no restriction. Library, PMD, App can register their
> dynamic fields as soon as there is room for it.

I see that API itself has no restrictions, but the goal is to have
something working and it is very easy to break things with
dynamic fields and flags. May be obvious requirements are
sufficient (e.g. should be registered before lookup to be found
by lookup), but it is getting more complicated when drivers,
core libraries and applications come into play with their life
cycles. But may be it is really out-of-scope of the API description.

Thanks.


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-12 14:54  0% ` Andrew Rybchenko
@ 2019-07-16  9:49  0%   ` Olivier Matz
  2019-07-16 11:31  0%     ` [dpdk-dev] ***Spam*** " Andrew Rybchenko
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-07-16  9:49 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev

On Fri, Jul 12, 2019 at 05:54:57PM +0300, Andrew Rybchenko wrote:
> On 10.07.2019 12:29, Olivier Matz wrote:
> > Many features require to store data inside the mbuf. As the room in mbuf
> > structure is limited, it is not possible to have a field for each
> > feature. Also, changing fields in the mbuf structure can break the API
> > or ABI.
> > 
> > This commit addresses these issues, by enabling the dynamic registration
> > of fields or flags:
> > 
> > - a dynamic field is a named area in the rte_mbuf structure, with a
> >    given size (>= 1 byte) and alignment constraint.
> > - a dynamic flag is a named bit in the rte_mbuf structure.
> > 
> > The typical use case is a PMD that registers space for an offload
> > feature, when the application requests to enable this feature.  As
> > the space in mbuf is limited, the space should only be reserved if it
> > is going to be used (i.e when the application explicitly asks for it).
> > 
> > The registration can be done at any moment, but it is not possible
> > to unregister fields or flags for now.
> > 
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> 
> I like the idea.
> 
> I think it would be very useful to measure performance impact. Since it is
> core structure which is heavily used on datapath, performance impact is
> required to make decision to go or not to go. If acceptable, more fields
> can be converted to dynamic: timestamp, user data, sequence number,
> timesync data etc.

Agree. I'll try to do this in the coming days.

> Rules on which fields should be static and which
> dynamic are required. Timestamp, for example, is located in the first
> cache line. Do we need a way prioritize some dynamic fields to be located
> (if possible) in the first cache line? Or is it better simply move some
> static
> to the first cache line instead?

There is a "flags" argument, which is designed for this purpose. Today,
there is no room in the first cache line, but as soon as we remove
something from it, we can add a flag to ask to register a dynamic field
in the first cache line.

> I think rules should be better defined and imposed, if possible, when
> dynamic fields may be registered. Which entities are allowed to register
> dynamic fields?

I think there is no restriction. Library, PMD, App can register their
dynamic fields as soon as there is room for it.

> Do we need to keep track which entity has registered
> which dynamic fields?

Looks quite difficult to me. Most of the time, a dynamic field will be
registered at several places. Only the first registration is effective,
the other will just get the offset.

But at least we could add a log in the registration function.

> What to expect if a dynamic field is registered
> after port start (the field is registered, but most likely not filled in)?
> What to expect on port restart?

Registration of dynamic field can be done at any moment.

But to register a field that will be used by a PMD, we need to ask for
the feature at port configuration (usually through ethdev). Then the PMD
will register the dynamic field. If it fails, the configuration of the
port should fail.

The application that will access to the field will also register it. It
can be done before or after the PMD initialization.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] ethdev: extend flow metadata
  2019-07-11  7:44  0%         ` Adrien Mazarguil
@ 2019-07-14 11:46  0%           ` Andrew Rybchenko
  2019-07-29 15:06  0%             ` Adrien Mazarguil
  0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-07-14 11:46 UTC (permalink / raw)
  To: Adrien Mazarguil, Yongseok Koh
  Cc: Thomas Monjalon, Olivier Matz, Bruce Richardson, Shahaf Shuler,
	Ferruh Yigit, dev, Slava Ovsiienko

On 11.07.2019 10:44, Adrien Mazarguil wrote:
> On Wed, Jul 10, 2019 at 04:37:46PM +0000, Yongseok Koh wrote:
>>> On Jul 10, 2019, at 5:26 AM, Thomas Monjalon <thomas@monjalon.net> wrote:
>>>
>>> 10/07/2019 14:01, Bruce Richardson:
>>>> On Wed, Jul 10, 2019 at 12:07:43PM +0200, Olivier Matz wrote:
>>>>> On Wed, Jul 10, 2019 at 10:55:34AM +0100, Bruce Richardson wrote:
>>>>>> On Wed, Jul 10, 2019 at 11:31:56AM +0200, Olivier Matz wrote:
>>>>>>> On Thu, Jul 04, 2019 at 04:21:22PM -0700, Yongseok Koh wrote:
>>>>>>>> Currently, metadata can be set on egress path via mbuf tx_meatadata field
>>>>>>>> with PKT_TX_METADATA flag and RTE_FLOW_ITEM_TYPE_RX_META matches metadata.
>>>>>>>>
>>>>>>>> This patch extends the usability.
>>>>>>>>
>>>>>>>> 1) RTE_FLOW_ACTION_TYPE_SET_META
>>>>>>>>
>>>>>>>> When supporting multiple tables, Tx metadata can also be set by a rule and
>>>>>>>> matched by another rule. This new action allows metadata to be set as a
>>>>>>>> result of flow match.
>>>>>>>>
>>>>>>>> 2) Metadata on ingress
>>>>>>>>
>>>>>>>> There's also need to support metadata on packet Rx. Metadata can be set by
>>>>>>>> SET_META action and matched by META item like Tx. The final value set by
>>>>>>>> the action will be delivered to application via mbuf metadata field with
>>>>>>>> PKT_RX_METADATA ol_flag.
>>>>>>>>
>>>>>>>> For this purpose, mbuf->tx_metadata is moved as a separate new field and
>>>>>>>> renamed to 'metadata' to support both Rx and Tx metadata.
>>>>>>>>
>>>>>>>> For loopback/hairpin packet, metadata set on Rx/Tx may or may not be
>>>>>>>> propagated to the other path depending on HW capability.
>>>>>>>>
>>>>>>>> Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
>>>>>>>> --- a/lib/librte_mbuf/rte_mbuf.h
>>>>>>>> +++ b/lib/librte_mbuf/rte_mbuf.h
>>>>>>>> @@ -648,17 +653,6 @@ struct rte_mbuf {
>>>>>>>> 			/**< User defined tags. See rte_distributor_process() */
>>>>>>>> 			uint32_t usr;
>>>>>>>> 		} hash;                   /**< hash information */
>>>>>>>> -		struct {
>>>>>>>> -			/**
>>>>>>>> -			 * Application specific metadata value
>>>>>>>> -			 * for egress flow rule match.
>>>>>>>> -			 * Valid if PKT_TX_METADATA is set.
>>>>>>>> -			 * Located here to allow conjunct use
>>>>>>>> -			 * with hash.sched.hi.
>>>>>>>> -			 */
>>>>>>>> -			uint32_t tx_metadata;
>>>>>>>> -			uint32_t reserved;
>>>>>>>> -		};
>>>>>>>> 	};
>>>>>>>>
>>>>>>>> 	/** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ is set. */
>>>>>>>> @@ -727,6 +721,11 @@ struct rte_mbuf {
>>>>>>>> 	 */
>>>>>>>> 	struct rte_mbuf_ext_shared_info *shinfo;
>>>>>>>>
>>>>>>>> +	/** Application specific metadata value for flow rule match.
>>>>>>>> +	 * Valid if PKT_RX_METADATA or PKT_TX_METADATA is set.
>>>>>>>> +	 */
>>>>>>>> +	uint32_t metadata;
>>>>>>>> +
>>>>>>>> } __rte_cache_aligned;
>>>>>>> This will break the ABI, so we cannot put it in 19.08, and we need a
>>>>>>> deprecation notice.
>>>>>>>
>>>>>> Does it actually break the ABI? Adding a new field to the mbuf should only
>>>>>> break the ABI if it either causes new fields to move or changes the
>>>>>> structure size. Since this is at the end, it's not going to move any older
>>>>>> fields, and since everything is cache-aligned I don't think the structure
>>>>>> size changes either.
>>>>> I think it does break the ABI: in previous version, when the PKT_TX_METADATA
>>>>> flag is set, the associated value is put in m->tx_metadata (offset 44 on
>>>>> x86-64), and in the next version, it will be in m->metadata (offset 112). So,
>>>>> these 2 versions are not binary compatible.
>>>>>
>>>>> Anyway, at least it breaks the API.
>>>> Ok, I misunderstood. I thought it was the structure change itself you were
>>>> saying broke the ABI. Yes, putting the data in a different place is indeed
>>>> an ABI break.
>>> We could add the new field and keep the old one unused,
>>> so it does not break the ABI.
>> Still breaks ABI if PKT_TX_METADATA is set. :-) In order not to break it, I can
>> keep the current union'd field (tx_metadata) as is with PKT_TX_METADATA, add
>> the new one at the end and make it used with the new PKT_RX_METADATA.
>>
>>> However I suppose everybody will prefer a version using dynamic fields.
>>> Is someone against using dynamic field for such usage?
>> However, given that the amazing dynamic fields is coming soon (thanks for your
>> effort, Olivier and Thomas!), I'd be honored to be the first user of it.
>>
>> Olivier, I'll take a look at your RFC.
> Just got a crazy idea while reading this thread... How about repurposing
> that "reserved" field as "rx_metadata" in the meantime?

It overlaps with hash.fdir.hi which has RSS hash.

> I know reserved fields are cursed and no one's ever supposed to touch them
> but this risk is mitigated by having the end user explicitly request its
> use, so the patch author (and his relatives) should be safe from the
> resulting bad juju.
>
> Joke aside, while I like the idea of Tx/Rx META, I think the similarities
> with MARK (and TAG eventually) is a problem. I wasn't available and couldn't
> comment when META was originally added to the Tx path, but there's a lot of
> overlap between these items/actions, without anything explaining to the end
> user how and why they should pick one over the other, if they can be
> combined at all and what happens in that case.
>
> All this must be documented, then we should think about unifying their
> respective features and deprecate the less capable items/actions. In my
> opinion, users need exactly one method to mark/match some mark while
> processing Rx/Tx traffic and *optionally* have that mark read from/written
> to the mbuf, which may or may not be possible depending on HW features.
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring when not in use
  2019-07-12 15:40  0%                 ` Honnappa Nagarahalli
@ 2019-07-12 16:01  0%                   ` Gavin Hu (Arm Technology China)
  0 siblings, 0 replies; 200+ results
From: Gavin Hu (Arm Technology China) @ 2019-07-12 16:01 UTC (permalink / raw)
  To: Honnappa Nagarahalli, Olivier Matz
  Cc: thomas, dev, nd, jerinj, hemant.agrawal, Nipun.gupta@nxp.com,
	i.maximets, stable, Ruifeng Wang (Arm Technology China),
	nd

> -----Original Message-----
> From: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>
> Sent: Friday, July 12, 2019 11:41 PM
> To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>; Olivier Matz
> <olivier.matz@6wind.com>
> Cc: thomas@monjalon.net; dev@dpdk.org; nd <nd@arm.com>;
> jerinj@marvell.com; hemant.agrawal@nxp.com; Nipun.gupta@nxp.com;
> i.maximets@samsung.com; stable@dpdk.org; Ruifeng Wang (Arm
> Technology China) <Ruifeng.Wang@arm.com>; nd <nd@arm.com>
> Subject: RE: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring
> when not in use
> 
> <snip>
> 
> > > > > > >
> > > > > > > 29/03/2019 15:17, Olivier Matz:
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > On Fri, Mar 15, 2019 at 11:31:25AM +0800, Gavin Hu wrote:
> > > > > > > > > Currently, the flush is done by dequeuing the ring in a while
> loop.
> > > It is
> > > > > > > > > much simpler to flush the queue by resetting the head and
> > > > > > > > > tail
> > > indices.
> > > > > > > > >
> > > > > > > > > Fixes: af75078fece3 ("first public release")
> > > > > > > > > Cc: stable@dpdk.org
> > > > > > > > >
> > > > > > > > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > > > > > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > > > > > > Reviewed-by: Honnappa Nagarahalli
> > > <honnappa.nagarahalli@arm.com>
> > > > > > > > > ---
> > > > > > > > > --- a/lib/librte_ring/rte_ring_version.map
> > > > > > > > > +++ b/lib/librte_ring/rte_ring_version.map
> > > > > > > > > @@ -17,3 +17,10 @@ DPDK_2.2 {
> > > > > > > > >  	rte_ring_free;
> > > > > > > > >
> > > > > > > > >  } DPDK_2.0;
> > > > > > > > > +
> > > > > > > > > +EXPERIMENTAL {
> > > > > > > > > +    global:
> > > > > > > > > +
> > > > > > > > > +	rte_ring_reset;
> > > > > > > > > +
> > > > > > > > > +};
> > > > > > > >
> > > > > > > > To me, a static inline function does not need to be added in
> > > > > > > > rte_ring_version.map (or is it due to a check script
> > > > > > > > checking the __rte_experimental tag ?). I found at least one
> > > > > > > > commit where it is not the case:
> > > > > > > > c277b34c1b3b ("mbuf: add function returning buffer address")
> > > > > > > >
> > > > > > > > There are 2 options:
> > > > > > > > 1- remove the rte_ring_version.map part of the patch.
> > > > > > > > 2- change the static inline function into a standard function.
> > > > > > > >
> > > > > > > > I would prefer 2-, because it allows to keep an api/abi
> > > > > > > > compat layer in the future.
> > > > > > >
> > > > > > > There are no news about this patch.
> > > > > > > I classify it as changes requested.
> > > > > > >
> > > > > > Sorry for missed your comments for long time, I just submitted v8.
> > > > > > I took the first option as it is in the data path and to keep
> > > > > > consistent to
> > > its
> > > > > neighboring functions.
> > > > >
> > > > > Could you give a little more context about why you need to reset
> > > > > the ring in the data path? I see that it is used in
> > > > > rte_hash_reset(), but in my thinking, this was more used at init/exit.
> > > > Sorry,literally it is in the control path, but I was impressed it
> > > > will impact
> > > the
> > > > Data path performance when discussing this patch with Honnappa.
> > >
> > > I'm asking this because given the recent discussions about ABI
> > > stability, I'd like to avoid defining a new static inline if it is not required.
> >
> > Ok, will take 2nd option in V9, and squash the two patches into one,
> otherwise
> > it reports the following error:
> > "error: ‘rte_ring_reset’ defined but not used [-Werror=unused-function]"
> Agree, it is a control path function, does not impact any data path
> performance. It should not be inline.
Thanks for your clarification, I submitted v9 for this.

^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v9 0/2] new ring reset api and use it by hash
      2019-07-12  9:26  3% ` [dpdk-dev] [PATCH v8 0/2] new ring reset api and use it by hash Gavin Hu
@ 2019-07-12 15:54  3% ` Gavin Hu
  2019-07-16 19:23  3% ` [dpdk-dev] [PATCH v10 " Gavin Hu
  3 siblings, 0 replies; 200+ results
From: Gavin Hu @ 2019-07-12 15:54 UTC (permalink / raw)
  To: dev
  Cc: nd, thomas, jerinj, hemant.agrawal, nipun.gupta,
	Honnappa.Nagarahalli, gavin.hu, i.maximets, olivier.matz

V2:
- fix the coding style issue(commit message line too long)
V3:
- allow experimental API for meson build
V4: 
- include the ring perf test case enhancement patch in the series.
- replace ARRAY_SIZE with RTE_DIM.
- call memset to avoid clang compling complains.
V5:
- commit message tweaking for ring test case enhancement patch
- upper to lower for mails to make match/grep more easily
V6:
- make upper case for the user name to comply with the convention.
V7:
- leave the ring test case patch out as not closely linked to this series in logic
V8:
- the static inline function is removed from the rte_ring_version.map 
V9:
- change the static inline function into a standard function to keep an api/abi compat layer in the future
- add back the change to the rte_ring_version.map file

Gavin Hu (2):
  ring: add reset API to flush the ring when not in use
  hash: flush the rings instead of dequeuing one by one

 lib/librte_hash/Makefile             |  2 +-
 lib/librte_hash/meson.build          |  3 +++
 lib/librte_hash/rte_cuckoo_hash.c    | 11 ++++-------
 lib/librte_ring/rte_ring.c           |  7 +++++++
 lib/librte_ring/rte_ring.h           | 17 +++++++++++++++++
 lib/librte_ring/rte_ring_version.map |  7 +++++++
 6 files changed, 39 insertions(+), 8 deletions(-)

-- 
2.7.4


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring when not in use
  2019-07-12 15:07  0%               ` Gavin Hu (Arm Technology China)
@ 2019-07-12 15:40  0%                 ` Honnappa Nagarahalli
  2019-07-12 16:01  0%                   ` Gavin Hu (Arm Technology China)
  0 siblings, 1 reply; 200+ results
From: Honnappa Nagarahalli @ 2019-07-12 15:40 UTC (permalink / raw)
  To: Gavin Hu (Arm Technology China), Olivier Matz
  Cc: thomas, dev, nd, jerinj, hemant.agrawal, Nipun.gupta@nxp.com,
	i.maximets, stable, Ruifeng Wang (Arm Technology China),
	nd

<snip>

> > > > > >
> > > > > > 29/03/2019 15:17, Olivier Matz:
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Fri, Mar 15, 2019 at 11:31:25AM +0800, Gavin Hu wrote:
> > > > > > > > Currently, the flush is done by dequeuing the ring in a while loop.
> > It is
> > > > > > > > much simpler to flush the queue by resetting the head and
> > > > > > > > tail
> > indices.
> > > > > > > >
> > > > > > > > Fixes: af75078fece3 ("first public release")
> > > > > > > > Cc: stable@dpdk.org
> > > > > > > >
> > > > > > > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > > > > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > > > > > Reviewed-by: Honnappa Nagarahalli
> > <honnappa.nagarahalli@arm.com>
> > > > > > > > ---
> > > > > > > > --- a/lib/librte_ring/rte_ring_version.map
> > > > > > > > +++ b/lib/librte_ring/rte_ring_version.map
> > > > > > > > @@ -17,3 +17,10 @@ DPDK_2.2 {
> > > > > > > >  	rte_ring_free;
> > > > > > > >
> > > > > > > >  } DPDK_2.0;
> > > > > > > > +
> > > > > > > > +EXPERIMENTAL {
> > > > > > > > +    global:
> > > > > > > > +
> > > > > > > > +	rte_ring_reset;
> > > > > > > > +
> > > > > > > > +};
> > > > > > >
> > > > > > > To me, a static inline function does not need to be added in
> > > > > > > rte_ring_version.map (or is it due to a check script
> > > > > > > checking the __rte_experimental tag ?). I found at least one
> > > > > > > commit where it is not the case:
> > > > > > > c277b34c1b3b ("mbuf: add function returning buffer address")
> > > > > > >
> > > > > > > There are 2 options:
> > > > > > > 1- remove the rte_ring_version.map part of the patch.
> > > > > > > 2- change the static inline function into a standard function.
> > > > > > >
> > > > > > > I would prefer 2-, because it allows to keep an api/abi
> > > > > > > compat layer in the future.
> > > > > >
> > > > > > There are no news about this patch.
> > > > > > I classify it as changes requested.
> > > > > >
> > > > > Sorry for missed your comments for long time, I just submitted v8.
> > > > > I took the first option as it is in the data path and to keep
> > > > > consistent to
> > its
> > > > neighboring functions.
> > > >
> > > > Could you give a little more context about why you need to reset
> > > > the ring in the data path? I see that it is used in
> > > > rte_hash_reset(), but in my thinking, this was more used at init/exit.
> > > Sorry,literally it is in the control path, but I was impressed it
> > > will impact
> > the
> > > Data path performance when discussing this patch with Honnappa.
> >
> > I'm asking this because given the recent discussions about ABI
> > stability, I'd like to avoid defining a new static inline if it is not required.
> 
> Ok, will take 2nd option in V9, and squash the two patches into one, otherwise
> it reports the following error:
> "error: ‘rte_ring_reset’ defined but not used [-Werror=unused-function]"
Agree, it is a control path function, does not impact any data path performance. It should not be inline.

> 
> Best regards,
> Gavin

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring when not in use
  2019-07-12 11:48  3%             ` Olivier Matz
@ 2019-07-12 15:07  0%               ` Gavin Hu (Arm Technology China)
  2019-07-12 15:40  0%                 ` Honnappa Nagarahalli
  0 siblings, 1 reply; 200+ results
From: Gavin Hu (Arm Technology China) @ 2019-07-12 15:07 UTC (permalink / raw)
  To: Olivier Matz
  Cc: thomas, dev, nd, jerinj, hemant.agrawal, Nipun.gupta@nxp.com,
	Honnappa Nagarahalli, i.maximets, stable,
	Ruifeng Wang (Arm Technology China)

Hi Olivier,

> -----Original Message-----
> From: Olivier Matz <olivier.matz@6wind.com>
> Sent: Friday, July 12, 2019 7:49 PM
> To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> Cc: thomas@monjalon.net; dev@dpdk.org; nd <nd@arm.com>;
> jerinj@marvell.com; hemant.agrawal@nxp.com; Nipun.gupta@nxp.com;
> Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>;
> i.maximets@samsung.com; stable@dpdk.org; Ruifeng Wang (Arm
> Technology China) <Ruifeng.Wang@arm.com>
> Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring
> when not in use
> 
> Hi Gavin,
> 
> On Fri, Jul 12, 2019 at 11:06:28AM +0000, Gavin Hu (Arm Technology China)
> wrote:
> > Hi Olivier,
> >
> > > -----Original Message-----
> > > From: Olivier Matz <olivier.matz@6wind.com>
> > > Sent: Friday, July 12, 2019 5:54 PM
> > > To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> > > Cc: thomas@monjalon.net; dev@dpdk.org; nd <nd@arm.com>;
> > > jerinj@marvell.com; hemant.agrawal@nxp.com; Nipun.gupta@nxp.com;
> > > Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>;
> > > i.maximets@samsung.com; stable@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the
> ring
> > > when not in use
> > >
> > > Hi Gavin,
> > >
> > > On Fri, Jul 12, 2019 at 09:32:39AM +0000, Gavin Hu (Arm Technology
> China)
> > > wrote:
> > > > Hi Olivier and Thomas,
> > > >
> > > > > -----Original Message-----
> > > > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > > Sent: Thursday, July 4, 2019 10:42 PM
> > > > > To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> > > > > Cc: dev@dpdk.org; Olivier Matz <olivier.matz@6wind.com>; nd
> > > > > <nd@arm.com>; jerinj@marvell.com; hemant.agrawal@nxp.com;
> > > > > Nipun.gupta@nxp.com; Honnappa Nagarahalli
> > > > > <Honnappa.Nagarahalli@arm.com>; i.maximets@samsung.com;
> > > > > stable@dpdk.org
> > > > > Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush
> the ring
> > > > > when not in use
> > > > >
> > > > > 29/03/2019 15:17, Olivier Matz:
> > > > > > Hi,
> > > > > >
> > > > > > On Fri, Mar 15, 2019 at 11:31:25AM +0800, Gavin Hu wrote:
> > > > > > > Currently, the flush is done by dequeuing the ring in a while loop.
> It is
> > > > > > > much simpler to flush the queue by resetting the head and tail
> indices.
> > > > > > >
> > > > > > > Fixes: af75078fece3 ("first public release")
> > > > > > > Cc: stable@dpdk.org
> > > > > > >
> > > > > > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > > > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > > > > Reviewed-by: Honnappa Nagarahalli
> <honnappa.nagarahalli@arm.com>
> > > > > > > ---
> > > > > > > --- a/lib/librte_ring/rte_ring_version.map
> > > > > > > +++ b/lib/librte_ring/rte_ring_version.map
> > > > > > > @@ -17,3 +17,10 @@ DPDK_2.2 {
> > > > > > >  	rte_ring_free;
> > > > > > >
> > > > > > >  } DPDK_2.0;
> > > > > > > +
> > > > > > > +EXPERIMENTAL {
> > > > > > > +    global:
> > > > > > > +
> > > > > > > +	rte_ring_reset;
> > > > > > > +
> > > > > > > +};
> > > > > >
> > > > > > To me, a static inline function does not need to be added in
> > > > > > rte_ring_version.map (or is it due to a check script checking the
> > > > > > __rte_experimental tag ?). I found at least one commit where it
> > > > > > is not the case:
> > > > > > c277b34c1b3b ("mbuf: add function returning buffer address")
> > > > > >
> > > > > > There are 2 options:
> > > > > > 1- remove the rte_ring_version.map part of the patch.
> > > > > > 2- change the static inline function into a standard function.
> > > > > >
> > > > > > I would prefer 2-, because it allows to keep an api/abi compat
> > > > > > layer in the future.
> > > > >
> > > > > There are no news about this patch.
> > > > > I classify it as changes requested.
> > > > >
> > > > Sorry for missed your comments for long time, I just submitted v8.
> > > > I took the first option as it is in the data path and to keep consistent to
> its
> > > neighboring functions.
> > >
> > > Could you give a little more context about why you need to reset
> > > the ring in the data path? I see that it is used in rte_hash_reset(),
> > > but in my thinking, this was more used at init/exit.
> > Sorry,literally it is in the control path, but I was impressed it will impact
> the
> > Data path performance when discussing this patch with Honnappa.
> 
> I'm asking this because given the recent discussions about ABI stability,
> I'd like to avoid defining a new static inline if it is not required.

Ok, will take 2nd option in V9, and squash the two patches into one, otherwise it reports the following error:
"error: ‘rte_ring_reset’ defined but not used [-Werror=unused-function]"

Best regards,
Gavin

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
                     ` (2 preceding siblings ...)
  2019-07-11  9:24  3% ` Thomas Monjalon
@ 2019-07-12 14:54  0% ` Andrew Rybchenko
  2019-07-16  9:49  0%   ` Olivier Matz
  3 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2019-07-12 14:54 UTC (permalink / raw)
  To: Olivier Matz, dev

On 10.07.2019 12:29, Olivier Matz wrote:
> Many features require to store data inside the mbuf. As the room in mbuf
> structure is limited, it is not possible to have a field for each
> feature. Also, changing fields in the mbuf structure can break the API
> or ABI.
>
> This commit addresses these issues, by enabling the dynamic registration
> of fields or flags:
>
> - a dynamic field is a named area in the rte_mbuf structure, with a
>    given size (>= 1 byte) and alignment constraint.
> - a dynamic flag is a named bit in the rte_mbuf structure.
>
> The typical use case is a PMD that registers space for an offload
> feature, when the application requests to enable this feature.  As
> the space in mbuf is limited, the space should only be reserved if it
> is going to be used (i.e when the application explicitly asks for it).
>
> The registration can be done at any moment, but it is not possible
> to unregister fields or flags for now.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

I like the idea.

I think it would be very useful to measure performance impact. Since it is
core structure which is heavily used on datapath, performance impact is
required to make decision to go or not to go. If acceptable, more fields
can be converted to dynamic: timestamp, user data, sequence number,
timesync data etc. Rules on which fields should be static and which
dynamic are required. Timestamp, for example, is located in the first
cache line. Do we need a way prioritize some dynamic fields to be located
(if possible) in the first cache line? Or is it better simply move some 
static
to the first cache line instead?

I think rules should be better defined and imposed, if possible, when
dynamic fields may be registered. Which entities are allowed to register
dynamic fields? Do we need to keep track which entity has registered
which dynamic fields? What to expect if a dynamic field is registered
after port start (the field is registered, but most likely not filled in)?
What to expect on port restart?


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring when not in use
  2019-07-12 11:06  0%           ` Gavin Hu (Arm Technology China)
@ 2019-07-12 11:48  3%             ` Olivier Matz
  2019-07-12 15:07  0%               ` Gavin Hu (Arm Technology China)
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-07-12 11:48 UTC (permalink / raw)
  To: Gavin Hu (Arm Technology China)
  Cc: thomas, dev, nd, jerinj, hemant.agrawal, Nipun.gupta@nxp.com,
	Honnappa Nagarahalli, i.maximets, stable,
	Ruifeng Wang (Arm Technology China)

Hi Gavin,

On Fri, Jul 12, 2019 at 11:06:28AM +0000, Gavin Hu (Arm Technology China) wrote:
> Hi Olivier,
> 
> > -----Original Message-----
> > From: Olivier Matz <olivier.matz@6wind.com>
> > Sent: Friday, July 12, 2019 5:54 PM
> > To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> > Cc: thomas@monjalon.net; dev@dpdk.org; nd <nd@arm.com>;
> > jerinj@marvell.com; hemant.agrawal@nxp.com; Nipun.gupta@nxp.com;
> > Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>;
> > i.maximets@samsung.com; stable@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring
> > when not in use
> > 
> > Hi Gavin,
> > 
> > On Fri, Jul 12, 2019 at 09:32:39AM +0000, Gavin Hu (Arm Technology China)
> > wrote:
> > > Hi Olivier and Thomas,
> > >
> > > > -----Original Message-----
> > > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > Sent: Thursday, July 4, 2019 10:42 PM
> > > > To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> > > > Cc: dev@dpdk.org; Olivier Matz <olivier.matz@6wind.com>; nd
> > > > <nd@arm.com>; jerinj@marvell.com; hemant.agrawal@nxp.com;
> > > > Nipun.gupta@nxp.com; Honnappa Nagarahalli
> > > > <Honnappa.Nagarahalli@arm.com>; i.maximets@samsung.com;
> > > > stable@dpdk.org
> > > > Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring
> > > > when not in use
> > > >
> > > > 29/03/2019 15:17, Olivier Matz:
> > > > > Hi,
> > > > >
> > > > > On Fri, Mar 15, 2019 at 11:31:25AM +0800, Gavin Hu wrote:
> > > > > > Currently, the flush is done by dequeuing the ring in a while loop. It is
> > > > > > much simpler to flush the queue by resetting the head and tail indices.
> > > > > >
> > > > > > Fixes: af75078fece3 ("first public release")
> > > > > > Cc: stable@dpdk.org
> > > > > >
> > > > > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > > > Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > > > > ---
> > > > > > --- a/lib/librte_ring/rte_ring_version.map
> > > > > > +++ b/lib/librte_ring/rte_ring_version.map
> > > > > > @@ -17,3 +17,10 @@ DPDK_2.2 {
> > > > > >  	rte_ring_free;
> > > > > >
> > > > > >  } DPDK_2.0;
> > > > > > +
> > > > > > +EXPERIMENTAL {
> > > > > > +    global:
> > > > > > +
> > > > > > +	rte_ring_reset;
> > > > > > +
> > > > > > +};
> > > > >
> > > > > To me, a static inline function does not need to be added in
> > > > > rte_ring_version.map (or is it due to a check script checking the
> > > > > __rte_experimental tag ?). I found at least one commit where it
> > > > > is not the case:
> > > > > c277b34c1b3b ("mbuf: add function returning buffer address")
> > > > >
> > > > > There are 2 options:
> > > > > 1- remove the rte_ring_version.map part of the patch.
> > > > > 2- change the static inline function into a standard function.
> > > > >
> > > > > I would prefer 2-, because it allows to keep an api/abi compat
> > > > > layer in the future.
> > > >
> > > > There are no news about this patch.
> > > > I classify it as changes requested.
> > > >
> > > Sorry for missed your comments for long time, I just submitted v8.
> > > I took the first option as it is in the data path and to keep consistent to its
> > neighboring functions.
> > 
> > Could you give a little more context about why you need to reset
> > the ring in the data path? I see that it is used in rte_hash_reset(),
> > but in my thinking, this was more used at init/exit.
> Sorry,literally it is in the control path, but I was impressed it will impact the 
> Data path performance when discussing this patch with Honnappa. 

I'm asking this because given the recent discussions about ABI stability,
I'd like to avoid defining a new static inline if it is not required.

Thanks,
Olivier

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring when not in use
  2019-07-12  9:53  0%         ` Olivier Matz
@ 2019-07-12 11:06  0%           ` Gavin Hu (Arm Technology China)
  2019-07-12 11:48  3%             ` Olivier Matz
  0 siblings, 1 reply; 200+ results
From: Gavin Hu (Arm Technology China) @ 2019-07-12 11:06 UTC (permalink / raw)
  To: Olivier Matz
  Cc: thomas, dev, nd, jerinj, hemant.agrawal, Nipun.gupta@nxp.com,
	Honnappa Nagarahalli, i.maximets, stable,
	Ruifeng Wang (Arm Technology China)

Hi Olivier,

> -----Original Message-----
> From: Olivier Matz <olivier.matz@6wind.com>
> Sent: Friday, July 12, 2019 5:54 PM
> To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> Cc: thomas@monjalon.net; dev@dpdk.org; nd <nd@arm.com>;
> jerinj@marvell.com; hemant.agrawal@nxp.com; Nipun.gupta@nxp.com;
> Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>;
> i.maximets@samsung.com; stable@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring
> when not in use
> 
> Hi Gavin,
> 
> On Fri, Jul 12, 2019 at 09:32:39AM +0000, Gavin Hu (Arm Technology China)
> wrote:
> > Hi Olivier and Thomas,
> >
> > > -----Original Message-----
> > > From: Thomas Monjalon <thomas@monjalon.net>
> > > Sent: Thursday, July 4, 2019 10:42 PM
> > > To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> > > Cc: dev@dpdk.org; Olivier Matz <olivier.matz@6wind.com>; nd
> > > <nd@arm.com>; jerinj@marvell.com; hemant.agrawal@nxp.com;
> > > Nipun.gupta@nxp.com; Honnappa Nagarahalli
> > > <Honnappa.Nagarahalli@arm.com>; i.maximets@samsung.com;
> > > stable@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring
> > > when not in use
> > >
> > > 29/03/2019 15:17, Olivier Matz:
> > > > Hi,
> > > >
> > > > On Fri, Mar 15, 2019 at 11:31:25AM +0800, Gavin Hu wrote:
> > > > > Currently, the flush is done by dequeuing the ring in a while loop. It is
> > > > > much simpler to flush the queue by resetting the head and tail indices.
> > > > >
> > > > > Fixes: af75078fece3 ("first public release")
> > > > > Cc: stable@dpdk.org
> > > > >
> > > > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > > Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > > > ---
> > > > > --- a/lib/librte_ring/rte_ring_version.map
> > > > > +++ b/lib/librte_ring/rte_ring_version.map
> > > > > @@ -17,3 +17,10 @@ DPDK_2.2 {
> > > > >  	rte_ring_free;
> > > > >
> > > > >  } DPDK_2.0;
> > > > > +
> > > > > +EXPERIMENTAL {
> > > > > +    global:
> > > > > +
> > > > > +	rte_ring_reset;
> > > > > +
> > > > > +};
> > > >
> > > > To me, a static inline function does not need to be added in
> > > > rte_ring_version.map (or is it due to a check script checking the
> > > > __rte_experimental tag ?). I found at least one commit where it
> > > > is not the case:
> > > > c277b34c1b3b ("mbuf: add function returning buffer address")
> > > >
> > > > There are 2 options:
> > > > 1- remove the rte_ring_version.map part of the patch.
> > > > 2- change the static inline function into a standard function.
> > > >
> > > > I would prefer 2-, because it allows to keep an api/abi compat
> > > > layer in the future.
> > >
> > > There are no news about this patch.
> > > I classify it as changes requested.
> > >
> > Sorry for missed your comments for long time, I just submitted v8.
> > I took the first option as it is in the data path and to keep consistent to its
> neighboring functions.
> 
> Could you give a little more context about why you need to reset
> the ring in the data path? I see that it is used in rte_hash_reset(),
> but in my thinking, this was more used at init/exit.
Sorry,literally it is in the control path, but I was impressed it will impact the 
Data path performance when discussing this patch with Honnappa. 
> 
> Thanks,
> Olivier

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring when not in use
  2019-07-12  9:32  0%       ` Gavin Hu (Arm Technology China)
@ 2019-07-12  9:53  0%         ` Olivier Matz
  2019-07-12 11:06  0%           ` Gavin Hu (Arm Technology China)
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-07-12  9:53 UTC (permalink / raw)
  To: Gavin Hu (Arm Technology China)
  Cc: thomas, dev, nd, jerinj, hemant.agrawal, Nipun.gupta@nxp.com,
	Honnappa Nagarahalli, i.maximets, stable

Hi Gavin,

On Fri, Jul 12, 2019 at 09:32:39AM +0000, Gavin Hu (Arm Technology China) wrote:
> Hi Olivier and Thomas,
> 
> > -----Original Message-----
> > From: Thomas Monjalon <thomas@monjalon.net>
> > Sent: Thursday, July 4, 2019 10:42 PM
> > To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> > Cc: dev@dpdk.org; Olivier Matz <olivier.matz@6wind.com>; nd
> > <nd@arm.com>; jerinj@marvell.com; hemant.agrawal@nxp.com;
> > Nipun.gupta@nxp.com; Honnappa Nagarahalli
> > <Honnappa.Nagarahalli@arm.com>; i.maximets@samsung.com;
> > stable@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring
> > when not in use
> > 
> > 29/03/2019 15:17, Olivier Matz:
> > > Hi,
> > >
> > > On Fri, Mar 15, 2019 at 11:31:25AM +0800, Gavin Hu wrote:
> > > > Currently, the flush is done by dequeuing the ring in a while loop. It is
> > > > much simpler to flush the queue by resetting the head and tail indices.
> > > >
> > > > Fixes: af75078fece3 ("first public release")
> > > > Cc: stable@dpdk.org
> > > >
> > > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > > ---
> > > > --- a/lib/librte_ring/rte_ring_version.map
> > > > +++ b/lib/librte_ring/rte_ring_version.map
> > > > @@ -17,3 +17,10 @@ DPDK_2.2 {
> > > >  	rte_ring_free;
> > > >
> > > >  } DPDK_2.0;
> > > > +
> > > > +EXPERIMENTAL {
> > > > +    global:
> > > > +
> > > > +	rte_ring_reset;
> > > > +
> > > > +};
> > >
> > > To me, a static inline function does not need to be added in
> > > rte_ring_version.map (or is it due to a check script checking the
> > > __rte_experimental tag ?). I found at least one commit where it
> > > is not the case:
> > > c277b34c1b3b ("mbuf: add function returning buffer address")
> > >
> > > There are 2 options:
> > > 1- remove the rte_ring_version.map part of the patch.
> > > 2- change the static inline function into a standard function.
> > >
> > > I would prefer 2-, because it allows to keep an api/abi compat
> > > layer in the future.
> > 
> > There are no news about this patch.
> > I classify it as changes requested.
> > 
> Sorry for missed your comments for long time, I just submitted v8.
> I took the first option as it is in the data path and to keep consistent to its neighboring functions. 

Could you give a little more context about why you need to reset
the ring in the data path? I see that it is used in rte_hash_reset(),
but in my thinking, this was more used at init/exit.

Thanks,
Olivier

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring when not in use
  @ 2019-07-12  9:32  0%       ` Gavin Hu (Arm Technology China)
  2019-07-12  9:53  0%         ` Olivier Matz
  0 siblings, 1 reply; 200+ results
From: Gavin Hu (Arm Technology China) @ 2019-07-12  9:32 UTC (permalink / raw)
  To: thomas
  Cc: dev, Olivier Matz, nd, jerinj, hemant.agrawal,
	Nipun.gupta@nxp.com, Honnappa Nagarahalli, i.maximets, stable

Hi Olivier and Thomas,

> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Thursday, July 4, 2019 10:42 PM
> To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>
> Cc: dev@dpdk.org; Olivier Matz <olivier.matz@6wind.com>; nd
> <nd@arm.com>; jerinj@marvell.com; hemant.agrawal@nxp.com;
> Nipun.gupta@nxp.com; Honnappa Nagarahalli
> <Honnappa.Nagarahalli@arm.com>; i.maximets@samsung.com;
> stable@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring
> when not in use
> 
> 29/03/2019 15:17, Olivier Matz:
> > Hi,
> >
> > On Fri, Mar 15, 2019 at 11:31:25AM +0800, Gavin Hu wrote:
> > > Currently, the flush is done by dequeuing the ring in a while loop. It is
> > > much simpler to flush the queue by resetting the head and tail indices.
> > >
> > > Fixes: af75078fece3 ("first public release")
> > > Cc: stable@dpdk.org
> > >
> > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > ---
> > > --- a/lib/librte_ring/rte_ring_version.map
> > > +++ b/lib/librte_ring/rte_ring_version.map
> > > @@ -17,3 +17,10 @@ DPDK_2.2 {
> > >  	rte_ring_free;
> > >
> > >  } DPDK_2.0;
> > > +
> > > +EXPERIMENTAL {
> > > +    global:
> > > +
> > > +	rte_ring_reset;
> > > +
> > > +};
> >
> > To me, a static inline function does not need to be added in
> > rte_ring_version.map (or is it due to a check script checking the
> > __rte_experimental tag ?). I found at least one commit where it
> > is not the case:
> > c277b34c1b3b ("mbuf: add function returning buffer address")
> >
> > There are 2 options:
> > 1- remove the rte_ring_version.map part of the patch.
> > 2- change the static inline function into a standard function.
> >
> > I would prefer 2-, because it allows to keep an api/abi compat
> > layer in the future.
> 
> There are no news about this patch.
> I classify it as changes requested.
> 
Sorry for missed your comments for long time, I just submitted v8.
I took the first option as it is in the data path and to keep consistent to its neighboring functions. 


^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v8 0/2] new ring reset api and use it by hash
    @ 2019-07-12  9:26  3% ` Gavin Hu
  2019-07-12 15:54  3% ` [dpdk-dev] [PATCH v9 " Gavin Hu
  2019-07-16 19:23  3% ` [dpdk-dev] [PATCH v10 " Gavin Hu
  3 siblings, 0 replies; 200+ results
From: Gavin Hu @ 2019-07-12  9:26 UTC (permalink / raw)
  To: dev
  Cc: nd, thomas, jerinj, hemant.agrawal, nipun.gupta,
	Honnappa.Nagarahalli, gavin.hu, i.maximets, olivier.matz

V2:
- fix the coding style issue(commit message line too long)
V3:
- allow experimental API for meson build
V4: 
- include the ring perf test case enhancement patch in the series.
- replace ARRAY_SIZE with RTE_DIM.
- call memset to avoid clang compling complains.
V5:
- commit message tweaking for ring test case enhancement patch
- upper to lower for mails to make match/grep more easily
V6:
- make upper case for the user name to comply with the convention.
V7:
- leave the ring test case patch out as not closely linked to this series in logic
V8:
- change the static inline function into a standard function to keep an api/abi compat layer in the future 

Gavin Hu (2):
  ring: add reset API to flush the ring when not in use
  hash: flush the rings instead of dequeuing one by one

 lib/librte_hash/Makefile          |  2 +-
 lib/librte_hash/meson.build       |  3 +++
 lib/librte_hash/rte_cuckoo_hash.c | 11 ++++-------
 lib/librte_ring/rte_ring.h        | 21 +++++++++++++++++++++
 4 files changed, 29 insertions(+), 8 deletions(-)

-- 
2.7.4


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-11 14:37  0%       ` Wiles, Keith
@ 2019-07-12  9:06  0%         ` Olivier Matz
  0 siblings, 0 replies; 200+ results
From: Olivier Matz @ 2019-07-12  9:06 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: dpdk dev community, Stephen Hemminger

Hi,

On Thu, Jul 11, 2019 at 02:37:23PM +0000, Wiles, Keith wrote:
> 
> 
> > On Jul 11, 2019, at 2:53 AM, Olivier Matz <olivier.matz@6wind.com> wrote:
> > 
> > Hi Keith,
> > 
> > On Wed, Jul 10, 2019 at 06:12:16PM +0000, Wiles, Keith wrote:
> >> 
> >> 
> >>> On Jul 10, 2019, at 12:49 PM, Stephen Hemminger <stephen@networkplumber.org> wrote:
> >>> 
> >>> On Wed, 10 Jul 2019 11:29:07 +0200
> >>> Olivier Matz <olivier.matz@6wind.com> wrote:
> >>> 
> >>>> /**
> >>>> * Indicate that the metadata field in the mbuf is in use.
> >>>> @@ -738,6 +741,8 @@ struct rte_mbuf {
> >>>> 	 */
> >>>> 	struct rte_mbuf_ext_shared_info *shinfo;
> >>>> 
> >>>> +	uint64_t dynfield1; /**< Reserved for dynamic fields. */
> >>>> +	uint64_t dynfield2; /**< Reserved for dynamic fields. */
> >>>> } __rte_cache_aligned;
> >>> 
> >>> Growing mbuf is a fundamental ABI break and this needs
> >>> higher level approval.  Why not one pointer?
> >>> 
> >>> It looks like you are creating something like FreeBSD m_tag.
> >>> Why not use that?
> >> 
> >> Changing the mbuf structure causes a big problem for a number reasons as Stephen states.
> > 
> > Can you elaborate?
> > 
> > This is indeed an ABI break, but I think this is only due to the adding
> > of rte_mbuf_dynfield_copy() in rte_pktmbuf_attach(). The size of the
> > mbuf does not change and the fields are not initialized when creating a
> > new mbuf. So I think there is no ABI change for code that is not using
> > rte_pktmbuf_attach().
> > 
> > I don't think it's a problem to have one ABI change, if it avoids many
> > others in the future.
> > 
> >> If we leave the mbuf stucture alone and add this feature to the
> >> headroom space between the mbuf structure and the packet. When setting
> >> up the mempool/mbuf pool we define a headroom to hold the extra data
> >> when the mbuf pool is created or just use the current headroom
> >> space. Using this method we can eliminate the mbuf structure change
> >> and add the data to the packet buffer. We can do away with dynfield1
> >> and 2 as we know where headroom space begins and ends. Just a thought.
> > 
> > The size of the mbuf metadata (between the mbuf structure and the
> > buffer) is configured per pool, so it can be different accross
> > mbufs. So, the access to the dynamic field would be slower:
> > *(mbuf + dynfield_offset + metadata_size(mbuf))
> 

> We can force that space to be a minimum size when the mempool is
> created in the case of a cloned mbuf. The cloned mbuf is a small use
> case, but am important one and increasing the size for those special
> mbufs by a cache line should not be a huge problem.
> 
> I think most allocations do not change the size from the default value
> of the headroom (128). The mbuf + buffer are normally rounded to 2K or
> a bit bigger, which gives a bit more space in those cases of a packet
> size of 1518-1522. Jumbo frames are the same. Using the headroom size
> for an application needs to be defined and setup for the max size
> anyway for the application needs, so normally all mbuf creates should
> contain the same size to account for mbuf moments within the system.

If we want more room for dynamic fields, we can do something like
this. But I don't think this is something that will happen soon: we
already have 16 bytes available, and I'm sure we can get another 16
bytes very easily by just converting fields like timestamp or sequence
numbers.

To attach larger amount of data to mbufs, the metadata feature still
exists. We can imagine to extend the dynamic fields feature to be able
to use more space after the mbuf structure (in metadata?), but it is
more complex.

I don't think that using headroom or tailroom is a good idea. That's
true that mbufs are usually a bit more than 2K, and some space is lost
when mtu is 1500. But smaller mbufs are perfectly legal too, except that
some drivers do not support it. Anyway, headroom and tailroom must be
used for what they are designed: reserving room to prepend or append
data. If we want more space for dynamic fields, let's add a specific
location for it, when it will be needed.


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-11  7:53  4%     ` Olivier Matz
@ 2019-07-11 14:37  0%       ` Wiles, Keith
  2019-07-12  9:06  0%         ` Olivier Matz
  0 siblings, 1 reply; 200+ results
From: Wiles, Keith @ 2019-07-11 14:37 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dpdk dev community, Stephen Hemminger



> On Jul 11, 2019, at 2:53 AM, Olivier Matz <olivier.matz@6wind.com> wrote:
> 
> Hi Keith,
> 
> On Wed, Jul 10, 2019 at 06:12:16PM +0000, Wiles, Keith wrote:
>> 
>> 
>>> On Jul 10, 2019, at 12:49 PM, Stephen Hemminger <stephen@networkplumber.org> wrote:
>>> 
>>> On Wed, 10 Jul 2019 11:29:07 +0200
>>> Olivier Matz <olivier.matz@6wind.com> wrote:
>>> 
>>>> /**
>>>> * Indicate that the metadata field in the mbuf is in use.
>>>> @@ -738,6 +741,8 @@ struct rte_mbuf {
>>>> 	 */
>>>> 	struct rte_mbuf_ext_shared_info *shinfo;
>>>> 
>>>> +	uint64_t dynfield1; /**< Reserved for dynamic fields. */
>>>> +	uint64_t dynfield2; /**< Reserved for dynamic fields. */
>>>> } __rte_cache_aligned;
>>> 
>>> Growing mbuf is a fundamental ABI break and this needs
>>> higher level approval.  Why not one pointer?
>>> 
>>> It looks like you are creating something like FreeBSD m_tag.
>>> Why not use that?
>> 
>> Changing the mbuf structure causes a big problem for a number reasons as Stephen states.
> 
> Can you elaborate?
> 
> This is indeed an ABI break, but I think this is only due to the adding
> of rte_mbuf_dynfield_copy() in rte_pktmbuf_attach(). The size of the
> mbuf does not change and the fields are not initialized when creating a
> new mbuf. So I think there is no ABI change for code that is not using
> rte_pktmbuf_attach().
> 
> I don't think it's a problem to have one ABI change, if it avoids many
> others in the future.
> 
>> If we leave the mbuf stucture alone and add this feature to the
>> headroom space between the mbuf structure and the packet. When setting
>> up the mempool/mbuf pool we define a headroom to hold the extra data
>> when the mbuf pool is created or just use the current headroom
>> space. Using this method we can eliminate the mbuf structure change
>> and add the data to the packet buffer. We can do away with dynfield1
>> and 2 as we know where headroom space begins and ends. Just a thought.
> 
> The size of the mbuf metadata (between the mbuf structure and the
> buffer) is configured per pool, so it can be different accross
> mbufs. So, the access to the dynamic field would be slower:
> *(mbuf + dynfield_offset + metadata_size(mbuf))

We can force that space to be a minimum size when the mempool is created in the case of a cloned mbuf. The cloned mbuf is a small use case, but am important one and increasing the size for those special mbufs by a cache line should not be a huge problem.

I think most allocations do not change the size from the default value of the headroom (128). The mbuf + buffer are normally rounded to 2K or a bit bigger, which gives a bit more space in those cases of a packet size of 1518-1522. Jumbo frames are the same. Using the headroom size for an application needs to be defined and setup for the max size anyway for the application needs, so normally all mbuf creates should contain the same size to account for mbuf moments within the system.

That is my $0.02.

> 
> Also, the size of the data buffer can be 0: it happens for mbuf pools
> that are dedicated to mbuf clones (that reference data in another mbuf
> or in an external buffer). In this case, there is no room after metadata
> to store the dynamic fields.
> 
> Thanks,
> Olivier

Regards,
Keith


^ permalink raw reply	[relevance 0%]

* [dpdk-dev] [PATCH v3] devtools: better freebsd support
  @ 2019-07-11 14:25  6% ` Olivier Matz
  2019-07-29  8:31  0%   ` David Marchand
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-07-11 14:25 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, David Marchand, Bruce Richardson, Musatescu, Flavia

- As "readlink -e" and "readlink -m" do not exist on freebsd,
  use "readlink -f", it should not have any impact in these cases.
- "sed -ri" is invalid on freebsd and should be replaced by
  "sed -ri=''"
- Use gmake instead of make.

This fixes the following command:
  SYSDIR=/usr/src/sys ./devtools/test-build.sh \
    -j4 x86_64-native-freebsd-gcc

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---

v3:
- fix examples installation path, pointed-out by Flavia

v2:
- remove sed_ri() function and use 'sed -ri=""' as suggested by Bruce

 devtools/check-dup-includes.sh |  2 +-
 devtools/checkpatches.sh       |  8 ++--
 devtools/get-maintainer.sh     |  2 +-
 devtools/load-devel-config     |  4 +-
 devtools/test-build.sh         | 94 ++++++++++++++++++++++--------------------
 devtools/validate-abi.sh       |  2 +-
 6 files changed, 58 insertions(+), 54 deletions(-)

diff --git a/devtools/check-dup-includes.sh b/devtools/check-dup-includes.sh
index e4c2748c6..591599949 100755
--- a/devtools/check-dup-includes.sh
+++ b/devtools/check-dup-includes.sh
@@ -5,7 +5,7 @@
 # Check C files in git repository for duplicated includes.
 # Usage: devtools/check-dup-includes.sh [directory]
 
-dir=${1:-$(dirname $(readlink -m $0))/..}
+dir=${1:-$(dirname $(readlink -f $0))/..}
 cd $dir
 
 # speed up by ignoring Unicode details
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 560e6ce93..8e2beee16 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -7,9 +7,9 @@
 # - DPDK_CHECKPATCH_CODESPELL
 # - DPDK_CHECKPATCH_LINE_LENGTH
 # - DPDK_CHECKPATCH_OPTIONS
-. $(dirname $(readlink -e $0))/load-devel-config
+. $(dirname $(readlink -f $0))/load-devel-config
 
-VALIDATE_NEW_API=$(dirname $(readlink -e $0))/check-symbol-change.sh
+VALIDATE_NEW_API=$(dirname $(readlink -f $0))/check-symbol-change.sh
 
 # Enable codespell by default. This can be overwritten from a config file.
 # Codespell can also be enabled by setting DPDK_CHECKPATCH_CODESPELL to a valid path
@@ -66,7 +66,7 @@ check_forbidden_additions() { # <patch>
 		-v EXPRESSIONS="rte_panic\\\( rte_exit\\\(" \
 		-v RET_ON_FAIL=1 \
 		-v MESSAGE='Using rte_panic/rte_exit' \
-		-f $(dirname $(readlink -e $0))/check-forbidden-tokens.awk \
+		-f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
 		"$1" || res=1
 
 	# svg figures must be included with wildcard extension
@@ -75,7 +75,7 @@ check_forbidden_additions() { # <patch>
 		-v EXPRESSIONS='::[[:space:]]*[^[:space:]]*\\.svg' \
 		-v RET_ON_FAIL=1 \
 		-v MESSAGE='Using explicit .svg extension instead of .*' \
-		-f $(dirname $(readlink -e $0))/check-forbidden-tokens.awk \
+		-f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
 		"$1" || res=1
 
 	return $res
diff --git a/devtools/get-maintainer.sh b/devtools/get-maintainer.sh
index b9160486a..85740f5af 100755
--- a/devtools/get-maintainer.sh
+++ b/devtools/get-maintainer.sh
@@ -5,7 +5,7 @@
 
 # Load config options:
 # - DPDK_GETMAINTAINER_PATH
-. $(dirname $(readlink -e $0))/load-devel-config
+. $(dirname $(readlink -f $0))/load-devel-config
 
 options="--no-git-fallback"
 options="$options --no-rolestats"
diff --git a/devtools/load-devel-config b/devtools/load-devel-config
index 4f43cb352..380c79db4 100644
--- a/devtools/load-devel-config
+++ b/devtools/load-devel-config
@@ -6,7 +6,7 @@ test ! -r /etc/dpdk/devel.config ||
 test ! -r ~/.config/dpdk/devel.config ||
         . ~/.config/dpdk/devel.config
 # from local file
-test ! -r $(dirname $(readlink -m $0))/../.develconfig ||
-        . $(dirname $(readlink -m $0))/../.develconfig
+test ! -r $(dirname $(readlink -f $0))/../.develconfig ||
+        . $(dirname $(readlink -f $0))/../.develconfig
 
 # The config files must export variables in the shell style
diff --git a/devtools/test-build.sh b/devtools/test-build.sh
index 9b50bf73d..3c029ce31 100755
--- a/devtools/test-build.sh
+++ b/devtools/test-build.sh
@@ -28,7 +28,7 @@ default_path=$PATH
 # - LIBSSO_SNOW3G_PATH
 # - LIBSSO_KASUMI_PATH
 # - LIBSSO_ZUC_PATH
-. $(dirname $(readlink -e $0))/load-devel-config
+. $(dirname $(readlink -f $0))/load-devel-config
 
 print_usage () {
 	echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] ...]]"
@@ -57,6 +57,10 @@ print_help () {
 	END_OF_HELP
 }
 
+[ -z $MAKE ] && command -v gmake > /dev/null && MAKE=gmake
+[ -z $MAKE ] && command -v make > /dev/null && MAKE=make
+[ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1
+
 J=$DPDK_MAKE_JOBS
 short=false
 unset verbose
@@ -90,7 +94,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT
 # notify result on exit
 trap on_exit EXIT
 
-cd $(dirname $(readlink -m $0))/..
+cd $(dirname $(readlink -f $0))/..
 
 reset_env ()
 {
@@ -127,83 +131,83 @@ config () # <directory> <target> <options>
 	fi
 	if [ ! -e $1/.config ] || $reconfig ; then
 		echo "================== Configure $1"
-		make T=$2 O=$1 config
+		${MAKE} T=$2 O=$1 config
 
 		echo 'Customize configuration'
 		# Built-in options (lowercase)
 		! echo $3 | grep -q '+default' || \
-		sed -ri 's,(RTE_MACHINE=")native,\1default,' $1/.config
+		sed -ri="" 's,(RTE_MACHINE=")native,\1default,' $1/.config
 		echo $3 | grep -q '+next' || \
-		sed -ri           's,(NEXT_ABI=)y,\1n,' $1/.config
+		sed -ri=""           's,(NEXT_ABI=)y,\1n,' $1/.config
 		! echo $3 | grep -q '+shared' || \
-		sed -ri         's,(SHARED_LIB=)n,\1y,' $1/.config
+		sed -ri=""         's,(SHARED_LIB=)n,\1y,' $1/.config
 		! echo $3 | grep -q '+debug' || ( \
-		sed -ri  's,(RTE_LOG_DP_LEVEL=).*,\1RTE_LOG_DEBUG,' $1/.config
-		sed -ri           's,(_DEBUG.*=)n,\1y,' $1/.config
-		sed -ri            's,(_STAT.*=)n,\1y,' $1/.config
-		sed -ri 's,(TEST_PMD_RECORD_.*=)n,\1y,' $1/.config )
+		sed -ri=""  's,(RTE_LOG_DP_LEVEL=).*,\1RTE_LOG_DEBUG,' $1/.config
+		sed -ri=""           's,(_DEBUG.*=)n,\1y,' $1/.config
+		sed -ri=""            's,(_STAT.*=)n,\1y,' $1/.config
+		sed -ri="" 's,(TEST_PMD_RECORD_.*=)n,\1y,' $1/.config )
 
 		# Automatic configuration
 		test "$DPDK_DEP_NUMA" != n || \
-		sed -ri             's,(NUMA.*=)y,\1n,' $1/.config
-		sed -ri    's,(LIBRTE_IEEE1588=)n,\1y,' $1/.config
-		sed -ri             's,(BYPASS=)n,\1y,' $1/.config
+		sed -ri=""             's,(NUMA.*=)y,\1n,' $1/.config
+		sed -ri=""    's,(LIBRTE_IEEE1588=)n,\1y,' $1/.config
+		sed -ri=""             's,(BYPASS=)n,\1y,' $1/.config
 		test "$DPDK_DEP_ARCHIVE" != y || \
-		sed -ri       's,(RESOURCE_TAR=)n,\1y,' $1/.config
+		sed -ri=""       's,(RESOURCE_TAR=)n,\1y,' $1/.config
 		test "$DPDK_DEP_ISAL" != y || \
-		sed -ri           's,(PMD_ISAL=)n,\1y,' $1/.config
+		sed -ri=""           's,(PMD_ISAL=)n,\1y,' $1/.config
 		test "$DPDK_DEP_MLX" != y || \
-		sed -ri           's,(MLX._PMD=)n,\1y,' $1/.config
+		sed -ri=""           's,(MLX._PMD=)n,\1y,' $1/.config
 		test "$DPDK_DEP_SZE" != y || \
-		sed -ri       's,(PMD_SZEDATA2=)n,\1y,' $1/.config
+		sed -ri=""       's,(PMD_SZEDATA2=)n,\1y,' $1/.config
 		test "$DPDK_DEP_ZLIB" != y || \
-		sed -ri          's,(BNX2X_PMD=)n,\1y,' $1/.config
+		sed -ri=""          's,(BNX2X_PMD=)n,\1y,' $1/.config
 		test "$DPDK_DEP_ZLIB" != y || \
-		sed -ri           's,(PMD_ZLIB=)n,\1y,' $1/.config
+		sed -ri=""           's,(PMD_ZLIB=)n,\1y,' $1/.config
 		test "$DPDK_DEP_ZLIB" != y || \
-		sed -ri   's,(COMPRESSDEV_TEST=)n,\1y,' $1/.config
+		sed -ri=""   's,(COMPRESSDEV_TEST=)n,\1y,' $1/.config
 		test "$DPDK_DEP_PCAP" != y || \
-		sed -ri               's,(PCAP=)n,\1y,' $1/.config
+		sed -ri=""               's,(PCAP=)n,\1y,' $1/.config
 		test -z "$ARMV8_CRYPTO_LIB_PATH" || \
-		sed -ri   's,(PMD_ARMV8_CRYPTO=)n,\1y,' $1/.config
+		sed -ri=""   's,(PMD_ARMV8_CRYPTO=)n,\1y,' $1/.config
 		test "$DPDK_DEP_IPSEC_MB" != y || \
-		sed -ri       's,(PMD_AESNI_MB=)n,\1y,' $1/.config
+		sed -ri=""       's,(PMD_AESNI_MB=)n,\1y,' $1/.config
 		test "$DPDK_DEP_IPSEC_MB" != y || \
-		sed -ri      's,(PMD_AESNI_GCM=)n,\1y,' $1/.config
+		sed -ri=""      's,(PMD_AESNI_GCM=)n,\1y,' $1/.config
 		test -z "$LIBSSO_SNOW3G_PATH" || \
-		sed -ri         's,(PMD_SNOW3G=)n,\1y,' $1/.config
+		sed -ri=""         's,(PMD_SNOW3G=)n,\1y,' $1/.config
 		test -z "$LIBSSO_KASUMI_PATH" || \
-		sed -ri         's,(PMD_KASUMI=)n,\1y,' $1/.config
+		sed -ri=""         's,(PMD_KASUMI=)n,\1y,' $1/.config
 		test -z "$LIBSSO_ZUC_PATH" || \
-		sed -ri            's,(PMD_ZUC=)n,\1y,' $1/.config
+		sed -ri=""            's,(PMD_ZUC=)n,\1y,' $1/.config
 		test "$DPDK_DEP_SSL" != y || \
-		sed -ri            's,(PMD_CCP=)n,\1y,' $1/.config
+		sed -ri=""            's,(PMD_CCP=)n,\1y,' $1/.config
 		test "$DPDK_DEP_SSL" != y || \
-		sed -ri        's,(PMD_OPENSSL=)n,\1y,' $1/.config
+		sed -ri=""        's,(PMD_OPENSSL=)n,\1y,' $1/.config
 		test "$DPDK_DEP_SSL" != y || \
-		sed -ri            's,(QAT_SYM=)n,\1y,' $1/.config
+		sed -ri=""            's,(QAT_SYM=)n,\1y,' $1/.config
 		test -z "$FLEXRAN_SDK" || \
-		sed -ri     's,(BBDEV_TURBO_SW=)n,\1y,' $1/.config
-		sed -ri           's,(SCHED_.*=)n,\1y,' $1/.config
+		sed -ri=""     's,(BBDEV_TURBO_SW=)n,\1y,' $1/.config
+		sed -ri=""           's,(SCHED_.*=)n,\1y,' $1/.config
 		test -z "$LIBMUSDK_PATH" || \
-		sed -ri   's,(PMD_MVSAM_CRYPTO=)n,\1y,' $1/.config
+		sed -ri=""   's,(PMD_MVSAM_CRYPTO=)n,\1y,' $1/.config
 		test -z "$LIBMUSDK_PATH" || \
-		sed -ri          's,(MVPP2_PMD=)n,\1y,' $1/.config
+		sed -ri=""          's,(MVPP2_PMD=)n,\1y,' $1/.config
 		test -z "$LIBMUSDK_PATH" || \
-		sed -ri         's,(MVNETA_PMD=)n,\1y,' $1/.config
+		sed -ri=""         's,(MVNETA_PMD=)n,\1y,' $1/.config
 		test "$DPDK_DEP_ELF" != y || \
-		sed -ri            's,(BPF_ELF=)n,\1y,' $1/.config
+		sed -ri=""            's,(BPF_ELF=)n,\1y,' $1/.config
 		test "$DPDK_DEP_JSON" != y || \
-		sed -ri          's,(TELEMETRY=)n,\1y,' $1/.config
+		sed -ri=""          's,(TELEMETRY=)n,\1y,' $1/.config
 		build_config_hook $1 $2 $3
 
 		# Explicit enabler/disabler (uppercase)
 		for option in $(echo $3 | sed 's,[~+], &,g') ; do
 			pattern=$(echo $option | cut -c2-)
 			if echo $option | grep -q '^~' ; then
-				sed -ri "s,($pattern=)y,\1n," $1/.config
+				sed -ri="" "s,($pattern=)y,\1n," $1/.config
 			elif echo $option | grep -q '^+' ; then
-				sed -ri "s,($pattern=)n,\1y," $1/.config
+				sed -ri="" "s,($pattern=)n,\1y," $1/.config
 			fi
 		done
 	fi
@@ -220,22 +224,22 @@ for conf in $configs ; do
 	# reload config with DPDK_TARGET set
 	DPDK_TARGET=$target
 	reset_env
-	. $(dirname $(readlink -e $0))/load-devel-config
+	. $(dirname $(readlink -f $0))/load-devel-config
 
 	options=$(echo $conf | sed 's,[^~+]*,,')
 	dir=$conf
 	config $dir $target $options
 
 	echo "================== Build $dir"
-	make -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \
+	${MAKE} -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \
 		EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose O=$dir
 	! $short || break
 	echo "================== Build examples for $dir"
 	export RTE_SDK=$(pwd)
 	export RTE_TARGET=$dir
-	make -j$J -sC examples \
+	${MAKE} -j$J -sC examples \
 		EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \
-		O=$(readlink -m $dir/examples)
+		O=$(readlink -f $dir)/examples
 	unset RTE_TARGET
 	echo "################## $dir done."
 	unset dir
@@ -244,9 +248,9 @@ done
 if ! $short ; then
 	mkdir -p .check
 	echo "================== Build doxygen HTML API"
-	make doc-api-html >/dev/null 2>.check/doc.txt
+	${MAKE} doc-api-html >/dev/null 2>.check/doc.txt
 	echo "================== Build sphinx HTML guides"
-	make doc-guides-html >/dev/null 2>>.check/doc.txt
+	${MAKE} doc-guides-html >/dev/null 2>>.check/doc.txt
 	echo "================== Check docs"
 	diff -u /dev/null .check/doc.txt
 fi
diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
index 138436d93..f64e19d38 100755
--- a/devtools/validate-abi.sh
+++ b/devtools/validate-abi.sh
@@ -181,7 +181,7 @@ case "${dst}" in
 	/*) ;;
 	*) dst=${PWD}/${dst} ;;
 esac
-dpdkroot=$(readlink -e $(dirname $0)/..)
+dpdkroot=$(readlink -f $(dirname $0)/..)
 
 if [ -e "${dst}" -a "$force" = 0 ]; then
 	echo "The ${dst} directory is not empty. Remove it, use another"
-- 
2.11.0


^ permalink raw reply	[relevance 6%]

* Re: [dpdk-dev] [PATCH v2 1/1] fbarray: get fbarrays from containerized secondary
  2019-07-11  9:37  0%             ` Yasufumi Ogawa
@ 2019-07-11  9:43  3%               ` Burakov, Anatoly
  0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2019-07-11  9:43 UTC (permalink / raw)
  To: Yasufumi Ogawa; +Cc: dev, stable

On 11-Jul-19 10:37 AM, Yasufumi Ogawa wrote:
> On 2019/07/09 19:26, Burakov, Anatoly wrote:
>> On 09-Jul-19 11:24 AM, Burakov, Anatoly wrote:
>>> On 09-Jul-19 11:22 AM, Yasufumi Ogawa wrote:
>>>> Hi Anatoly,
>>>>
>>>> On 2019/07/05 17:53, Burakov, Anatoly wrote:
>>>>> On 16-Apr-19 4:43 AM, ogawa.yasufumi@lab.ntt.co.jp wrote:
>>>>>> From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
>>>>>>
>>>>>> In secondary_msl_create_walk(), it creates a file for fbarrays 
>>>>>> with its
>>>>>> PID for reserving unique name among secondary processes. However, it
>>>>>> does not work if secondary is run as app container because each of
>>>>>> containerized secondary has PID 1. To reserve unique name, use 
>>>>>> hostname
>>>>>> instead of PID if the value is 1.
>>>>>>
>>>>>> Cc: stable@dpdk.org
>>>>>>
>>>>>> Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
>>>>>> ---
>>>>>
>>>>> I'm not too well versed in containers - is this hostname 1) always 
>>>>> set, and 2) always unique?
>>>> For docker, 1) hostname is always set. 2) The hostname is decided as 
>>>> short form of container ID, so it might not be unique even though 
>>>> very low possibility.
>>>>
>>>> I found that we can get whole container ID in `/proc/self/cgroup` as 
>>>> discussed [1]. I think using hostname is reasonable way without 
>>>> running many secondary processes. However, it might be better to use 
>>>> 64 digits full container ID instead of 12 digits short ID if ensure 
>>>> uniqueness strongly. What do yo think?
>>>>
>>>> [1] 
>>>> https://forums.docker.com/t/get-a-containers-full-id-from-inside-of-itself/37237 
>>>>
>>>
>>> I think it's better to err on the side of caution and guarantee 
>>> better uniqueness. This code will get into an LTS and will be used 
>>> for years to come :)
>>>
>>
>> ...however, i think a full 64-digit ID won't even fit into the fbarray 
>> filename, as i believe it's limited to something like 64 chars. 
>> Perhaps hostname would be enough after all... or we can increase 
>> fbarray name length - that would require ABI breakage but the ABI is 
>> already broken in this release, so it's OK i think.
> OK.

Just a note: you're targetting this fix towards stable too. For stable, 
you cannot break ABI, so we would have to do with the shorter hostname. 
It's only for 19.08 that you can change fbarray length and use the full 
64-char container ID for uniqueness.

> 
>  >> Wouldn't an error in fscanf() leak the file handle? I think you need 
> to fclose() before checking the result.
>  > I would like to fix it.
> I would like send v3 patch for fixing for fclose().

Please do :)

> 
> Thanks,
> Yasufumi
> 
> 


-- 
Thanks,
Anatoly

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH v2 1/1] fbarray: get fbarrays from containerized secondary
  @ 2019-07-11  9:37  0%             ` Yasufumi Ogawa
  2019-07-11  9:43  3%               ` Burakov, Anatoly
  0 siblings, 1 reply; 200+ results
From: Yasufumi Ogawa @ 2019-07-11  9:37 UTC (permalink / raw)
  To: Burakov, Anatoly; +Cc: dev, stable

On 2019/07/09 19:26, Burakov, Anatoly wrote:
> On 09-Jul-19 11:24 AM, Burakov, Anatoly wrote:
>> On 09-Jul-19 11:22 AM, Yasufumi Ogawa wrote:
>>> Hi Anatoly,
>>>
>>> On 2019/07/05 17:53, Burakov, Anatoly wrote:
>>>> On 16-Apr-19 4:43 AM, ogawa.yasufumi@lab.ntt.co.jp wrote:
>>>>> From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
>>>>>
>>>>> In secondary_msl_create_walk(), it creates a file for fbarrays with 
>>>>> its
>>>>> PID for reserving unique name among secondary processes. However, it
>>>>> does not work if secondary is run as app container because each of
>>>>> containerized secondary has PID 1. To reserve unique name, use 
>>>>> hostname
>>>>> instead of PID if the value is 1.
>>>>>
>>>>> Cc: stable@dpdk.org
>>>>>
>>>>> Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
>>>>> ---
>>>>
>>>> I'm not too well versed in containers - is this hostname 1) always 
>>>> set, and 2) always unique?
>>> For docker, 1) hostname is always set. 2) The hostname is decided as 
>>> short form of container ID, so it might not be unique even though 
>>> very low possibility.
>>>
>>> I found that we can get whole container ID in `/proc/self/cgroup` as 
>>> discussed [1]. I think using hostname is reasonable way without 
>>> running many secondary processes. However, it might be better to use 
>>> 64 digits full container ID instead of 12 digits short ID if ensure 
>>> uniqueness strongly. What do yo think?
>>>
>>> [1] 
>>> https://forums.docker.com/t/get-a-containers-full-id-from-inside-of-itself/37237 
>>>
>>
>> I think it's better to err on the side of caution and guarantee better 
>> uniqueness. This code will get into an LTS and will be used for years 
>> to come :)
>>
> 
> ...however, i think a full 64-digit ID won't even fit into the fbarray 
> filename, as i believe it's limited to something like 64 chars. Perhaps 
> hostname would be enough after all... or we can increase fbarray name 
> length - that would require ABI breakage but the ABI is already broken 
> in this release, so it's OK i think.
OK.

 >> Wouldn't an error in fscanf() leak the file handle? I think you need 
to fclose() before checking the result.
 > I would like to fix it.
I would like send v3 patch for fixing for fclose().

Thanks,
Yasufumi


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
    2019-07-10 17:14  0% ` Wang, Haiyue
  2019-07-10 17:49  3% ` Stephen Hemminger
@ 2019-07-11  9:24  3% ` Thomas Monjalon
  2019-07-12 14:54  0% ` Andrew Rybchenko
  3 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-07-11  9:24 UTC (permalink / raw)
  To: dev; +Cc: Olivier Matz

10/07/2019 11:29, Olivier Matz:
> Many features require to store data inside the mbuf. As the room in mbuf
> structure is limited, it is not possible to have a field for each
> feature. Also, changing fields in the mbuf structure can break the API
> or ABI.
> 
> This commit addresses these issues, by enabling the dynamic registration
> of fields or flags:
> 
> - a dynamic field is a named area in the rte_mbuf structure, with a
>   given size (>= 1 byte) and alignment constraint.
> - a dynamic flag is a named bit in the rte_mbuf structure.
> 
> The typical use case is a PMD that registers space for an offload
> feature, when the application requests to enable this feature.  As
> the space in mbuf is limited, the space should only be reserved if it
> is going to be used (i.e when the application explicitly asks for it).
> 
> The registration can be done at any moment, but it is not possible
> to unregister fields or flags for now.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

I fully support this solution.
It will give a lot of space for new features and will solve
the ABI stability problem.

Next step, I would like to move some existing mbuf fields to this
dynamic model. It will increase the free space in mbuf to be used
by dynamic fields. By converting some fields which are currently
union'ed, we can also fix the issue of these features being exclusive.

Acked-by: Thomas Monjalon <thomas@monjalon.net>



^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-11  8:20  0%       ` Olivier Matz
@ 2019-07-11  8:34  0%         ` Wang, Haiyue
  0 siblings, 0 replies; 200+ results
From: Wang, Haiyue @ 2019-07-11  8:34 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Thursday, July 11, 2019 16:21
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> 
> On Thu, Jul 11, 2019 at 08:04:00AM +0000, Wang, Haiyue wrote:
> > > -----Original Message-----
> > > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > > Sent: Thursday, July 11, 2019 15:26
> > > To: Wang, Haiyue <haiyue.wang@intel.com>
> > > Cc: dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> > >
> > > Hi,
> > >
> > > On Wed, Jul 10, 2019 at 05:14:33PM +0000, Wang, Haiyue wrote:
> > > > Hi,
> > > >
> > > > Sounds cool, just have some questions inline.
> > > >
> > > > > -----Original Message-----
> > > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
> > > > > Sent: Wednesday, July 10, 2019 17:29
> > > > > To: dev@dpdk.org
> > > > > Subject: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> > > > >
> > > > > Many features require to store data inside the mbuf. As the room in mbuf
> > > > > structure is limited, it is not possible to have a field for each
> > > > > feature. Also, changing fields in the mbuf structure can break the API
> > > > > or ABI.
> > > > >
> > > > > This commit addresses these issues, by enabling the dynamic registration
> > > > > of fields or flags:
> > > > >
> > > > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > > >   given size (>= 1 byte) and alignment constraint.
> > > > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > > > >
> > > > > The typical use case is a PMD that registers space for an offload
> > > > > feature, when the application requests to enable this feature.  As
> > > > > the space in mbuf is limited, the space should only be reserved if it
> > > > > is going to be used (i.e when the application explicitly asks for it).
> > > > >
> > > > > The registration can be done at any moment, but it is not possible
> > > > > to unregister fields or flags for now.
> > > > >
> > > > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > >
> > > (...)
> > >
> > > > > +/**
> > > > > + * @file
> > > > > + * RTE Mbuf dynamic fields and flags
> > > > > + *
> > > > > + * Many features require to store data inside the mbuf. As the room in
> > > > > + * mbuf structure is limited, it is not possible to have a field for
> > > > > + * each feature. Also, changing fields in the mbuf structure can break
> > > > > + * the API or ABI.
> > > > > + *
> > > > > + * This module addresses this issue, by enabling the dynamic
> > > > > + * registration of fields or flags:
> > > > > + *
> > > > > + * - a dynamic field is a named area in the rte_mbuf structure, with a
> > > > > + *   given size (>= 1 byte) and alignment constraint.
> > > > > + * - a dynamic flag is a named bit in the rte_mbuf structure.
> > > > > + *
> > > > > + * The typical use case is a PMD that registers space for an offload
> > > > > + * feature, when the application requests to enable this feature.  As
> > > > > + * the space in mbuf is limited, the space should only be reserved if it
> > > > > + * is going to be used (i.e when the application explicitly asks for it).
> > > > > + *
> > > > > + * The registration can be done at any moment, but it is not possible
> > > > > + * to unregister fields or flags for now.
> > > > > + *
> > > > > + * Example of use:
> > > > > + *
> > > > > + * - RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN) are defined in this file
> > > >
> > > > Does it means that all PMDs define their own 'RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN)'
> > > > here ? In other words, each PMD can expose its private DYN_<feature> here for public
> > > > using ?
> > >
> > > For generic fields, I think they should be declared in this file. For
> > > instance, if we decide to replace the current m->timestamp field by a
> > > dynamic field, we should add like this:
> > >
> > > #define RTE_MBUF_DYN_TIMESTAMP_ID "rte_timestamp"
> > > #define RTE_MBUF_DYN_TIMESTAMP_SIZE sizeof(uint64_t)
> > > #define RTE_MBUF_DYN_TIMESTAMP_ALIGN __alignof__(uint64_t)
> > >
> > > If the feature is PMD-specific, the defines could be exposed in a
> > > PMD header.
> > >
> >
> > Now, understand the comments a little : ... must not define identifers prefixed with "rte_",
> > which are reserved for standard features. Seems have big plan ?
> 
> The dynamic field can also be used by an external application or by an
> external library. For instance, a field to tag a packet, like skb->mark
> in linux. In this case, id, size and alignment would be defined outside
> dpdk subtree.
> 
> To avoid name conflicts, I think we should define a convention for
> identifiers, so they are in different namespaces:
> 
> - "rte_*" for identifiers declared inside dpdk subtree
> - any other name for identifiers declared in an external application or
>   library

Very clearer now, thanks, this convention can be in programming guide document. :)

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-11  8:04  0%     ` Wang, Haiyue
@ 2019-07-11  8:20  0%       ` Olivier Matz
  2019-07-11  8:34  0%         ` Wang, Haiyue
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-07-11  8:20 UTC (permalink / raw)
  To: Wang, Haiyue; +Cc: dev

On Thu, Jul 11, 2019 at 08:04:00AM +0000, Wang, Haiyue wrote:
> > -----Original Message-----
> > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > Sent: Thursday, July 11, 2019 15:26
> > To: Wang, Haiyue <haiyue.wang@intel.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> > 
> > Hi,
> > 
> > On Wed, Jul 10, 2019 at 05:14:33PM +0000, Wang, Haiyue wrote:
> > > Hi,
> > >
> > > Sounds cool, just have some questions inline.
> > >
> > > > -----Original Message-----
> > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
> > > > Sent: Wednesday, July 10, 2019 17:29
> > > > To: dev@dpdk.org
> > > > Subject: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> > > >
> > > > Many features require to store data inside the mbuf. As the room in mbuf
> > > > structure is limited, it is not possible to have a field for each
> > > > feature. Also, changing fields in the mbuf structure can break the API
> > > > or ABI.
> > > >
> > > > This commit addresses these issues, by enabling the dynamic registration
> > > > of fields or flags:
> > > >
> > > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > >   given size (>= 1 byte) and alignment constraint.
> > > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > > >
> > > > The typical use case is a PMD that registers space for an offload
> > > > feature, when the application requests to enable this feature.  As
> > > > the space in mbuf is limited, the space should only be reserved if it
> > > > is going to be used (i.e when the application explicitly asks for it).
> > > >
> > > > The registration can be done at any moment, but it is not possible
> > > > to unregister fields or flags for now.
> > > >
> > > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > 
> > (...)
> > 
> > > > +/**
> > > > + * @file
> > > > + * RTE Mbuf dynamic fields and flags
> > > > + *
> > > > + * Many features require to store data inside the mbuf. As the room in
> > > > + * mbuf structure is limited, it is not possible to have a field for
> > > > + * each feature. Also, changing fields in the mbuf structure can break
> > > > + * the API or ABI.
> > > > + *
> > > > + * This module addresses this issue, by enabling the dynamic
> > > > + * registration of fields or flags:
> > > > + *
> > > > + * - a dynamic field is a named area in the rte_mbuf structure, with a
> > > > + *   given size (>= 1 byte) and alignment constraint.
> > > > + * - a dynamic flag is a named bit in the rte_mbuf structure.
> > > > + *
> > > > + * The typical use case is a PMD that registers space for an offload
> > > > + * feature, when the application requests to enable this feature.  As
> > > > + * the space in mbuf is limited, the space should only be reserved if it
> > > > + * is going to be used (i.e when the application explicitly asks for it).
> > > > + *
> > > > + * The registration can be done at any moment, but it is not possible
> > > > + * to unregister fields or flags for now.
> > > > + *
> > > > + * Example of use:
> > > > + *
> > > > + * - RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN) are defined in this file
> > >
> > > Does it means that all PMDs define their own 'RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN)'
> > > here ? In other words, each PMD can expose its private DYN_<feature> here for public
> > > using ?
> > 
> > For generic fields, I think they should be declared in this file. For
> > instance, if we decide to replace the current m->timestamp field by a
> > dynamic field, we should add like this:
> > 
> > #define RTE_MBUF_DYN_TIMESTAMP_ID "rte_timestamp"
> > #define RTE_MBUF_DYN_TIMESTAMP_SIZE sizeof(uint64_t)
> > #define RTE_MBUF_DYN_TIMESTAMP_ALIGN __alignof__(uint64_t)
> > 
> > If the feature is PMD-specific, the defines could be exposed in a
> > PMD header.
> > 
> 
> Now, understand the comments a little : ... must not define identifers prefixed with "rte_",
> which are reserved for standard features. Seems have big plan ?

The dynamic field can also be used by an external application or by an
external library. For instance, a field to tag a packet, like skb->mark
in linux. In this case, id, size and alignment would be defined outside
dpdk subtree.

To avoid name conflicts, I think we should define a convention for
identifiers, so they are in different namespaces:

- "rte_*" for identifiers declared inside dpdk subtree
- any other name for identifiers declared in an external application or
  library

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-11  7:26  0%   ` Olivier Matz
@ 2019-07-11  8:04  0%     ` Wang, Haiyue
  2019-07-11  8:20  0%       ` Olivier Matz
  0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2019-07-11  8:04 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Thursday, July 11, 2019 15:26
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> 
> Hi,
> 
> On Wed, Jul 10, 2019 at 05:14:33PM +0000, Wang, Haiyue wrote:
> > Hi,
> >
> > Sounds cool, just have some questions inline.
> >
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
> > > Sent: Wednesday, July 10, 2019 17:29
> > > To: dev@dpdk.org
> > > Subject: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> > >
> > > Many features require to store data inside the mbuf. As the room in mbuf
> > > structure is limited, it is not possible to have a field for each
> > > feature. Also, changing fields in the mbuf structure can break the API
> > > or ABI.
> > >
> > > This commit addresses these issues, by enabling the dynamic registration
> > > of fields or flags:
> > >
> > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > >   given size (>= 1 byte) and alignment constraint.
> > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > >
> > > The typical use case is a PMD that registers space for an offload
> > > feature, when the application requests to enable this feature.  As
> > > the space in mbuf is limited, the space should only be reserved if it
> > > is going to be used (i.e when the application explicitly asks for it).
> > >
> > > The registration can be done at any moment, but it is not possible
> > > to unregister fields or flags for now.
> > >
> > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> 
> (...)
> 
> > > +/**
> > > + * @file
> > > + * RTE Mbuf dynamic fields and flags
> > > + *
> > > + * Many features require to store data inside the mbuf. As the room in
> > > + * mbuf structure is limited, it is not possible to have a field for
> > > + * each feature. Also, changing fields in the mbuf structure can break
> > > + * the API or ABI.
> > > + *
> > > + * This module addresses this issue, by enabling the dynamic
> > > + * registration of fields or flags:
> > > + *
> > > + * - a dynamic field is a named area in the rte_mbuf structure, with a
> > > + *   given size (>= 1 byte) and alignment constraint.
> > > + * - a dynamic flag is a named bit in the rte_mbuf structure.
> > > + *
> > > + * The typical use case is a PMD that registers space for an offload
> > > + * feature, when the application requests to enable this feature.  As
> > > + * the space in mbuf is limited, the space should only be reserved if it
> > > + * is going to be used (i.e when the application explicitly asks for it).
> > > + *
> > > + * The registration can be done at any moment, but it is not possible
> > > + * to unregister fields or flags for now.
> > > + *
> > > + * Example of use:
> > > + *
> > > + * - RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN) are defined in this file
> >
> > Does it means that all PMDs define their own 'RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN)'
> > here ? In other words, each PMD can expose its private DYN_<feature> here for public
> > using ?
> 
> For generic fields, I think they should be declared in this file. For
> instance, if we decide to replace the current m->timestamp field by a
> dynamic field, we should add like this:
> 
> #define RTE_MBUF_DYN_TIMESTAMP_ID "rte_timestamp"
> #define RTE_MBUF_DYN_TIMESTAMP_SIZE sizeof(uint64_t)
> #define RTE_MBUF_DYN_TIMESTAMP_ALIGN __alignof__(uint64_t)
> 
> If the feature is PMD-specific, the defines could be exposed in a
> PMD header.
> 

Now, understand the comments a little : ... must not define identifers prefixed with "rte_",
which are reserved for standard features. Seems have big plan ?

> > How about adding another eth_dev_ops API definitions to show the PMD's supporting feature
> > names, sizes, align in run time for testpmd ? And also another eth_dev_ops API for showing
> > the data saved in rte_mbuf by 'dump_pkt_burst' ? Adding a new command for testpmd to set
> > the dynamic feature may be good for PMD test.
> >
> > > + * - If the application asks for the feature, the PMD use
> >
> > How does the application ask for the feature ? By ' rte_mbuf_dynfield_register()' ?
> 
> No change in this area. If we take again the timestamp example, the
> feature is asked by the application through the ethdev layer by passing
> DEV_RX_OFFLOAD_TIMESTAMP to port or queue configuration.
> 
> >
> > > + *   rte_mbuf_dynfield_register() to get the dynamic offset and stores
> > > + *   in a global variable.
> >
> > In case, the PMD calls 'rte_mbuf_dynfield_register()' for 'dyn_feature' firstly, this
> > means that PMD requests the dynamic feature itself if I understand correctly. Should
> > PMD calls 'rte_mbuf_dynfield_lookup' for 'dyn_feature' to query the name exists, the
> > size and align are right as expected ? If exists, but size and align are not right, may
> > be for PMD change its definition, then PMD can give a warning or error message. If name
> > exists, both size and align are expected, then PMD think that the application request
> > the right dynamic features.
> 
> The PMD should only call rte_mbuf_dynfield_register() if the application
> requests the feature (through ethdev, or through another mean if it's a
> PMD-specific feature). The goal is to only reserve the area in the mbuf
> for features that are actually needed.
> 
> Hope this is clearer now. I think I need to enhance the documentation in
> next version ;)
> 

Clearer now, more test code also will be better for fully understanding, thanks! :)

> Thanks for the feedback.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-10 18:12  0%   ` Wiles, Keith
@ 2019-07-11  7:53  4%     ` Olivier Matz
  2019-07-11 14:37  0%       ` Wiles, Keith
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-07-11  7:53 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: dpdk dev community, Stephen Hemminger

Hi Keith,

On Wed, Jul 10, 2019 at 06:12:16PM +0000, Wiles, Keith wrote:
> 
> 
> > On Jul 10, 2019, at 12:49 PM, Stephen Hemminger <stephen@networkplumber.org> wrote:
> > 
> > On Wed, 10 Jul 2019 11:29:07 +0200
> > Olivier Matz <olivier.matz@6wind.com> wrote:
> > 
> >> /**
> >>  * Indicate that the metadata field in the mbuf is in use.
> >> @@ -738,6 +741,8 @@ struct rte_mbuf {
> >> 	 */
> >> 	struct rte_mbuf_ext_shared_info *shinfo;
> >> 
> >> +	uint64_t dynfield1; /**< Reserved for dynamic fields. */
> >> +	uint64_t dynfield2; /**< Reserved for dynamic fields. */
> >> } __rte_cache_aligned;
> > 
> > Growing mbuf is a fundamental ABI break and this needs
> > higher level approval.  Why not one pointer?
> > 
> > It looks like you are creating something like FreeBSD m_tag.
> > Why not use that?
> 
> Changing the mbuf structure causes a big problem for a number reasons as Stephen states.

Can you elaborate?

This is indeed an ABI break, but I think this is only due to the adding
of rte_mbuf_dynfield_copy() in rte_pktmbuf_attach(). The size of the
mbuf does not change and the fields are not initialized when creating a
new mbuf. So I think there is no ABI change for code that is not using
rte_pktmbuf_attach().

I don't think it's a problem to have one ABI change, if it avoids many
others in the future.

> If we leave the mbuf stucture alone and add this feature to the
> headroom space between the mbuf structure and the packet. When setting
> up the mempool/mbuf pool we define a headroom to hold the extra data
> when the mbuf pool is created or just use the current headroom
> space. Using this method we can eliminate the mbuf structure change
> and add the data to the packet buffer. We can do away with dynfield1
> and 2 as we know where headroom space begins and ends. Just a thought.

The size of the mbuf metadata (between the mbuf structure and the
buffer) is configured per pool, so it can be different accross
mbufs. So, the access to the dynamic field would be slower:
*(mbuf + dynfield_offset + metadata_size(mbuf))

Also, the size of the data buffer can be 0: it happens for mbuf pools
that are dedicated to mbuf clones (that reference data in another mbuf
or in an external buffer). In this case, there is no room after metadata
to store the dynamic fields.

Thanks,
Olivier

^ permalink raw reply	[relevance 4%]

* Re: [dpdk-dev] [PATCH] ethdev: extend flow metadata
  2019-07-10 16:37  3%       ` Yongseok Koh
@ 2019-07-11  7:44  0%         ` Adrien Mazarguil
  2019-07-14 11:46  0%           ` Andrew Rybchenko
  0 siblings, 1 reply; 200+ results
From: Adrien Mazarguil @ 2019-07-11  7:44 UTC (permalink / raw)
  To: Yongseok Koh
  Cc: Thomas Monjalon, Olivier Matz, Bruce Richardson,
	Andrew Rybchenko, Shahaf Shuler, Ferruh Yigit, dev,
	Slava Ovsiienko

On Wed, Jul 10, 2019 at 04:37:46PM +0000, Yongseok Koh wrote:
> 
> > On Jul 10, 2019, at 5:26 AM, Thomas Monjalon <thomas@monjalon.net> wrote:
> > 
> > 10/07/2019 14:01, Bruce Richardson:
> >> On Wed, Jul 10, 2019 at 12:07:43PM +0200, Olivier Matz wrote:
> >>> On Wed, Jul 10, 2019 at 10:55:34AM +0100, Bruce Richardson wrote:
> >>>> On Wed, Jul 10, 2019 at 11:31:56AM +0200, Olivier Matz wrote:
> >>>>> On Thu, Jul 04, 2019 at 04:21:22PM -0700, Yongseok Koh wrote:
> >>>>>> Currently, metadata can be set on egress path via mbuf tx_meatadata field
> >>>>>> with PKT_TX_METADATA flag and RTE_FLOW_ITEM_TYPE_RX_META matches metadata.
> >>>>>> 
> >>>>>> This patch extends the usability.
> >>>>>> 
> >>>>>> 1) RTE_FLOW_ACTION_TYPE_SET_META
> >>>>>> 
> >>>>>> When supporting multiple tables, Tx metadata can also be set by a rule and
> >>>>>> matched by another rule. This new action allows metadata to be set as a
> >>>>>> result of flow match.
> >>>>>> 
> >>>>>> 2) Metadata on ingress
> >>>>>> 
> >>>>>> There's also need to support metadata on packet Rx. Metadata can be set by
> >>>>>> SET_META action and matched by META item like Tx. The final value set by
> >>>>>> the action will be delivered to application via mbuf metadata field with
> >>>>>> PKT_RX_METADATA ol_flag.
> >>>>>> 
> >>>>>> For this purpose, mbuf->tx_metadata is moved as a separate new field and
> >>>>>> renamed to 'metadata' to support both Rx and Tx metadata.
> >>>>>> 
> >>>>>> For loopback/hairpin packet, metadata set on Rx/Tx may or may not be
> >>>>>> propagated to the other path depending on HW capability.
> >>>>>> 
> >>>>>> Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
> >>>>> 
> >>>>>> --- a/lib/librte_mbuf/rte_mbuf.h
> >>>>>> +++ b/lib/librte_mbuf/rte_mbuf.h
> >>>>>> @@ -648,17 +653,6 @@ struct rte_mbuf {
> >>>>>> 			/**< User defined tags. See rte_distributor_process() */
> >>>>>> 			uint32_t usr;
> >>>>>> 		} hash;                   /**< hash information */
> >>>>>> -		struct {
> >>>>>> -			/**
> >>>>>> -			 * Application specific metadata value
> >>>>>> -			 * for egress flow rule match.
> >>>>>> -			 * Valid if PKT_TX_METADATA is set.
> >>>>>> -			 * Located here to allow conjunct use
> >>>>>> -			 * with hash.sched.hi.
> >>>>>> -			 */
> >>>>>> -			uint32_t tx_metadata;
> >>>>>> -			uint32_t reserved;
> >>>>>> -		};
> >>>>>> 	};
> >>>>>> 
> >>>>>> 	/** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ is set. */
> >>>>>> @@ -727,6 +721,11 @@ struct rte_mbuf {
> >>>>>> 	 */
> >>>>>> 	struct rte_mbuf_ext_shared_info *shinfo;
> >>>>>> 
> >>>>>> +	/** Application specific metadata value for flow rule match.
> >>>>>> +	 * Valid if PKT_RX_METADATA or PKT_TX_METADATA is set.
> >>>>>> +	 */
> >>>>>> +	uint32_t metadata;
> >>>>>> +
> >>>>>> } __rte_cache_aligned;
> >>>>> 
> >>>>> This will break the ABI, so we cannot put it in 19.08, and we need a
> >>>>> deprecation notice.
> >>>>> 
> >>>> Does it actually break the ABI? Adding a new field to the mbuf should only
> >>>> break the ABI if it either causes new fields to move or changes the
> >>>> structure size. Since this is at the end, it's not going to move any older
> >>>> fields, and since everything is cache-aligned I don't think the structure
> >>>> size changes either.
> >>> 
> >>> I think it does break the ABI: in previous version, when the PKT_TX_METADATA
> >>> flag is set, the associated value is put in m->tx_metadata (offset 44 on
> >>> x86-64), and in the next version, it will be in m->metadata (offset 112). So,
> >>> these 2 versions are not binary compatible.
> >>> 
> >>> Anyway, at least it breaks the API.
> >> 
> >> Ok, I misunderstood. I thought it was the structure change itself you were
> >> saying broke the ABI. Yes, putting the data in a different place is indeed
> >> an ABI break.
> > 
> > We could add the new field and keep the old one unused,
> > so it does not break the ABI.
> 
> Still breaks ABI if PKT_TX_METADATA is set. :-) In order not to break it, I can
> keep the current union'd field (tx_metadata) as is with PKT_TX_METADATA, add
> the new one at the end and make it used with the new PKT_RX_METADATA.
> 
> > However I suppose everybody will prefer a version using dynamic fields.
> > Is someone against using dynamic field for such usage?
> 
> However, given that the amazing dynamic fields is coming soon (thanks for your
> effort, Olivier and Thomas!), I'd be honored to be the first user of it.
> 
> Olivier, I'll take a look at your RFC.

Just got a crazy idea while reading this thread... How about repurposing
that "reserved" field as "rx_metadata" in the meantime?

I know reserved fields are cursed and no one's ever supposed to touch them
but this risk is mitigated by having the end user explicitly request its
use, so the patch author (and his relatives) should be safe from the
resulting bad juju.

Joke aside, while I like the idea of Tx/Rx META, I think the similarities
with MARK (and TAG eventually) is a problem. I wasn't available and couldn't
comment when META was originally added to the Tx path, but there's a lot of
overlap between these items/actions, without anything explaining to the end
user how and why they should pick one over the other, if they can be
combined at all and what happens in that case.

All this must be documented, then we should think about unifying their
respective features and deprecate the less capable items/actions. In my
opinion, users need exactly one method to mark/match some mark while
processing Rx/Tx traffic and *optionally* have that mark read from/written
to the mbuf, which may or may not be possible depending on HW features.

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-10 17:49  3% ` Stephen Hemminger
  2019-07-10 18:12  0%   ` Wiles, Keith
@ 2019-07-11  7:36  0%   ` Olivier Matz
    1 sibling, 1 reply; 200+ results
From: Olivier Matz @ 2019-07-11  7:36 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Wed, Jul 10, 2019 at 10:49:17AM -0700, Stephen Hemminger wrote:
> On Wed, 10 Jul 2019 11:29:07 +0200
> Olivier Matz <olivier.matz@6wind.com> wrote:
> 
> >  /**
> >   * Indicate that the metadata field in the mbuf is in use.
> > @@ -738,6 +741,8 @@ struct rte_mbuf {
> >  	 */
> >  	struct rte_mbuf_ext_shared_info *shinfo;
> >  
> > +	uint64_t dynfield1; /**< Reserved for dynamic fields. */
> > +	uint64_t dynfield2; /**< Reserved for dynamic fields. */
> >  } __rte_cache_aligned;
> 
> Growing mbuf is a fundamental ABI break and this needs
> higher level approval.

The size of the mbuf is still 128, I used the last 16 bytes that
were unused.

Later, we can think about removing existing fields and replace
them by a dynfield area, which can be anywhere in the structure
(even if it is in a 1 byte hole).

>  Why not one pointer?

A pointer to what?

> It looks like you are creating something like FreeBSD m_tag.
> Why not use that?

My implementation targets performance (accessing to *(mbuf + offset)
should be nearly as fast as accessing to a static field), at the price
of less flexibility compared to something like FreeBSD m_tag.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-10 17:14  0% ` Wang, Haiyue
@ 2019-07-11  7:26  0%   ` Olivier Matz
  2019-07-11  8:04  0%     ` Wang, Haiyue
  0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-07-11  7:26 UTC (permalink / raw)
  To: Wang, Haiyue; +Cc: dev

Hi,

On Wed, Jul 10, 2019 at 05:14:33PM +0000, Wang, Haiyue wrote:
> Hi,
> 
> Sounds cool, just have some questions inline.
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
> > Sent: Wednesday, July 10, 2019 17:29
> > To: dev@dpdk.org
> > Subject: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> > 
> > Many features require to store data inside the mbuf. As the room in mbuf
> > structure is limited, it is not possible to have a field for each
> > feature. Also, changing fields in the mbuf structure can break the API
> > or ABI.
> > 
> > This commit addresses these issues, by enabling the dynamic registration
> > of fields or flags:
> > 
> > - a dynamic field is a named area in the rte_mbuf structure, with a
> >   given size (>= 1 byte) and alignment constraint.
> > - a dynamic flag is a named bit in the rte_mbuf structure.
> > 
> > The typical use case is a PMD that registers space for an offload
> > feature, when the application requests to enable this feature.  As
> > the space in mbuf is limited, the space should only be reserved if it
> > is going to be used (i.e when the application explicitly asks for it).
> > 
> > The registration can be done at any moment, but it is not possible
> > to unregister fields or flags for now.
> > 
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

(...)

> > +/**
> > + * @file
> > + * RTE Mbuf dynamic fields and flags
> > + *
> > + * Many features require to store data inside the mbuf. As the room in
> > + * mbuf structure is limited, it is not possible to have a field for
> > + * each feature. Also, changing fields in the mbuf structure can break
> > + * the API or ABI.
> > + *
> > + * This module addresses this issue, by enabling the dynamic
> > + * registration of fields or flags:
> > + *
> > + * - a dynamic field is a named area in the rte_mbuf structure, with a
> > + *   given size (>= 1 byte) and alignment constraint.
> > + * - a dynamic flag is a named bit in the rte_mbuf structure.
> > + *
> > + * The typical use case is a PMD that registers space for an offload
> > + * feature, when the application requests to enable this feature.  As
> > + * the space in mbuf is limited, the space should only be reserved if it
> > + * is going to be used (i.e when the application explicitly asks for it).
> > + *
> > + * The registration can be done at any moment, but it is not possible
> > + * to unregister fields or flags for now.
> > + *
> > + * Example of use:
> > + *
> > + * - RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN) are defined in this file
> 
> Does it means that all PMDs define their own 'RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN)'
> here ? In other words, each PMD can expose its private DYN_<feature> here for public
> using ?

For generic fields, I think they should be declared in this file. For
instance, if we decide to replace the current m->timestamp field by a
dynamic field, we should add like this:

#define RTE_MBUF_DYN_TIMESTAMP_ID "rte_timestamp"
#define RTE_MBUF_DYN_TIMESTAMP_SIZE sizeof(uint64_t)
#define RTE_MBUF_DYN_TIMESTAMP_ALIGN __alignof__(uint64_t)

If the feature is PMD-specific, the defines could be exposed in a
PMD header.

> How about adding another eth_dev_ops API definitions to show the PMD's supporting feature
> names, sizes, align in run time for testpmd ? And also another eth_dev_ops API for showing
> the data saved in rte_mbuf by 'dump_pkt_burst' ? Adding a new command for testpmd to set
> the dynamic feature may be good for PMD test.
> 
> > + * - If the application asks for the feature, the PMD use
> 
> How does the application ask for the feature ? By ' rte_mbuf_dynfield_register()' ?

No change in this area. If we take again the timestamp example, the
feature is asked by the application through the ethdev layer by passing
DEV_RX_OFFLOAD_TIMESTAMP to port or queue configuration.

> 
> > + *   rte_mbuf_dynfield_register() to get the dynamic offset and stores
> > + *   in a global variable.
> 
> In case, the PMD calls 'rte_mbuf_dynfield_register()' for 'dyn_feature' firstly, this
> means that PMD requests the dynamic feature itself if I understand correctly. Should
> PMD calls 'rte_mbuf_dynfield_lookup' for 'dyn_feature' to query the name exists, the
> size and align are right as expected ? If exists, but size and align are not right, may
> be for PMD change its definition, then PMD can give a warning or error message. If name
> exists, both size and align are expected, then PMD think that the application request
> the right dynamic features.

The PMD should only call rte_mbuf_dynfield_register() if the application
requests the feature (through ethdev, or through another mean if it's a
PMD-specific feature). The goal is to only reserve the area in the mbuf
for features that are actually needed.

Hope this is clearer now. I think I need to enhance the documentation in
next version ;)

Thanks for the feedback.

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  2019-07-10 17:49  3% ` Stephen Hemminger
@ 2019-07-10 18:12  0%   ` Wiles, Keith
  2019-07-11  7:53  4%     ` Olivier Matz
  2019-07-11  7:36  0%   ` Olivier Matz
  1 sibling, 1 reply; 200+ results
From: Wiles, Keith @ 2019-07-10 18:12 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dpdk dev community, Stephen Hemminger



> On Jul 10, 2019, at 12:49 PM, Stephen Hemminger <stephen@networkplumber.org> wrote:
> 
> On Wed, 10 Jul 2019 11:29:07 +0200
> Olivier Matz <olivier.matz@6wind.com> wrote:
> 
>> /**
>>  * Indicate that the metadata field in the mbuf is in use.
>> @@ -738,6 +741,8 @@ struct rte_mbuf {
>> 	 */
>> 	struct rte_mbuf_ext_shared_info *shinfo;
>> 
>> +	uint64_t dynfield1; /**< Reserved for dynamic fields. */
>> +	uint64_t dynfield2; /**< Reserved for dynamic fields. */
>> } __rte_cache_aligned;
> 
> Growing mbuf is a fundamental ABI break and this needs
> higher level approval.  Why not one pointer?
> 
> It looks like you are creating something like FreeBSD m_tag.
> Why not use that?

Changing the mbuf structure causes a big problem for a number reasons as Stephen states.

If we leave the mbuf stucture alone and add this feature to the headroom space between the mbuf structure and the packet. When setting up the mempool/mbuf pool we define a headroom to hold the extra data when the mbuf pool is created or just use the current headroom space. Using this method we can eliminate the mbuf structure change and add the data to the packet buffer. We can do away with dynfield1 and 2 as we know where headroom space begins and ends. Just a thought.

Regards,
Keith


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
    2019-07-10 17:14  0% ` Wang, Haiyue
@ 2019-07-10 17:49  3% ` Stephen Hemminger
  2019-07-10 18:12  0%   ` Wiles, Keith
  2019-07-11  7:36  0%   ` Olivier Matz
  2019-07-11  9:24  3% ` Thomas Monjalon
  2019-07-12 14:54  0% ` Andrew Rybchenko
  3 siblings, 2 replies; 200+ results
From: Stephen Hemminger @ 2019-07-10 17:49 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

On Wed, 10 Jul 2019 11:29:07 +0200
Olivier Matz <olivier.matz@6wind.com> wrote:

>  /**
>   * Indicate that the metadata field in the mbuf is in use.
> @@ -738,6 +741,8 @@ struct rte_mbuf {
>  	 */
>  	struct rte_mbuf_ext_shared_info *shinfo;
>  
> +	uint64_t dynfield1; /**< Reserved for dynamic fields. */
> +	uint64_t dynfield2; /**< Reserved for dynamic fields. */
>  } __rte_cache_aligned;

Growing mbuf is a fundamental ABI break and this needs
higher level approval.  Why not one pointer?

It looks like you are creating something like FreeBSD m_tag.
Why not use that?

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
  @ 2019-07-10 17:14  0% ` Wang, Haiyue
  2019-07-11  7:26  0%   ` Olivier Matz
  2019-07-10 17:49  3% ` Stephen Hemminger
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2019-07-10 17:14 UTC (permalink / raw)
  To: Olivier Matz, dev

Hi,

Sounds cool, just have some questions inline.

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
> Sent: Wednesday, July 10, 2019 17:29
> To: dev@dpdk.org
> Subject: [dpdk-dev] [RFC] mbuf: support dynamic fields and flags
> 
> Many features require to store data inside the mbuf. As the room in mbuf
> structure is limited, it is not possible to have a field for each
> feature. Also, changing fields in the mbuf structure can break the API
> or ABI.
> 
> This commit addresses these issues, by enabling the dynamic registration
> of fields or flags:
> 
> - a dynamic field is a named area in the rte_mbuf structure, with a
>   given size (>= 1 byte) and alignment constraint.
> - a dynamic flag is a named bit in the rte_mbuf structure.
> 
> The typical use case is a PMD that registers space for an offload
> feature, when the application requests to enable this feature.  As
> the space in mbuf is limited, the space should only be reserved if it
> is going to be used (i.e when the application explicitly asks for it).
> 
> The registration can be done at any moment, but it is not possible
> to unregister fields or flags for now.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
>  app/test/test_mbuf.c                 |  83 +++++++-
>  lib/librte_mbuf/Makefile             |   2 +
>  lib/librte_mbuf/meson.build          |   6 +-
>  lib/librte_mbuf/rte_mbuf.h           |  25 ++-
>  lib/librte_mbuf/rte_mbuf_dyn.c       | 373 +++++++++++++++++++++++++++++++++++
>  lib/librte_mbuf/rte_mbuf_dyn.h       | 119 +++++++++++
>  lib/librte_mbuf/rte_mbuf_version.map |   4 +
>  7 files changed, 607 insertions(+), 5 deletions(-)
>  create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
>  create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> 
> diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> index 2a97afe20..8008cc766 100644
> --- a/app/test/test_mbuf.c
> +++ b/app/test/test_mbuf.c
> @@ -28,6 +28,7 @@
>  #include <rte_random.h>
>  #include <rte_cycles.h>
>  #include <rte_malloc.h>
> +#include <rte_mbuf_dyn.h>
> 
>  #include "test.h"
> 
> @@ -502,7 +503,6 @@ test_attach_from_different_pool(struct rte_mempool *pktmbuf_pool,
>  		rte_pktmbuf_free(clone2);
>  	return -1;
>  }
> -#undef GOTO_FAIL
> 
>  /*
>   * test allocation and free of mbufs
> @@ -1122,6 +1122,81 @@ test_tx_offload(void)
>  }
> 
>  static int
> +test_mbuf_dyn(struct rte_mempool *pktmbuf_pool)
> +{
> +	struct rte_mbuf *m = NULL;
> +	int offset, offset2;
> +	int flag, flag2;
> +
> +	offset = rte_mbuf_dynfield_register("test-dynfield", sizeof(uint8_t),
> +					__alignof__(uint8_t), 0);
> +	if (offset == -1)
> +		GOTO_FAIL("failed to register dynamic field, offset=%d: %s",
> +			offset, strerror(errno));
> +
> +	offset2 = rte_mbuf_dynfield_register("test-dynfield", sizeof(uint8_t),
> +					__alignof__(uint8_t), 0);
> +	if (offset2 != offset)
> +		GOTO_FAIL("failed to lookup dynamic field, offset=%d, offset2=%d: %s",
> +			offset, offset2, strerror(errno));
> +
> +	offset2 = rte_mbuf_dynfield_register("test-dynfield2", sizeof(uint16_t),
> +					__alignof__(uint16_t), 0);
> +	if (offset2 == -1 || offset2 == offset || (offset & 1))
> +		GOTO_FAIL("failed to register dynfield field 2, offset=%d, offset2=%d: %s",
> +			offset, offset2, strerror(errno));
> +
> +	printf("offset = %d, offset2 = %d\n", offset, offset2);
> +
> +	offset = rte_mbuf_dynfield_register("test-dynfield-fail", 256, 1, 0);
> +	if (offset != -1)
> +		GOTO_FAIL("dynamic field creation should fail (too big)");
> +
> +	offset = rte_mbuf_dynfield_register("test-dynfield-fail", 1, 3, 0);
> +	if (offset != -1)
> +		GOTO_FAIL("dynamic field creation should fail (bad alignment)");
> +
> +	flag = rte_mbuf_dynflag_register("test-dynflag");
> +	if (flag == -1)
> +		GOTO_FAIL("failed to register dynamic field, flag=%d: %s",
> +			flag, strerror(errno));
> +
> +	flag2 = rte_mbuf_dynflag_register("test-dynflag");
> +	if (flag2 != flag)
> +		GOTO_FAIL("failed to lookup dynamic field, flag=%d, flag2=%d: %s",
> +			flag, flag2, strerror(errno));
> +
> +	flag2 = rte_mbuf_dynflag_register("test-dynflag2");
> +	if (flag2 == -1 || flag2 == flag)
> +		GOTO_FAIL("failed to register dynflag field 2, flag=%d, flag2=%d: %s",
> +			flag, flag2, strerror(errno));
> +
> +	printf("flag = %d, flag2 = %d\n", flag, flag2);
> +
> +	/* set, get dynamic field */
> +	m = rte_pktmbuf_alloc(pktmbuf_pool);
> +	if (m == NULL)
> +		GOTO_FAIL("Cannot allocate mbuf");
> +
> +	*RTE_MBUF_DYNFIELD(m, offset, uint8_t *) = 1;
> +	if (*RTE_MBUF_DYNFIELD(m, offset, uint8_t *) != 1)
> +		GOTO_FAIL("failed to read dynamic field");
> +	*RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) = 1000;
> +	if (*RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) != 1000)
> +		GOTO_FAIL("failed to read dynamic field");
> +
> +	/* set a dynamic flag */
> +	m->ol_flags |= (1ULL << flag);
> +
> +	rte_pktmbuf_free(m);
> +	return 0;
> +fail:
> +	rte_pktmbuf_free(m);
> +	return -1;
> +}
> +#undef GOTO_FAIL
> +
> +static int
>  test_mbuf(void)
>  {
>  	int ret = -1;
> @@ -1140,6 +1215,12 @@ test_mbuf(void)
>  		goto err;
>  	}
> 
> +	/* test registration of dynamic fields and flags */
> +	if (test_mbuf_dyn(pktmbuf_pool) < 0) {
> +		printf("mbuf dynflag test failed\n");
> +		goto err;
> +	}
> +
>  	/* create a specific pktmbuf pool with a priv_size != 0 and no data
>  	 * room size */
>  	pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2",
> diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
> index c8f6d2689..5a9bcee73 100644
> --- a/lib/librte_mbuf/Makefile
> +++ b/lib/librte_mbuf/Makefile
> @@ -17,8 +17,10 @@ LIBABIVER := 5
> 
>  # all source are stored in SRCS-y
>  SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
> +SRCS-$(CONFIG_RTE_LIBRTE_MBUF) += rte_mbuf_dyn.c
> 
>  # install includes
>  SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include := rte_mbuf.h rte_mbuf_ptype.h rte_mbuf_pool_ops.h
> +SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include += rte_mbuf_dyn.h
> 
>  include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
> index 6cc11ebb4..9137e8f26 100644
> --- a/lib/librte_mbuf/meson.build
> +++ b/lib/librte_mbuf/meson.build
> @@ -2,8 +2,10 @@
>  # Copyright(c) 2017 Intel Corporation
> 
>  version = 5
> -sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
> -headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
> +sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c',
> +	'rte_mbuf_dyn.c')
> +headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h',
> +	'rte_mbuf_dyn.h')
>  deps += ['mempool']
> 
>  allow_experimental_apis = true
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index 98225ec80..ef588cd54 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -198,9 +198,12 @@ extern "C" {
>  #define PKT_RX_OUTER_L4_CKSUM_GOOD	(1ULL << 22)
>  #define PKT_RX_OUTER_L4_CKSUM_INVALID	((1ULL << 21) | (1ULL << 22))
> 
> -/* add new RX flags here */
> +/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
> 
> -/* add new TX flags here */
> +#define PKT_FIRST_FREE (1ULL << 23)
> +#define PKT_LAST_FREE (1ULL << 39)
> +
> +/* add new TX flags here, don't forget to update PKT_LAST_FREE  */
> 
>  /**
>   * Indicate that the metadata field in the mbuf is in use.
> @@ -738,6 +741,8 @@ struct rte_mbuf {
>  	 */
>  	struct rte_mbuf_ext_shared_info *shinfo;
> 
> +	uint64_t dynfield1; /**< Reserved for dynamic fields. */
> +	uint64_t dynfield2; /**< Reserved for dynamic fields. */
>  } __rte_cache_aligned;
> 
>  /**
> @@ -1685,6 +1690,21 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
>  #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
> 
>  /**
> + * Copy dynamic fields from m_src to m_dst.
> + *
> + * @param m_dst
> + *   The destination mbuf.
> + * @param m_src
> + *   The source mbuf.
> + */
> +static inline void
> +rte_mbuf_dynfield_copy(struct rte_mbuf *m_dst, const struct rte_mbuf *m_src)
> +{
> +	m_dst->dynfield1 = m_src->dynfield1;
> +	m_dst->dynfield2 = m_src->dynfield2;
> +}
> +
> +/**
>   * Attach packet mbuf to another packet mbuf.
>   *
>   * If the mbuf we are attaching to isn't a direct buffer and is attached to
> @@ -1732,6 +1752,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
>  	mi->vlan_tci_outer = m->vlan_tci_outer;
>  	mi->tx_offload = m->tx_offload;
>  	mi->hash = m->hash;
> +	rte_mbuf_dynfield_copy(mi, m);
> 
>  	mi->next = NULL;
>  	mi->pkt_len = mi->data_len;
> diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c b/lib/librte_mbuf/rte_mbuf_dyn.c
> new file mode 100644
> index 000000000..6a96a43da
> --- /dev/null
> +++ b/lib/librte_mbuf/rte_mbuf_dyn.c
> @@ -0,0 +1,373 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2019 6WIND S.A.
> + */
> +
> +#include <sys/queue.h>
> +
> +#include <rte_common.h>
> +#include <rte_eal.h>
> +#include <rte_eal_memconfig.h>
> +#include <rte_tailq.h>
> +#include <rte_errno.h>
> +#include <rte_malloc.h>
> +#include <rte_string_fns.h>
> +#include <rte_mbuf.h>
> +#include <rte_mbuf_dyn.h>
> +
> +#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
> +
> +struct mbuf_dynfield {
> +	TAILQ_ENTRY(mbuf_dynfield) next;
> +	char name[RTE_MBUF_DYN_NAMESIZE];
> +	size_t size;
> +	size_t align;
> +	unsigned int flags;
> +	int offset;
> +};
> +TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
> +
> +static struct rte_tailq_elem mbuf_dynfield_tailq = {
> +	.name = "RTE_MBUF_DYNFIELD",
> +};
> +EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
> +
> +struct mbuf_dynflag {
> +	TAILQ_ENTRY(mbuf_dynflag) next;
> +	char name[RTE_MBUF_DYN_NAMESIZE];
> +	int bitnum;
> +};
> +TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
> +
> +static struct rte_tailq_elem mbuf_dynflag_tailq = {
> +	.name = "RTE_MBUF_DYNFLAG",
> +};
> +EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
> +
> +struct mbuf_dyn_shm {
> +	/** For each mbuf byte, free_space[i] == 1 if space is free. */
> +	uint8_t free_space[sizeof(struct rte_mbuf)];
> +	/** Bitfield of available flags. */
> +	uint64_t free_flags;
> +};
> +static struct mbuf_dyn_shm *shm;
> +
> +/* allocate and initialize the shared memory */
> +static int
> +init_shared_mem(void)
> +{
> +	const struct rte_memzone *mz;
> +	uint64_t mask;
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		mz = rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
> +						sizeof(struct mbuf_dyn_shm),
> +						SOCKET_ID_ANY, 0,
> +						RTE_CACHE_LINE_SIZE);
> +	} else {
> +		mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
> +	}
> +	if (mz == NULL)
> +		return -1;
> +
> +	shm = mz->addr;
> +
> +#define mark_free(field)						\
> +	memset(&shm->free_space[offsetof(struct rte_mbuf, field)],	\
> +		0xff, sizeof(((struct rte_mbuf *)0)->field))
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		/* init free_space, keep it sync'd with
> +		 * rte_mbuf_dynfield_copy().
> +		 */
> +		memset(shm, 0, sizeof(*shm));
> +		mark_free(dynfield1);
> +		mark_free(dynfield2);
> +
> +		/* init free_flags */
> +		for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask <<= 1)
> +			shm->free_flags |= mask;
> +	}
> +#undef mark_free
> +
> +	return 0;
> +}
> +
> +/* check if this offset can be used */
> +static int
> +check_offset(size_t offset, size_t size, size_t align, unsigned int flags)
> +{
> +	size_t i;
> +
> +	(void)flags;
> +
> +	if ((offset & (align - 1)) != 0)
> +		return -1;
> +	if (offset + size > sizeof(struct rte_mbuf))
> +		return -1;
> +
> +	for (i = 0; i < size; i++) {
> +		if (!shm->free_space[i + offset])
> +			return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +/* assume tailq is locked */
> +static struct mbuf_dynfield *
> +__mbuf_dynfield_lookup(const char *name)
> +{
> +	struct mbuf_dynfield_list *mbuf_dynfield_list;
> +	struct mbuf_dynfield *mbuf_dynfield;
> +	struct rte_tailq_entry *te;
> +
> +	mbuf_dynfield_list = RTE_TAILQ_CAST(
> +		mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> +
> +	TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> +		mbuf_dynfield = (struct mbuf_dynfield *)te->data;
> +		if (strncmp(name, mbuf_dynfield->name,
> +				RTE_MBUF_DYN_NAMESIZE) == 0)
> +			break;
> +	}
> +
> +	if (te == NULL) {
> +		rte_errno = ENOENT;
> +		return NULL;
> +	}
> +
> +	return mbuf_dynfield;
> +}
> +
> +int
> +rte_mbuf_dynfield_lookup(const char *name, size_t *size, size_t *align)
> +{
> +	struct mbuf_dynfield *mbuf_dynfield;
> +
> +	if (shm == NULL) {
> +		rte_errno = ENOENT;
> +		return -1;
> +	}
> +
> +	rte_mcfg_tailq_read_lock();
> +	mbuf_dynfield = __mbuf_dynfield_lookup(name);
> +	rte_mcfg_tailq_read_unlock();
> +
> +	if (mbuf_dynfield == NULL) {
> +		rte_errno = ENOENT;
> +		return -1;
> +	}
> +
> +	if (size != NULL)
> +		*size = mbuf_dynfield->size;
> +	if (align != NULL)
> +		*align = mbuf_dynfield->align;
> +
> +	return mbuf_dynfield->offset;
> +}
> +
> +int
> +rte_mbuf_dynfield_register(const char *name, size_t size, size_t align,
> +			unsigned int flags)
> +{
> +	struct mbuf_dynfield_list *mbuf_dynfield_list;
> +	struct mbuf_dynfield *mbuf_dynfield = NULL;
> +	struct rte_tailq_entry *te = NULL;
> +	int offset, ret;
> +	size_t i;
> +
> +	if (shm == NULL && init_shared_mem() < 0)
> +		goto fail;
> +	if (size >= sizeof(struct rte_mbuf)) {
> +		rte_errno = EINVAL;
> +		goto fail;
> +	}
> +	if (!rte_is_power_of_2(align)) {
> +		rte_errno = EINVAL;
> +		goto fail;
> +	}
> +
> +	rte_mcfg_tailq_write_lock();
> +
> +	mbuf_dynfield = __mbuf_dynfield_lookup(name);
> +	if (mbuf_dynfield != NULL) {
> +		if (mbuf_dynfield->size != size ||
> +				mbuf_dynfield->align != align ||
> +				mbuf_dynfield->flags != flags) {
> +			rte_errno = EEXIST;
> +			goto fail_unlock;
> +		}
> +		offset = mbuf_dynfield->offset;
> +		goto out_unlock;
> +	}
> +
> +	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> +		rte_errno = EPERM;
> +		goto fail_unlock;
> +	}
> +
> +	for (offset = 0;
> +	     offset < (int)sizeof(struct rte_mbuf);
> +	     offset++) {
> +		if (check_offset(offset, size, align, flags) == 0)
> +			break;
> +	}
> +
> +	if (offset == sizeof(struct rte_mbuf)) {
> +		rte_errno = ENOENT;
> +		goto fail_unlock;
> +	}
> +
> +	mbuf_dynfield_list = RTE_TAILQ_CAST(
> +		mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> +
> +	te = rte_zmalloc("MBUF_DYNFIELD_TAILQ_ENTRY", sizeof(*te), 0);
> +	if (te == NULL)
> +		goto fail_unlock;
> +
> +	mbuf_dynfield = rte_zmalloc("mbuf_dynfield", sizeof(*mbuf_dynfield), 0);
> +	if (mbuf_dynfield == NULL)
> +		goto fail_unlock;
> +
> +	ret = strlcpy(mbuf_dynfield->name, name, sizeof(mbuf_dynfield->name));
> +	if (ret < 0 || ret >= (int)sizeof(mbuf_dynfield->name)) {
> +		rte_errno = ENAMETOOLONG;
> +		goto fail_unlock;
> +	}
> +	mbuf_dynfield->size = size;
> +	mbuf_dynfield->align = align;
> +	mbuf_dynfield->flags = flags;
> +	mbuf_dynfield->offset = offset;
> +	te->data = mbuf_dynfield;
> +
> +	TAILQ_INSERT_TAIL(mbuf_dynfield_list, te, next);
> +
> +	for (i = offset; i < offset + size; i++)
> +		shm->free_space[i] = 0;
> +
> +out_unlock:
> +	rte_mcfg_tailq_write_unlock();
> +
> +	return offset;
> +
> +fail_unlock:
> +	rte_mcfg_tailq_write_unlock();
> +fail:
> +	rte_free(mbuf_dynfield);
> +	rte_free(te);
> +	return -1;
> +}
> +
> +/* assume tailq is locked */
> +static struct mbuf_dynflag *
> +__mbuf_dynflag_lookup(const char *name)
> +{
> +	struct mbuf_dynflag_list *mbuf_dynflag_list;
> +	struct mbuf_dynflag *mbuf_dynflag;
> +	struct rte_tailq_entry *te;
> +
> +	mbuf_dynflag_list = RTE_TAILQ_CAST(
> +		mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> +
> +	TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
> +		mbuf_dynflag = (struct mbuf_dynflag *)te->data;
> +		if (strncmp(name, mbuf_dynflag->name,
> +				RTE_MBUF_DYN_NAMESIZE) == 0)
> +			break;
> +	}
> +
> +	if (te == NULL) {
> +		rte_errno = ENOENT;
> +		return NULL;
> +	}
> +
> +	return mbuf_dynflag;
> +}
> +
> +int
> +rte_mbuf_dynflag_lookup(const char *name)
> +{
> +	struct mbuf_dynflag *mbuf_dynflag;
> +
> +	if (shm == NULL) {
> +		rte_errno = ENOENT;
> +		return -1;
> +	}
> +
> +	rte_mcfg_tailq_read_lock();
> +	mbuf_dynflag = __mbuf_dynflag_lookup(name);
> +	rte_mcfg_tailq_read_unlock();
> +
> +	if (mbuf_dynflag == NULL) {
> +		rte_errno = ENOENT;
> +		return -1;
> +	}
> +
> +	return mbuf_dynflag->bitnum;
> +}
> +
> +int
> +rte_mbuf_dynflag_register(const char *name)
> +{
> +	struct mbuf_dynflag_list *mbuf_dynflag_list;
> +	struct mbuf_dynflag *mbuf_dynflag = NULL;
> +	struct rte_tailq_entry *te = NULL;
> +	int bitnum, ret;
> +
> +	if (shm == NULL && init_shared_mem() < 0)
> +		goto fail;
> +
> +	rte_mcfg_tailq_write_lock();
> +
> +	mbuf_dynflag = __mbuf_dynflag_lookup(name);
> +	if (mbuf_dynflag != NULL) {
> +		bitnum = mbuf_dynflag->bitnum;
> +		goto out_unlock;
> +	}
> +
> +	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> +		rte_errno = EPERM;
> +		goto fail_unlock;
> +	}
> +
> +	if (shm->free_flags == 0) {
> +		rte_errno = ENOENT;
> +		goto fail_unlock;
> +	}
> +	bitnum = rte_bsf64(shm->free_flags);
> +
> +	mbuf_dynflag_list = RTE_TAILQ_CAST(
> +		mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> +
> +	te = rte_zmalloc("MBUF_DYNFLAG_TAILQ_ENTRY", sizeof(*te), 0);
> +	if (te == NULL)
> +		goto fail_unlock;
> +
> +	mbuf_dynflag = rte_zmalloc("mbuf_dynflag", sizeof(*mbuf_dynflag), 0);
> +	if (mbuf_dynflag == NULL)
> +		goto fail_unlock;
> +
> +	ret = strlcpy(mbuf_dynflag->name, name, sizeof(mbuf_dynflag->name));
> +	if (ret < 0 || ret >= (int)sizeof(mbuf_dynflag->name)) {
> +		rte_errno = ENAMETOOLONG;
> +		goto fail_unlock;
> +	}
> +	mbuf_dynflag->bitnum = bitnum;
> +	te->data = mbuf_dynflag;
> +
> +	TAILQ_INSERT_TAIL(mbuf_dynflag_list, te, next);
> +
> +	shm->free_flags &= ~(1ULL << bitnum);
> +
> +out_unlock:
> +	rte_mcfg_tailq_write_unlock();
> +
> +	return bitnum;
> +
> +fail_unlock:
> +	rte_mcfg_tailq_write_unlock();
> +fail:
> +	rte_free(mbuf_dynflag);
> +	rte_free(te);
> +	return -1;
> +}
> diff --git a/lib/librte_mbuf/rte_mbuf_dyn.h b/lib/librte_mbuf/rte_mbuf_dyn.h
> new file mode 100644
> index 000000000..a86986a0f
> --- /dev/null
> +++ b/lib/librte_mbuf/rte_mbuf_dyn.h
> @@ -0,0 +1,119 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2019 6WIND S.A.
> + */
> +
> +#ifndef _RTE_MBUF_DYN_H_
> +#define _RTE_MBUF_DYN_H_
> +
> +/**
> + * @file
> + * RTE Mbuf dynamic fields and flags
> + *
> + * Many features require to store data inside the mbuf. As the room in
> + * mbuf structure is limited, it is not possible to have a field for
> + * each feature. Also, changing fields in the mbuf structure can break
> + * the API or ABI.
> + *
> + * This module addresses this issue, by enabling the dynamic
> + * registration of fields or flags:
> + *
> + * - a dynamic field is a named area in the rte_mbuf structure, with a
> + *   given size (>= 1 byte) and alignment constraint.
> + * - a dynamic flag is a named bit in the rte_mbuf structure.
> + *
> + * The typical use case is a PMD that registers space for an offload
> + * feature, when the application requests to enable this feature.  As
> + * the space in mbuf is limited, the space should only be reserved if it
> + * is going to be used (i.e when the application explicitly asks for it).
> + *
> + * The registration can be done at any moment, but it is not possible
> + * to unregister fields or flags for now.
> + *
> + * Example of use:
> + *
> + * - RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN) are defined in this file

Does it means that all PMDs define their own 'RTE_MBUF_DYN_<feature>_(ID|SIZE|ALIGN)'
here ? In other words, each PMD can expose its private DYN_<feature> here for public
using ?

How about adding another eth_dev_ops API definitions to show the PMD's supporting feature
names, sizes, align in run time for testpmd ? And also another eth_dev_ops API for showing
the data saved in rte_mbuf by 'dump_pkt_burst' ? Adding a new command for testpmd to set
the dynamic feature may be good for PMD test.

> + * - If the application asks for the feature, the PMD use

How does the application ask for the feature ? By ' rte_mbuf_dynfield_register()' ?

> + *   rte_mbuf_dynfield_register() to get the dynamic offset and stores
> + *   in a global variable.

In case, the PMD calls 'rte_mbuf_dynfield_register()' for 'dyn_feature' firstly, this
means that PMD requests the dynamic feature itself if I understand correctly. Should
PMD calls 'rte_mbuf_dynfield_lookup' for 'dyn_feature' to query the name exists, the
size and align are right as expected ? If exists, but size and align are not right, may
be for PMD change its definition, then PMD can give a warning or error message. If name
exists, both size and align are expected, then PMD think that the application request
the right dynamic features.

> + * - The application also calls rte_mbuf_dynfield_register() to get the
> + *   dynamic offset and stores it in a global variable.
> + * - When the field must be used by the PMD or the application, they
> + *   use the RTE_MBUF_DYNFIELD() helper.
> + */
> +
> +struct rte_mbuf;
> +
> +/**
> + * Register space for a dynamic field in the mbuf structure.
> + *
> + * @param name
> + *   A string identifying the dynamic field. External applications or
> + *   libraries must not define identifers prefixed with "rte_", which
> + *   are reserved for standard features.
> + * @param size
> + *   The number of bytes to reserve.
> + * @param align
> + *   The alignment constraint, which must be a power of 2.
> + * @param flags
> + *   Reserved for future use.
> + * @return
> + *   The offset in the mbuf structure, or -1 on error (rte_errno is set).
> + */
> +__rte_experimental
> +int rte_mbuf_dynfield_register(const char *name, size_t size, size_t align,
> +			unsigned int flags);
> +
> +/**
> + * Lookup for a registered dynamic mbuf field.
> + *
> + * @param name
> + *   A string identifying the dynamic field.
> + * @param size
> + *   If not NULL, the number of reserved bytes for this field is stored
> + *   at this address.
> + * @param align
> + *   If not NULL, the alignement constraint for this field is stored
> + *   at this address.
> + * @return
> + *   The offset of this field in the mbuf structure, or -1 on error
> + *   (rte_errno is set).
> + */
> +__rte_experimental
> +int rte_mbuf_dynfield_lookup(const char *name, size_t *size, size_t *align);
> +
> +/**
> + * Register a dynamic flag in the mbuf structure.
> + *
> + * @param name
> + *   A string identifying the dynamic flag. External applications or
> + *   libraries must not define identifers prefixed with "rte_", which
> + *   are reserved for standard features.
> + * @return
> + *   The number of the reserved bit, or -1 on error (rte_errno is set).
> + */
> +__rte_experimental
> +int rte_mbuf_dynflag_register(const char *name);
> +
> +/**
> + * Lookup for a registered dynamic mbuf flag.
> + *
> + * @param name
> + *   A string identifying the dynamic flag.
> + * @return
> + *   The offset of this flag in the mbuf structure, or -1 on error
> + *   (rte_errno is set).
> + */
> +__rte_experimental
> +int rte_mbuf_dynflag_lookup(const char *name);
> +
> +/**
> + * Helper macro to access to a dynamic field.
> + */
> +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((char *)(m) + (offset)))
> +
> +/**
> + * Maximum length of the dynamic field or flag string.
> + */
> +#define RTE_MBUF_DYN_NAMESIZE 32
> +
> +#endif
> diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
> index 2662a37bf..a98310570 100644
> --- a/lib/librte_mbuf/rte_mbuf_version.map
> +++ b/lib/librte_mbuf/rte_mbuf_version.map
> @@ -50,4 +50,8 @@ EXPERIMENTAL {
>  	global:
> 
>  	rte_mbuf_check;
> +	rte_mbuf_dynfield_lookup;
> +	rte_mbuf_dynfield_register;
> +	rte_mbuf_dynflag_lookup;
> +	rte_mbuf_dynflag_register;
>  } DPDK_18.08;
> --
> 2.11.0


^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [PATCH] ethdev: extend flow metadata
  2019-07-10 12:26  3%     ` Thomas Monjalon
@ 2019-07-10 16:37  3%       ` Yongseok Koh
  2019-07-11  7:44  0%         ` Adrien Mazarguil
  0 siblings, 1 reply; 200+ results
From: Yongseok Koh @ 2019-07-10 16:37 UTC (permalink / raw)
  To: Thomas Monjalon, Olivier Matz
  Cc: Bruce Richardson, Andrew Rybchenko, Adrien Mazarguil,
	Shahaf Shuler, Ferruh Yigit, dev, Slava Ovsiienko


> On Jul 10, 2019, at 5:26 AM, Thomas Monjalon <thomas@monjalon.net> wrote:
> 
> 10/07/2019 14:01, Bruce Richardson:
>> On Wed, Jul 10, 2019 at 12:07:43PM +0200, Olivier Matz wrote:
>>> On Wed, Jul 10, 2019 at 10:55:34AM +0100, Bruce Richardson wrote:
>>>> On Wed, Jul 10, 2019 at 11:31:56AM +0200, Olivier Matz wrote:
>>>>> On Thu, Jul 04, 2019 at 04:21:22PM -0700, Yongseok Koh wrote:
>>>>>> Currently, metadata can be set on egress path via mbuf tx_meatadata field
>>>>>> with PKT_TX_METADATA flag and RTE_FLOW_ITEM_TYPE_RX_META matches metadata.
>>>>>> 
>>>>>> This patch extends the usability.
>>>>>> 
>>>>>> 1) RTE_FLOW_ACTION_TYPE_SET_META
>>>>>> 
>>>>>> When supporting multiple tables, Tx metadata can also be set by a rule and
>>>>>> matched by another rule. This new action allows metadata to be set as a
>>>>>> result of flow match.
>>>>>> 
>>>>>> 2) Metadata on ingress
>>>>>> 
>>>>>> There's also need to support metadata on packet Rx. Metadata can be set by
>>>>>> SET_META action and matched by META item like Tx. The final value set by
>>>>>> the action will be delivered to application via mbuf metadata field with
>>>>>> PKT_RX_METADATA ol_flag.
>>>>>> 
>>>>>> For this purpose, mbuf->tx_metadata is moved as a separate new field and
>>>>>> renamed to 'metadata' to support both Rx and Tx metadata.
>>>>>> 
>>>>>> For loopback/hairpin packet, metadata set on Rx/Tx may or may not be
>>>>>> propagated to the other path depending on HW capability.
>>>>>> 
>>>>>> Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
>>>>> 
>>>>>> --- a/lib/librte_mbuf/rte_mbuf.h
>>>>>> +++ b/lib/librte_mbuf/rte_mbuf.h
>>>>>> @@ -648,17 +653,6 @@ struct rte_mbuf {
>>>>>> 			/**< User defined tags. See rte_distributor_process() */
>>>>>> 			uint32_t usr;
>>>>>> 		} hash;                   /**< hash information */
>>>>>> -		struct {
>>>>>> -			/**
>>>>>> -			 * Application specific metadata value
>>>>>> -			 * for egress flow rule match.
>>>>>> -			 * Valid if PKT_TX_METADATA is set.
>>>>>> -			 * Located here to allow conjunct use
>>>>>> -			 * with hash.sched.hi.
>>>>>> -			 */
>>>>>> -			uint32_t tx_metadata;
>>>>>> -			uint32_t reserved;
>>>>>> -		};
>>>>>> 	};
>>>>>> 
>>>>>> 	/** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ is set. */
>>>>>> @@ -727,6 +721,11 @@ struct rte_mbuf {
>>>>>> 	 */
>>>>>> 	struct rte_mbuf_ext_shared_info *shinfo;
>>>>>> 
>>>>>> +	/** Application specific metadata value for flow rule match.
>>>>>> +	 * Valid if PKT_RX_METADATA or PKT_TX_METADATA is set.
>>>>>> +	 */
>>>>>> +	uint32_t metadata;
>>>>>> +
>>>>>> } __rte_cache_aligned;
>>>>> 
>>>>> This will break the ABI, so we cannot put it in 19.08, and we need a
>>>>> deprecation notice.
>>>>> 
>>>> Does it actually break the ABI? Adding a new field to the mbuf should only
>>>> break the ABI if it either causes new fields to move or changes the
>>>> structure size. Since this is at the end, it's not going to move any older
>>>> fields, and since everything is cache-aligned I don't think the structure
>>>> size changes either.
>>> 
>>> I think it does break the ABI: in previous version, when the PKT_TX_METADATA
>>> flag is set, the associated value is put in m->tx_metadata (offset 44 on
>>> x86-64), and in the next version, it will be in m->metadata (offset 112). So,
>>> these 2 versions are not binary compatible.
>>> 
>>> Anyway, at least it breaks the API.
>> 
>> Ok, I misunderstood. I thought it was the structure change itself you were
>> saying broke the ABI. Yes, putting the data in a different place is indeed
>> an ABI break.
> 
> We could add the new field and keep the old one unused,
> so it does not break the ABI.

Still breaks ABI if PKT_TX_METADATA is set. :-) In order not to break it, I can
keep the current union'd field (tx_metadata) as is with PKT_TX_METADATA, add
the new one at the end and make it used with the new PKT_RX_METADATA.

> However I suppose everybody will prefer a version using dynamic fields.
> Is someone against using dynamic field for such usage?

However, given that the amazing dynamic fields is coming soon (thanks for your
effort, Olivier and Thomas!), I'd be honored to be the first user of it.

Olivier, I'll take a look at your RFC.


Thanks,
Yongseok


^ permalink raw reply	[relevance 3%]

* [dpdk-dev]  devtools: fix symbol change file matching
@ 2019-07-10  9:57  3% Bing Zhao
  0 siblings, 0 replies; 200+ results
From: Bing Zhao @ 2019-07-10  9:57 UTC (permalink / raw)
  To: nhorman; +Cc: dev, stable

The previous regex miss a situation that a new file is added after
the map file. It will starts with '/dev/null' instead of 'a /', so
all the content in the patch file after 'map' will be considered in
the symbol map file. Also, a second regex matching is used for map
and other files, the '^map' in square brackets is not quite exact
the same with the design even if it works.

Fixes: 4bec48184e33 ("devtools: add checks for ABI symbol addition")
Cc: nhorman@tuxdriver.com

Signed-off-by: Bing Zhao <bingz@mellanox.com>
---
 devtools/check-symbol-change.sh | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index c5434f3..eac71f3 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -11,19 +11,32 @@ build_map_changes()
 		# Initialize our variables
 		BEGIN {map="";sym="";ar="";sec=""; in_sec=0; in_map=0}
 
-		# Anything that starts with + or -, followed by an a
+		# Anything that starts with + or -, followed by an a or b
 		# and ends in the string .map is the name of our map file
 		# This may appear multiple times in a patch if multiple
 		# map files are altered, and all section/symbol names
 		# appearing between a triggering of this rule and the
 		# next trigger of this rule are associated with this file
-		/[-+] a\/.*\.map/ {map=$2; in_map=1}
 
 		# Same pattern as above, only it matches on anything that
-		# does not end in 'map', indicating we have left the map chunk.
+		# does not end in "map", indicating we have left the map chunk.
 		# When we hit this, turn off the in_map variable, which
 		# supresses the subordonate rules below
-		/[-+] a\/.*\.[^map]/ {in_map=0}
+		# Currently, using the same pattern for all the files matching,
+		# and a second RE matching is used to distinguish map files from
+		# other types of files
+		/[-+] [ab]\/.*\.[[:alnum:]]+$/ {
+			if ($2 ~ /\.map$/) {
+				if (in_map == 0) {in_map = 1}
+			} else {
+				if (in_map == 1) {in_map = 0}
+			}
+		}
+
+		# Indeed, this RE matching has no use. The only purpose here
+		# is to remind that the git will have a third file pattern
+		# "-+ /dev/null" besides "-a /" and "+b /"
+		/[-+] \/dev\/null$/ {next}
 
 		# Triggering this rule, which starts a line and ends it
 		# with a { identifies a versioned section.  The section name is
-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [PATCH] ethdev: extend flow metadata
  @ 2019-07-10 12:26  3%     ` Thomas Monjalon
  2019-07-10 16:37  3%       ` Yongseok Koh
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-07-10 12:26 UTC (permalink / raw)
  To: Bruce Richardson, Olivier Matz, arybchenko, adrien.mazarguil
  Cc: Yongseok Koh, shahafs, ferruh.yigit, dev, viacheslavo

10/07/2019 14:01, Bruce Richardson:
> On Wed, Jul 10, 2019 at 12:07:43PM +0200, Olivier Matz wrote:
> > On Wed, Jul 10, 2019 at 10:55:34AM +0100, Bruce Richardson wrote:
> > > On Wed, Jul 10, 2019 at 11:31:56AM +0200, Olivier Matz wrote:
> > > > On Thu, Jul 04, 2019 at 04:21:22PM -0700, Yongseok Koh wrote:
> > > > > Currently, metadata can be set on egress path via mbuf tx_meatadata field
> > > > > with PKT_TX_METADATA flag and RTE_FLOW_ITEM_TYPE_RX_META matches metadata.
> > > > > 
> > > > > This patch extends the usability.
> > > > > 
> > > > > 1) RTE_FLOW_ACTION_TYPE_SET_META
> > > > > 
> > > > > When supporting multiple tables, Tx metadata can also be set by a rule and
> > > > > matched by another rule. This new action allows metadata to be set as a
> > > > > result of flow match.
> > > > > 
> > > > > 2) Metadata on ingress
> > > > > 
> > > > > There's also need to support metadata on packet Rx. Metadata can be set by
> > > > > SET_META action and matched by META item like Tx. The final value set by
> > > > > the action will be delivered to application via mbuf metadata field with
> > > > > PKT_RX_METADATA ol_flag.
> > > > > 
> > > > > For this purpose, mbuf->tx_metadata is moved as a separate new field and
> > > > > renamed to 'metadata' to support both Rx and Tx metadata.
> > > > > 
> > > > > For loopback/hairpin packet, metadata set on Rx/Tx may or may not be
> > > > > propagated to the other path depending on HW capability.
> > > > > 
> > > > > Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
> > > > 
> > > > > --- a/lib/librte_mbuf/rte_mbuf.h
> > > > > +++ b/lib/librte_mbuf/rte_mbuf.h
> > > > > @@ -648,17 +653,6 @@ struct rte_mbuf {
> > > > >  			/**< User defined tags. See rte_distributor_process() */
> > > > >  			uint32_t usr;
> > > > >  		} hash;                   /**< hash information */
> > > > > -		struct {
> > > > > -			/**
> > > > > -			 * Application specific metadata value
> > > > > -			 * for egress flow rule match.
> > > > > -			 * Valid if PKT_TX_METADATA is set.
> > > > > -			 * Located here to allow conjunct use
> > > > > -			 * with hash.sched.hi.
> > > > > -			 */
> > > > > -			uint32_t tx_metadata;
> > > > > -			uint32_t reserved;
> > > > > -		};
> > > > >  	};
> > > > >  
> > > > >  	/** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ is set. */
> > > > > @@ -727,6 +721,11 @@ struct rte_mbuf {
> > > > >  	 */
> > > > >  	struct rte_mbuf_ext_shared_info *shinfo;
> > > > >  
> > > > > +	/** Application specific metadata value for flow rule match.
> > > > > +	 * Valid if PKT_RX_METADATA or PKT_TX_METADATA is set.
> > > > > +	 */
> > > > > +	uint32_t metadata;
> > > > > +
> > > > >  } __rte_cache_aligned;
> > > > 
> > > > This will break the ABI, so we cannot put it in 19.08, and we need a
> > > > deprecation notice.
> > > > 
> > > Does it actually break the ABI? Adding a new field to the mbuf should only
> > > break the ABI if it either causes new fields to move or changes the
> > > structure size. Since this is at the end, it's not going to move any older
> > > fields, and since everything is cache-aligned I don't think the structure
> > > size changes either.
> > 
> > I think it does break the ABI: in previous version, when the PKT_TX_METADATA
> > flag is set, the associated value is put in m->tx_metadata (offset 44 on
> > x86-64), and in the next version, it will be in m->metadata (offset 112). So,
> > these 2 versions are not binary compatible.
> > 
> > Anyway, at least it breaks the API.
> 
> Ok, I misunderstood. I thought it was the structure change itself you were
> saying broke the ABI. Yes, putting the data in a different place is indeed
> an ABI break.

We could add the new field and keep the old one unused,
so it does not break the ABI.
However I suppose everybody will prefer a version using dynamic fields.
Is someone against using dynamic field for such usage?



^ permalink raw reply	[relevance 3%]

Results 7801-8000 of ~18000   |  | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2018-04-26 22:03     [dpdk-dev] [PATCH v4 0/4] lib/rib: Add Routing Information Base library Medvedkin Vladimir
2019-09-11 17:09  2% ` [dpdk-dev] [PATCH v5 00/12] lib: add RIB and FIB liraries Vladimir Medvedkin
2019-09-12  7:37  0%   ` Morten Brørup
2019-09-12  9:47  0%     ` Medvedkin, Vladimir
2018-12-12  6:24     [dpdk-dev] [PATCH v1 0/2] add rte_ring_reset and use it to flush a ring Gavin Hu
2019-03-15  3:31     ` [dpdk-dev] [PATCH v7 1/2] ring: add reset API to flush the ring when not in use Gavin Hu
2019-03-29 14:17       ` Olivier Matz
2019-07-04 14:42         ` Thomas Monjalon
2019-07-12  9:32  0%       ` Gavin Hu (Arm Technology China)
2019-07-12  9:53  0%         ` Olivier Matz
2019-07-12 11:06  0%           ` Gavin Hu (Arm Technology China)
2019-07-12 11:48  3%             ` Olivier Matz
2019-07-12 15:07  0%               ` Gavin Hu (Arm Technology China)
2019-07-12 15:40  0%                 ` Honnappa Nagarahalli
2019-07-12 16:01  0%                   ` Gavin Hu (Arm Technology China)
2019-07-12  9:26  3% ` [dpdk-dev] [PATCH v8 0/2] new ring reset api and use it by hash Gavin Hu
2019-07-12 15:54  3% ` [dpdk-dev] [PATCH v9 " Gavin Hu
2019-07-16 19:23  3% ` [dpdk-dev] [PATCH v10 " Gavin Hu
2019-04-05 20:30     [dpdk-dev] [PATCH] eal: resort symbols in EXPERIMENTAL section Stephen Hemminger
2019-06-14  7:39     ` Thomas Monjalon
2019-06-14  7:44       ` David Marchand
2019-06-14 15:32         ` Ferruh Yigit
2019-06-20 17:23           ` David Marchand
2019-07-26 13:54  0%         ` David Marchand
2019-04-16  1:59     [dpdk-dev] [PATCH] fbarray: get fbarrays from containerized secondary ogawa.yasufumi
2019-04-16  3:43     ` [dpdk-dev] [PATCH v2 0/1] Get " ogawa.yasufumi
2019-04-16  3:43       ` [dpdk-dev] [PATCH v2 1/1] fbarray: get " ogawa.yasufumi
2019-07-05  8:53         ` Burakov, Anatoly
2019-07-09 10:22           ` Yasufumi Ogawa
2019-07-09 10:24             ` Burakov, Anatoly
2019-07-09 10:26               ` Burakov, Anatoly
2019-07-11  9:37  0%             ` Yasufumi Ogawa
2019-07-11  9:43  3%               ` Burakov, Anatoly
2019-05-25 18:43     [dpdk-dev] [RFC PATCH 0/2] introduce __rte_internal tag Neil Horman
2019-06-13 14:23     ` [dpdk-dev] [PATCH v2 0/10] dpdk: " Neil Horman
2019-08-06 10:03  0%   ` Thomas Monjalon
2019-08-06 12:21  0%     ` Neil Horman
2019-06-03 21:32     [dpdk-dev] [RFC 1/3] ethdev: extend flow metadata Yongseok Koh
2019-07-10 10:07     ` [dpdk-dev] [PATCH] " Olivier Matz
2019-07-10 12:01       ` Bruce Richardson
2019-07-10 12:26  3%     ` Thomas Monjalon
2019-07-10 16:37  3%       ` Yongseok Koh
2019-07-11  7:44  0%         ` Adrien Mazarguil
2019-07-14 11:46  0%           ` Andrew Rybchenko
2019-07-29 15:06  0%             ` Adrien Mazarguil
2019-06-23  2:41     [dpdk-dev] [PATCH v1 1/3] eal/arm64: add 128-bit atomic compare exchange Phil Yang
2019-06-28  8:11     ` [dpdk-dev] [PATCH v3 " Phil Yang
2019-07-19  6:24  4%   ` [dpdk-dev] [EXT] " Jerin Jacob Kollanukkaran
2019-07-19 11:01  0%     ` Phil Yang (Arm Technology China)
2019-07-19 12:35  0%       ` Jerin Jacob Kollanukkaran
2019-07-19 13:56  0%         ` Phil Yang (Arm Technology China)
2019-07-22  8:44  2% ` [dpdk-dev] [PATCH v4 " Phil Yang
2019-07-22 13:06  2% ` [dpdk-dev] [PATCH v5 " Phil Yang
2019-07-22 16:22  2% ` [dpdk-dev] [PATCH v6 " Phil Yang
2019-07-23  5:57  2% ` [dpdk-dev] [PATCH v7 " Phil Yang
2019-07-23  7:05  2%   ` [dpdk-dev] [PATCH v8 " jerinj
2019-08-14  8:27  2%     ` [dpdk-dev] [PATCH v9 " Phil Yang
2019-07-04  4:43     [dpdk-dev] [PATCH] doc: announce ABI change for RSS hash funtion simei
2019-08-06 11:34  4% ` Thomas Monjalon
2019-08-06 14:45  4%   ` Ananyev, Konstantin
2019-08-10 20:39  4%     ` Thomas Monjalon
2019-07-04  4:46     [dpdk-dev] [PATCH] doc: announce ABI change for rte flow RSS action simei
2019-08-06 11:31  4% ` Thomas Monjalon
2019-08-06 11:38  4%   ` Zhang, Qi Z
2019-08-06 11:40  4%   ` Zhang, Qi Z
2019-07-04 12:26     [dpdk-dev] [PATCH] Changes to ABI Policy introducing major ABI versions Ray Kinsella
2019-07-04 12:26     ` [dpdk-dev] [PATCH] doc: " Ray Kinsella
2019-07-30 10:34 10%   ` Mcnamara, John
2019-07-30 10:35  5%     ` Ray Kinsella
2019-07-05  9:33     [dpdk-dev] [RFC PATCH 0/2] standardize rawdev names Bruce Richardson
2019-07-30 13:39     ` [dpdk-dev] [PATCH v2 " Thomas Monjalon
2019-07-30 13:39  7%   ` [dpdk-dev] [PATCH v2 2/2] drivers/raw: standardize naming Thomas Monjalon
2019-07-31  7:29  0%     ` Xu, Rosen
2019-07-05 13:58     [dpdk-dev] [PATCH v2] devtools: better freebsd support Olivier Matz
2019-07-11 14:25  6% ` [dpdk-dev] [PATCH v3] " Olivier Matz
2019-07-29  8:31  0%   ` David Marchand
2019-07-29  8:36  0%     ` David Marchand
2019-07-09 11:09     [dpdk-dev] [PATCH] librte_flow_classify: fix out-of-bounds access Bernard Iremonger
2019-07-10 21:48     ` Thomas Monjalon
2019-07-29 13:09       ` David Marchand
2019-07-30 14:42         ` Aaron Conole
2019-07-30 14:48           ` [dpdk-dev] [dpdk-stable] " Ferruh Yigit
2019-07-30 15:43  2%         ` Aaron Conole
2019-07-30 16:55  0%           ` Ferruh Yigit
2019-07-30 17:30  0%             ` Aaron Conole
2019-07-10  9:29     [dpdk-dev] [RFC] mbuf: support dynamic fields and flags Olivier Matz
2019-07-10 17:14  0% ` Wang, Haiyue
2019-07-11  7:26  0%   ` Olivier Matz
2019-07-11  8:04  0%     ` Wang, Haiyue
2019-07-11  8:20  0%       ` Olivier Matz
2019-07-11  8:34  0%         ` Wang, Haiyue
2019-07-10 17:49  3% ` Stephen Hemminger
2019-07-10 18:12  0%   ` Wiles, Keith
2019-07-11  7:53  4%     ` Olivier Matz
2019-07-11 14:37  0%       ` Wiles, Keith
2019-07-12  9:06  0%         ` Olivier Matz
2019-07-11  7:36  0%   ` Olivier Matz
2019-07-12 12:23         ` Jerin Jacob Kollanukkaran
2019-07-16  9:39           ` Olivier Matz
2019-07-16 14:43  3%         ` Stephen Hemminger
2019-07-11  9:24  3% ` Thomas Monjalon
2019-07-12 14:54  0% ` Andrew Rybchenko
2019-07-16  9:49  0%   ` Olivier Matz
2019-07-16 11:31  0%     ` [dpdk-dev] ***Spam*** " Andrew Rybchenko
2019-07-10  9:57  3% [dpdk-dev] devtools: fix symbol change file matching Bing Zhao
2019-07-15 23:41     [dpdk-dev] [PATCH] pci: fix missing pci bus with shared library build Stephen Hemminger
2019-07-22 17:04     ` Thomas Monjalon
2019-07-22 17:13       ` Stephen Hemminger
2019-07-22 17:31         ` Thomas Monjalon
2019-07-22 18:53           ` Stephen Hemminger
2019-07-23 12:30             ` Bruce Richardson
2019-07-23 18:11               ` Stephen Hemminger
2019-07-24  8:56  3%             ` Bruce Richardson
2019-07-16 18:52     [dpdk-dev] [PATCH v3 00/11] Rework API for RSA algorithm in asymmetric crypto Arek Kusztal
2019-07-16 18:52     ` [dpdk-dev] [PATCH v3 04/11] test: add cipher field to RSA test Arek Kusztal
2019-07-17  7:41       ` [dpdk-dev] [EXT] " Shally Verma
2019-07-17  9:42         ` Kusztal, ArkadiuszX
2019-07-17 12:54           ` Shally Verma
2019-07-18 12:44  3%         ` Trahe, Fiona
2019-07-17  7:45     [dpdk-dev] [PATCH] app/testpmd: support QinQ strip offload viveksharma
2019-07-19 16:53     ` Ferruh Yigit
2019-07-22 12:04       ` Iremonger, Bernard
2019-07-22 14:26         ` Ferruh Yigit
2019-07-22 14:55           ` Iremonger, Bernard
2019-07-22 15:40  3%         ` Ferruh Yigit
2019-07-22 17:03  0%           ` Iremonger, Bernard
2019-07-22 17:16  0%             ` Ferruh Yigit
2019-07-17  9:04     [dpdk-dev] [PATCH v7 0/4] kni: add IOVA=VA support vattunuru
2019-07-23  5:38     ` [dpdk-dev] [PATCH v8 0/5] " vattunuru
2019-07-23  5:38  3%   ` [dpdk-dev] [PATCH v8 3/5] kni: add app specific mempool create & free routine vattunuru
2019-07-23 10:50  0%     ` Andrew Rybchenko
2019-07-23 11:01  0%       ` Vamsi Krishna Attunuru
2019-07-29 12:13       ` [dpdk-dev] [PATCH v9 0/5] kni: add IOVA=VA support vattunuru
2019-07-29 12:13  3%     ` [dpdk-dev] [PATCH v9 3/5] kni: add app specific mempool create & free routine vattunuru
2019-07-17 12:34     [dpdk-dev] [RFC] mark asym session-buffer non-reuseable Ayuj Verma
2019-07-17 14:10     ` Kusztal, ArkadiuszX
2019-07-18  9:47       ` Ayuj Verma
2019-07-19 14:50  3%     ` Ayuj Verma
2019-07-19 15:38  3%       ` Trahe, Fiona
2019-07-17 18:40  7% [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI pbhagavatula
2019-07-18  5:53  4% ` Jerin Jacob Kollanukkaran
2019-07-18  6:51  7% ` [dpdk-dev] [PATCH v2] mempool/octeontx2: fix possible ABI break with force inline pbhagavatula
2019-07-18  8:04  4%   ` Jerin Jacob Kollanukkaran
2019-07-18 22:15  4%     ` Thomas Monjalon
2019-07-18 14:43  8% ` [dpdk-dev] [PATCH] mempool/octeontx2: use noinline to preserve ABI Stephen Hemminger
2019-07-18 14:49  7%   ` [dpdk-dev] [EXT] " Pavan Nikhilesh Bhagavatula
2019-07-18 16:09     [dpdk-dev] [PATCH v5 0/7] Rework API for RSA algorithm in asymmetric crypto Arek Kusztal
2019-07-18 16:09     ` [dpdk-dev] [PATCH v5 2/7] cryptodev: add cipher field to RSA op Arek Kusztal
2019-07-19  4:42       ` [dpdk-dev] [EXT] " Shally Verma
2019-07-19  5:10  3%     ` Kusztal, ArkadiuszX
2019-07-23  9:13  3% [dpdk-dev] [PATCH] ethdev: avoid usage of uninit device info in bad port case Andrew Rybchenko
2019-07-23 10:40  0% ` Ferruh Yigit
2019-07-23 12:16  3%   ` Andrew Rybchenko
2019-07-23 12:50  0%     ` Thomas Monjalon
2019-07-23 12:11  3% ` [dpdk-dev] [PATCH v2] " Andrew Rybchenko
2019-07-23 13:14  0%   ` Thomas Monjalon
2019-07-23 13:34  0%     ` Andrew Rybchenko
2019-07-23 13:39  0%       ` Thomas Monjalon
2019-07-23 18:45  0%         ` Thomas Monjalon
2019-07-24 15:35     [dpdk-dev] [RFC] kni: support allmulticast mode set Xiaolong Ye
2019-07-29 13:38  4% ` Ferruh Yigit
2019-07-29 15:25  3%   ` Ye Xiaolong
2019-07-24 22:22  4% [dpdk-dev] [dpdk-announce] You're Invited: DPDK Userspace, Sept. 19-20, Bordeaux, France Jill Lovato
2019-07-26  0:35     [dpdk-dev] [RFC,v2] ethdev: extend RSS offload types simei
2019-07-29  2:44     ` [dpdk-dev] [RFC,v3] " simei
2019-07-30  6:06       ` Ori Kam
2019-07-30  7:42  4%     ` Adrien Mazarguil
2019-07-29 12:13     [dpdk-dev] [PATCH v9 1/5] mempool: populate mempool with the page sized chunks of memory vattunuru
2019-08-16  6:12     ` [dpdk-dev] [PATCH v10 0/5] kni: add IOVA=VA support vattunuru
2019-08-16  6:12  3%   ` [dpdk-dev] [PATCH v10 3/5] kni: add app specific mempool create and free routines vattunuru
2019-07-30 12:49     [dpdk-dev] [RFC 19.11 0/2] Hide DPDK internal struct from public API Marcin Zapolski
2019-07-30 12:49     ` [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline Marcin Zapolski
2019-07-30 15:01  3%   ` Jerin Jacob Kollanukkaran
2019-07-30 15:32  0%     ` Bruce Richardson
2019-09-06 13:18     ` [dpdk-dev] [RFC 19.11 v2 0/3] Hide DPDK internal struct from public API Marcin Zapolski
2019-09-06 14:00  3%   ` Bruce Richardson
2019-07-30 13:24 14% [dpdk-dev] [PATCH v1] doc: update release notes for 19.08 John McNamara
2019-07-30 15:45  0% [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline Jerin Jacob Kollanukkaran
2019-07-30 16:05  5% ` Bruce Richardson
2019-07-30 16:24  3%   ` [dpdk-dev] [EXT] " Jerin Jacob Kollanukkaran
2019-07-31 11:06  5% [dpdk-dev] [PATCH] doc: announce lcore_config symbol removal David Marchand
2019-07-31 13:48  0% ` Stephen Hemminger
2019-08-08  9:31  5% ` [dpdk-dev] [PATCH v2] " David Marchand
2019-08-02 15:38 11% [dpdk-dev] [PATCH v2 0/3] doc: changes to abi policy introducing major abi versions Ray Kinsella
2019-08-02 15:38 13% ` [dpdk-dev] [PATCH v2 1/3] doc: separate versioning.rst into version and policy Ray Kinsella
2019-08-02 15:38 32% ` [dpdk-dev] [PATCH v2 2/3] doc: changes to abi policy introducing major abi versions Ray Kinsella
2019-08-02 15:38 28% ` [dpdk-dev] [PATCH v2 3/3] doc: updates to versioning guide for " Ray Kinsella
2019-08-05 12:30 11% [dpdk-dev] [PATCH] doc: remove major in designation of normal releases Thomas Monjalon
2019-08-06 14:56  4% [dpdk-dev] [PATCH 1/2] doc: announce ethdev ABI change for LRO fields Matan Azrad
2019-08-06 15:27  4% ` Andrew Rybchenko
2019-08-10 21:40  4%   ` Thomas Monjalon
2019-08-07  2:04  3% [dpdk-dev] [RFC 0/3] ethdev: add ptype as Rx offload Jerin Jacob Kollanukkaran
2019-08-07  8:32  0% ` Andrew Rybchenko
2019-08-07 15:22  0%   ` Stephen Hemminger
2019-08-07 15:44  0%     ` Andrew Rybchenko
2019-08-07 10:12     [dpdk-dev] [PATCH] eal: change max hugepage sizes to 4 Gagandeep Singh
2019-08-07 12:07     ` Thomas Monjalon
2019-08-07 13:28       ` Hemant Agrawal
2019-08-08  7:31         ` Thomas Monjalon
2019-08-12  9:43  3%       ` Burakov, Anatoly
2019-08-12  9:49  0%         ` David Marchand
2019-08-12 10:01  0%           ` Thomas Monjalon
2019-08-12 10:38  0%           ` Burakov, Anatoly
2019-08-08  8:12  4% [dpdk-dev] 19.11 Intel Roadmap O'Driscoll, Tim
2019-08-09  8:17     [dpdk-dev] [patch v4] doc: announce API change in ethdev offload flags pbhagavatula
2019-08-09  9:55     ` [dpdk-dev] [patch v5] " pbhagavatula
2019-08-09 10:13       ` Ananyev, Konstantin
2019-08-10 21:10  3%     ` Thomas Monjalon
2019-08-12 11:43  6% [dpdk-dev] [PATCH] version: 19.11-rc0 David Marchand
2019-08-13 12:18  6% ` [dpdk-dev] [PATCH v2] " David Marchand
2019-08-12 14:15     [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field Haiyue Wang
2019-08-12 14:15     ` [dpdk-dev] [RFC v1 1/3] ethdev: add the Rx/Tx burst description field in queue information Haiyue Wang
2019-08-12 15:37  3%   ` Stephen Hemminger
2019-08-12 14:27     ` [dpdk-dev] [RFC v1 0/3] show the Rx/Tx burst description field David Marchand
2019-08-12 15:38  3%   ` Stephen Hemminger
2019-08-12 15:42  0%     ` Wang, Haiyue
2019-08-12 15:54  0%       ` Stephen Hemminger
2019-08-12 16:00  0%         ` Wang, Haiyue
2019-08-12 17:28  0%           ` Stephen Hemminger
2019-08-12 17:36  0%             ` Wang, Haiyue
2019-08-13  3:06  3% [dpdk-dev] [RFC v2 " Haiyue Wang
2019-08-13 10:02     [dpdk-dev] [PATCH 0/2] IXGBE vPMD changes for aarch64 Ruifeng Wang
2019-08-25  1:33     ` Ye Xiaolong
2019-08-26  2:52       ` Ruifeng Wang (Arm Technology China)
2019-08-26 10:39  3%     ` Ferruh Yigit
2019-08-26 10:53  0%       ` Ruifeng Wang (Arm Technology China)
2019-08-13 13:37     [dpdk-dev] [RFC] ethdev: support hairpin queue Ori Kam
2019-09-05  4:00  3% ` Wu, Jingjing
2019-09-05  5:44  0%   ` Ori Kam
2019-09-06  3:08  0%     ` Wu, Jingjing
2019-09-08  6:44  0%       ` Ori Kam
2019-08-14  3:00     [dpdk-dev] [PATCH] ethdev: add more protocol support in flow API Wang Ying A
2019-08-14  3:24     ` [dpdk-dev] [PATCH v2] " Wang Ying A
2019-08-14  9:08  4%   ` Adrien Mazarguil
2019-08-19 11:53  0%     ` Zhang, Qi Z
2019-08-15 10:23 11% [dpdk-dev] [PATCH v3 0/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
2019-08-15 10:23 13% ` [dpdk-dev] [PATCH v3 1/4] doc: separate versioning.rst into version and policy Ray Kinsella
2019-08-15 10:23 31% ` [dpdk-dev] [PATCH v3 2/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
2019-08-30 16:20 10%   ` Kevin Traynor
2019-08-15 10:23 30% ` [dpdk-dev] [PATCH v3 3/4] doc: updates to versioning guide for " Ray Kinsella
2019-08-15 10:23 13% ` [dpdk-dev] [PATCH v3 4/4] doc: add maintainer for abi policy Ray Kinsella
2019-08-15 15:06     [dpdk-dev] [RFC] ethdev: configure SR-IOV VF from host Thomas Monjalon
2019-08-15 15:34  3% ` Jerin Jacob Kollanukkaran
2019-08-15 17:59  0%   ` Thomas Monjalon
2019-08-16  5:16  0% Jerin Jacob Kollanukkaran
2019-08-19 11:41     [dpdk-dev] [PATCH 00/11] Fixing log levels for dynamically loaded drivers David Marchand
2019-08-19 11:41     ` [dpdk-dev] [PATCH 02/11] log: define logtype register wrapper for drivers David Marchand
2019-09-02 14:29       ` Ferruh Yigit
2019-09-03  8:06  4%     ` David Marchand
2019-09-03  8:47  3%       ` Ferruh Yigit
2019-09-04 17:45  0%         ` Thomas Monjalon
2019-08-22  8:42     [dpdk-dev] [PATCH v3] timer: use rte_mp_msg to get freq from primary process Jim Harris
2019-08-27 16:16  3% ` [dpdk-dev] [PATCH v6] eal: add tsc_hz to rte_mem_config Jim Harris
2019-08-22 16:07  9% [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test Ray Kinsella
2019-08-22 16:07 14% ` [dpdk-dev] [PATCH v2 1/2] app/test: add abi version testing functionality Ray Kinsella
2019-08-22 16:07  4% ` [dpdk-dev] [PATCH v2 2/2] app/test: lpm abi version testing Ray Kinsella
2019-08-23 15:49  4% ` [dpdk-dev] [PATCH v2 0/2] add abi version testing to app/test Aaron Conole
2019-08-26 16:45  9%   ` Ray Kinsella
2019-08-27  8:17  7%     ` Bruce Richardson
2019-08-27  8:28  8%       ` Ray Kinsella
2019-08-27 14:19  7%         ` Ray Kinsella
2019-08-23 14:45     [dpdk-dev] [PATCH 00/15] sched: subport level configuration of pipe nodes Jasvinder Singh
2019-08-23 14:46  4% ` [dpdk-dev] [PATCH 15/15] sched: remove redundant code Jasvinder Singh
2019-09-09 10:05     ` [dpdk-dev] [PATCH v2 00/15] sched: subport level configuration of pipe nodes Jasvinder Singh
2019-09-09 10:05  4%   ` [dpdk-dev] [PATCH v2 15/15] sched: remove redundant code Jasvinder Singh
2019-08-27 14:25     [dpdk-dev] [PATCH 00/51] ethdev: change rte_eth_dev_info_get() return value to int Andrew Rybchenko
2019-08-27 14:25  3% ` [dpdk-dev] [PATCH 01/51] " Andrew Rybchenko
2019-09-03 13:56     ` [dpdk-dev] [PATCH v2 00/54] " Andrew Rybchenko
2019-09-03 13:56  3%   ` [dpdk-dev] [PATCH v2 02/54] " Andrew Rybchenko
2019-09-06  7:30     ` [dpdk-dev] [PATCH v3 00/54] " Andrew Rybchenko
2019-09-06  7:30  3%   ` [dpdk-dev] [PATCH v3 02/54] " Andrew Rybchenko
2019-09-12 16:42     ` [dpdk-dev] [PATCH v4 00/54] " Andrew Rybchenko
2019-09-12 16:42  3%   ` [dpdk-dev] [PATCH v4 02/54] " Andrew Rybchenko
2019-09-13 10:18  0%     ` Iremonger, Bernard
2019-08-28  6:51     [dpdk-dev] [RFC] hash: introduce resizable hash list Bing Zhao
2019-08-28  6:51     ` [dpdk-dev] [RFC] rte_hash: introduce hash list into hash lib Bing Zhao
2019-08-28 11:53  3%   ` Stephen Hemminger
2019-08-29  7:59     [dpdk-dev] [PATCH 00/15] Introduce Virtio vDPA driver Maxime Coquelin
2019-08-29  7:59  4% ` [dpdk-dev] [PATCH 04/15] net/virtio: add virtio PCI subsystem device ID declaration Maxime Coquelin
2019-09-02  6:14  0%   ` Tiwei Bie
2019-09-03  7:25  0%     ` Maxime Coquelin
2019-09-03 15:40     [dpdk-dev] [RFC PATCH 0/9] security: add software synchronous crypto process Fan Zhang
2019-09-03 15:40     ` [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API Fan Zhang
2019-09-04 10:32       ` Akhil Goyal
2019-09-04 13:06         ` Zhang, Roy Fan
2019-09-06  9:01           ` Akhil Goyal
2019-09-06 13:27  4%         ` Ananyev, Konstantin
2019-09-10 10:44  4%           ` Akhil Goyal
2019-09-11 12:29  4%             ` Ananyev, Konstantin
2019-09-12 14:12  5%               ` Akhil Goyal
2019-09-16 14:53  3%                 ` Ananyev, Konstantin
2019-09-16 15:08  0%                   ` Ananyev, Konstantin
2019-09-17  6:02  3%                   ` Akhil Goyal
2019-09-05 15:47  6% [dpdk-dev] [PATCH 1/2] version: 19.11-rc0 agupta3
2019-09-05 16:10     [dpdk-dev] [PATCH 00/13] ethdev: change promiscuous mode functions to return status Andrew Rybchenko
2019-09-05 16:10  3% ` [dpdk-dev] [PATCH 01/13] ethdev: change promiscuous mode controllers to return errors Andrew Rybchenko
2019-09-09 11:58     ` [dpdk-dev] [PATCH v2 00/13] ethdev: change promiscuous mode functions to return status Andrew Rybchenko
2019-09-09 11:58  3%   ` [dpdk-dev] [PATCH v2 01/13] ethdev: change promiscuous mode controllers to return errors Andrew Rybchenko
2019-09-14 11:37     ` [dpdk-dev] [PATCH v3 00/13] ethdev: change promiscuous mode functions to return status Andrew Rybchenko
2019-09-14 11:37  3%   ` [dpdk-dev] [PATCH v3 01/13] ethdev: change promiscuous mode controllers to return errors Andrew Rybchenko
2019-09-06 14:34     [dpdk-dev] [PATCH 0/2] ethdev: change xstats reset function return value to int Andrew Rybchenko
2019-09-06 14:34  4% ` [dpdk-dev] [PATCH 1/2] " Andrew Rybchenko
     [not found]     <20190806182500.22320>
2019-08-29 14:12     ` [dpdk-dev] [PATCH v6 00/10] vhost: support inflight share memory protocol feature JinYu
2019-08-29 14:12       ` [dpdk-dev] [PATCH v6 02/10] vhost: add packed ring JinYu
2019-09-06 16:42  3%     ` Maxime Coquelin
2019-09-09 12:13     [dpdk-dev] [PATCH 0/7] ethdev: change allmulticast controls to return status Andrew Rybchenko
2019-09-09 12:13  4% ` [dpdk-dev] [PATCH 1/7] ethdev: change allmulticast mode controllers to return errors Andrew Rybchenko
2019-09-10  8:25     [dpdk-dev] [PATCH 00/18] ethdev: change link status get functions return value to int Andrew Rybchenko
2019-09-10  8:25  3% ` [dpdk-dev] [PATCH 02/18] " Andrew Rybchenko
2019-09-10  8:52     [dpdk-dev] [PATCH 0/7] ethdev: change MAC addr get function " Andrew Rybchenko
2019-09-10  8:52  4% ` [dpdk-dev] [PATCH 1/7] " Andrew Rybchenko
2019-09-10  9:02     [dpdk-dev] [PATCH 0/1] ethdev: change owner delete " Andrew Rybchenko
2019-09-10  9:02  4% ` [dpdk-dev] [PATCH 1/1] " Andrew Rybchenko
2019-09-10 16:33  3% [dpdk-dev] [RFC v3 0/4] get Rx/Tx packet burst mode information Haiyue Wang
2019-09-11  9:19     [dpdk-dev] [PATCH] mbuf: add bulk free function Morten Brørup
2019-09-11 11:18     ` Stephen Hemminger
2019-09-11 11:33       ` Olivier Matz
2019-09-11 11:39  3%     ` Stephen Hemminger
2019-09-11 15:04  5% [dpdk-dev] DPDK techboard minutes of July 31 Maxime Coquelin
2019-09-11 15:05  3% [dpdk-dev] DPDK techboard minutes (2019-07-17) Olivier Matz
2019-09-12 16:46  5% [dpdk-dev] DPDK techboard minutes of September 11 Thomas Monjalon
2019-09-13 13:32     [dpdk-dev] The type string in the malloc library is unused Morten Brørup
     [not found]     ` <CAOaVG17_bhBOfJdvHZOzoVO3t7CXCZCa7f=_Q=_Pi5jgnY3GzA@mail.gmail.com>
2019-09-14  8:29  3%   ` Morten Brørup

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).