* Re: Hyper-v support
From: Thomas Monjalon @ 2016-12-06 21:25 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Varun, dev
In-Reply-To: <20161206122531.4d147748@xeon-e3>
2016-12-06 12:25, Stephen Hemminger:
> 2016-12-01 12:21, Thomas Monjalon:
> > 2016-11-30 14:34, Varun:
> > > Hi,
> > >
> > > I would like to know if the latest DPDK (16.11) supports hyper-v?
> > >
> > > I couldn't find any conclusive evidence online or in dpdk roadmap. Is it
> > > likely that we see it in 17.05?
> >
> > Stephen did a presentation at the last DPDK userspace summit:
> > https://dpdksummit.com/Archive/pdf/2016Userspace/Day01-Session03-StephenHemminger-Userspace2016.pdf
> >
> > Stephen, please, could you confirm the expected release for Hyper-V support?
> > A patch for the roadmap page would be great:
> > http://dpdk.org/dev/roadmap
>
> Yes, the plan is the same. Since DPDK is moving target, getting merges done has been
> a real pain. The Hyper-V UIO generic driver has just gone into upstream next tree.
I don't understand what you mean.
> Therefore the driver will depend on 4.10 kernel initially.
Please, could you send a patch for the web roadmap?
^ permalink raw reply
* Re: [PATCH] config: remove insecure warnings
From: Stephen Hemminger @ 2016-12-06 21:24 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
In-Reply-To: <1480889826-3891-1-git-send-email-thomas.monjalon@6wind.com>
On Sun, 4 Dec 2016 23:17:06 +0100
Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
> There was an option CONFIG_RTE_INSECURE_FUNCTION_WARNING (disabled by
> default), which prevents from using some libc functions:
> sprintf, snprintf, vsnprintf, strcpy, strncpy, strcat, strncat, sscanf,
> strtok, strsep and strlen.
>
> It's all about using them at the right place with the right precautions.
> However, it is neither really possible nor a good advice to disable them.
>
> Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
Agreed, this is better done by fortify and other static checkers anyway.
^ permalink raw reply
* Re: [PATCH v2 03/12] crypto/armv8: Add core crypto operations for ARMv8
From: Jerin Jacob @ 2016-12-06 21:18 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: zbigniew.bodek, dev, pablo.de.lara.guarch, Emery Davis
In-Reply-To: <370264788.TNfU8e7VBG@xps13>
On Tue, Dec 06, 2016 at 09:29:25PM +0100, Thomas Monjalon wrote:
> 2016-12-06 18:32, zbigniew.bodek@caviumnetworks.com:
> > From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> >
> > This patch adds core low-level crypto operations
> > for ARMv8 processors. The assembly code is a base
> > for an optimized PMD and is currently excluded
> > from the build.
>
> It's a bit sad that you cannot achieve the same performance with
> C code and a good compiler.
> Have you tried it? How much is the difference?
Like AES-NI on IA side(exposed as separate PMD in dpdk),
armv8 has special dedicated instructions for crypto operation using SIMD.
This patch is using the "dedicated" armv8 crypto instructions and SIMD
operation to achieve better performance.
We had compared with openssl implementation.Here is the performance
improvement for chained crypto operations case WRT openssl pmd
Buffer
Size(B) OPS(M) Throughput(Gbps)
64 729 % 742 %
128 577 % 592 %
256 483 % 476 %
512 336 % 351 %
768 300 % 286 %
1024 263 % 250 %
1280 225 % 229 %
1536 214 % 213 %
1792 186 % 203 %
2048 200 % 193 %
^ permalink raw reply
* Re: [PATCH 18/32] net/dpaa2: introducing dpaa2 pmd driver
From: Thomas Monjalon @ 2016-12-06 21:08 UTC (permalink / raw)
To: Ferruh Yigit, Hemant Agrawal; +Cc: dev, bruce.richardson, shreyansh.jain
In-Reply-To: <2023a9a6-f342-8986-7ded-3703b3623a70@intel.com>
2016-12-06 19:49, Ferruh Yigit:
> On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > + eth_dev->data->dev_private = rte_zmalloc(
> > + "ethdev private structure",
> > + eth_drv->dev_private_size,
> > + RTE_CACHE_LINE_SIZE);
> > + if (eth_dev->data->dev_private == NULL)
> > + rte_panic("Cannot allocate memzone for private port"
> > + " data\n");
>
> Should this error kill all app, or return an error for this PMD that is
> probed.
It cannot be a question :)
rte_panic() inside libs or drivers is forbidden (and existing ones must
be removed).
^ permalink raw reply
* Re: [PATCH 11/32] net/dpaa2: add dpaa2 vfio support
From: Thomas Monjalon @ 2016-12-06 21:04 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: dev, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-12-git-send-email-hemant.agrawal@nxp.com>
2016-12-04 23:47, Hemant Agrawal:
> Add support for using VFIO for dpaa2 based fsl-mc bus.
Why do we need so much special code for interfacing VFIO on fsl-mc?
Can you reuse some code from EAL VFIO?
^ permalink raw reply
* Re: [PATCH 00/13] Introducing EAL Bus-Device-Driver Model
From: David Marchand @ 2016-12-06 20:52 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev@dpdk.org, Thomas Monjalon
In-Reply-To: <1480846288-2517-1-git-send-email-shreyansh.jain@nxp.com>
"Big patchset and a lot of things to look at.
Here is a first look at it.
On Sun, Dec 4, 2016 at 11:11 AM, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> In continuation to the RFC posted on 17/Nov [9],
> A series of patches is being posted which attempts to create:
> 1. A basic bus model
> `- define rte_bus and associated methods/helpers
> `- test infrastructure to test the Bus infra
> 2. Changes in EAL to support PCI as a bus
> `- a "pci" bus is registered
> `- existing scan/match/probe are modified to allow for bus integration
> `- PCI Device and Driver list, which were global entities, have been
> moved to rte_bus->[device/driver]_list
>
> I have sanity tested this patch over a XeonD X552 available with me, as
> well as part of PoC for verifying NXP's DPAA2 PMD (being pushed out in a
> separate series). Exhaustive testing is still pending.
I saw some checkpatch issues for patch 1 (I would ignore this one) and
4 (please check).
> :: Brief about Patch Layout ::
>
> 0001: Container_of patch from [3]
> 0002~0003: Introducing the basic Bus model and associated test case
> 0005: Support insertion of device rather than addition to tail
Patch 2 and 5 could be squashed.
The constructor priority stuff seems unneeded as long as we use
explicit reference to a global (or local, did not check) bus symbol
rather than a runtime lookup.
> 0004: Add scan and match callbacks for the Bus and updated test case
Why do you push back the bus object in the 'scan' method ?
This method is bus specific which means that the code "knows" the
object registered with the callback.
Is is that you want to have a single scan method used by multiple buses ?
> 0006: Integrate bus scan/match with EAL, without any effective driver
Hard to find a right balance in patch splittng, but patch 4 and 6 are
linked, I would squash them into one.
> 0007: rte_pci_driver->probe replaced with rte_driver->probe
This patch is too big, please separate in two patches: eal changes
then ethdev/driver changes.
I almost missed that mlx4 has been broken : you moved the drv_flags
from the mlx4 pci driver to rte_driver.
Why do you push back the driver object in the 'probe' method ? (idem
rte_bus->scan).
> 0008: Integrate probe of drivers with EAL
This patch does nothing about "remove" while its title talks about it.
+ What about hotplug code ? I suppose this is for later.
> 0009: Split the existing PCI probe into match and probe
You don't need to expose rte_eal_pci_match_default() (and I am not
sure what the "default" means here).
This method should be internal to the pci bus object ?
> 0010: Make PCI probe/match work on rte_driver/device rather than
> rte_pci_device/rte_pci_driver
> 0011: Patch from Ben [8], part of series [2]
> 0012~0013: Enable Scan/Match/probe on Bus from EAL and remove unused
> functions and lists
Same thing as earlier in the series, you don't need to check for the bus object.
The pci bus code can't be called if the bus was not registered and
consequently, you are sure that the pci bus object is the pci_bus
symbol.
Regards,
--
David Marchand
^ permalink raw reply
* Re: [PATCH v12 0/6] add Tx preparation
From: Ananyev, Konstantin @ 2016-12-06 20:31 UTC (permalink / raw)
To: Adrien Mazarguil
Cc: Thomas Monjalon, dev@dpdk.org, Rahul Lakkireddy, Stephen Hurd,
Jan Medala, Jakub Palider, John Daley, Alejandro Lucero,
Harish Patil, Rasesh Mody, Jerin Jacob, Yuanhan Liu, Yong Wang,
Kulasek, TomaszX, olivier.matz@6wind.com
In-Reply-To: <20161206135951.GY10340@6wind.com>
> Hi Konstantin,
>
> On Tue, Dec 06, 2016 at 10:56:26AM +0000, Ananyev, Konstantin wrote:
> >
> > Hi Adrien,
> >
> > >
> > > On Mon, Dec 05, 2016 at 04:43:52PM +0000, Ananyev, Konstantin wrote:
> > > [...]
> > > > > On Fri, Dec 02, 2016 at 01:00:55AM +0000, Ananyev, Konstantin wrote:
> > > > > [...]
> > > > > > > On Wed, Nov 30, 2016 at 10:54:50AM +0000, Ananyev, Konstantin wrote:
> > > > > > > [...]
> > > > > > > > Do you have anything particular in mind here?
> > > > > > >
> > > > > > > Nothing in particular, so for the sake of the argument, let's suppose that I
> > > > > > > would like to add a field to expose some limitation that only applies to my
> > > > > > > PMD during TX but looks generic enough to make sense, e.g. maximum packet
> > > > > > > size when VLAN tagging is requested.
> > > > > >
> > > > > > Hmm, I didn't hear about such limitations so far, but if it is real case -
> > > > > > sure, feel free to submit the patch.
> > > > >
> > > > > I won't, that was hypothetical.
> > > >
> > > > Then why we discussing it? :)
> > >
> > > Just to make a point, which is that new limitations may appear anytime and
> > > tx_prepare() can now be used to check for them. First patch of the series
> > > does it:
> > >
> > > + uint16_t nb_seg_max; /**< Max number of segments per whole packet. */
> > > + uint16_t nb_mtu_seg_max; /**< Max number of segments per one MTU */
> > >
> > > And states that:
> > >
> > > + * For each packet to send, the rte_eth_tx_prepare() function performs
> > > + * the following operations:
> > > + *
> > > + * - Check if packet meets devices requirements for tx offloads.
> > > + *
> > > + * - Check limitations about number of segments.
> > > + *
> > > + * - Check additional requirements when debug is enabled.
> > > + *
> > > + * - Update and/or reset required checksums when tx offload is set for packet.
> >
> > I think I already explained in my previous email why I think that
> > nb_seg_max and nb_mtu_seg_max are not redundant because of tx_prepare().
> > From my point they are complement to tx_prepare():
> > Even if people do use tx_prepare() they still should take this information into account.
> > As an example ixgbe can't TX packets with then 40 segments.
> > tx_prepare() for ixgbe will flag that issue, but it can't make a decision on user behalf
> > what to do in that case: drop the packet, try to coalesce it into the packet with less
> > number of segments, split the packet into several smaller, etc.
> > That's up to user to make such decision, and to make it, user might need this information.
>
> Yet tx_prepare() has already the ability to update mbuf contents, issue is
> what will this function do in the future, where will it stop? It is defined
> in a way that each PMD does what it wants to make mbufs edible for
> tx_burst(), because of this applications will just always call it to be on
> the safe side.
>
> > > It's like making this function mandatory IMO.
> >
> > That's probably where confusion starts: I don't think that
> > tx_prepare() should be mandatory for the user to call.
> > Yes, it should be a recommended way.
> > But the user still should have the ability to by-pass it,
> > if he believes there is no need for it, or he prefers to implement
> > the same functionality on his own.
> > As an example, if the user knows that he is going to send a group
> > of one-segment packets that don't require any tx offloads, he can safely skip
> > tx_prepare() for them.
>
> I understand your point, and agree with the example you provide. Many
> applications do not know what's inside mbufs though, except perhaps that
> they contain TCP and may want to perform TSO because of that. Those will
> have to call tx_prepare() to be future-proof.
>
> > > > > > > PMDs are free to set that field to some
> > > > > > > special value (say, 0) if they do not care.
> > > > > > >
> > > > > > > Since that field exists however, conscious applications should check its
> > > > > > > value for each packet that needs to be transmitted. This extra code causes a
> > > > > > > slowdown just by sitting in the data path. Since it is not the only field in
> > > > > > > that structure, the performance impact can be significant.
> >
> > Conscious user will probably use this information at the stage of packet formation.
> > He probably has to do this sort of things for large packets anyway:
> > Check what is the underlying mtu, to decide does he need to split the packet,
> > or enable tso for it, etc.
>
> There are already too many things to check,
There always been, that patch exposes them, before that upper layer probably
had to use some hard-coded defines.
> applications probably won't mind
> a little help from PMDs. If we keep adding fields to this structure, we'll
> have to provide some sort of PMD-specific function that checks what is
> relevant.
Why PMD specific?
These fields are generic enough and could be used by upper layer to consult
when packet is formed.
>
> Furthermore, assuming most packets are fine and do not require any extra
> processing, what is rejected by tx_burst() could enter some unlikely() path
> that attempts to rectify and re-send them. That would at least optimize the
> common scenario.
It is up to the upper layer to decide what to do with ill-formed packets:
drop/log/try to cure/etc.
Obviously different applications would have different logic and make different decisions here.
If you'd like to introduce a new function (in rte_net or whatever) that would be smart and
generic enough to cure ill-formed packets - you are more than welcome to try.
Though discussion of such fallback function is far of scope of that patch, I believe.
>
> > > > > > > Even though this code is inside applications, it remains unfair to PMDs for
> > > > > > > which these tests are irrelevant. This problem is identified and addressed
> > > > > > > by tx_prepare().
> > > > > >
> > > > > > I suppose the question is why do we need:
> > > > > > uint16_t nb_seg_max;
> > > > > > uint16_t nb_mtu_seg_max;
> > > > > > as we now have tx_prepare(), right?
> > > > > >
> > > > > > For two reasons:
> > > > > > 1. Some people might feel that tx_prepare() is not good (smart/fast) enough
> > > > > > for them and would prefer to do necessary preparations for TX offloads themselves.
> > > > > >
> > > > > > 2. Even if people do use tx_prepare() they still should take this information into accout.
> > > > > > As an example ixgbe can't TX packets with then 40 segments.
> > > > > > Obviously ixbge_tx_prep() performs that check and returns an error.
> > > > >
> > > > > Problem is that tx_prepare() also provides safeties which are not part of
> > > > > tx_burst(), such as not going over nb_mtu_seg_max. Because of this and the
> > > > > fact struct rte_eth_desc_lim can grow new fields anytime, application
> > > > > developers will be tempted to just call tx_prepare() and focus on more
> > > > > useful things.
> > > >
> > > > NP with that, that was an intention beyond introducing it.
> > > >
> > > > > Put another way, from a user's point of view, tx_prepare() is an opaque
> > > > > function that greatly increases tx_burst()'s ability to send mbufs as
> > > > > requested, with extra error checking on top; applications not written to run
> > > > > on a specific PMD/device (all of them ideally) will thus call tx_prepare()
> > > > > at some point.
> > > > >
> > > > > > But it wouldn't try to merge/reallocate mbufs for you.
> > > > > > User still has to do it himself, or just prevent creating such long chains somehow.
> > > > >
> > > > > Yes, that's another debate. PMDs could still implement a software fallback
> > > > > for unlikely slow events like these. The number of PMDs is not going to
> > > > > decrease, each device having its own set of weird limitations in specific
> > > > > cases, PMDs should do their best to process mbufs even if that means slowly
> > > > > due to the lack of preparation.
> > > > >
> > > > > tx_prepare() has its uses but should really be optional, in the sense that
> > > > > if that function is not called, tx_burst() should deal with it somehow.
> > > >
> > > > As I said before, I don't think it is a good idea to put everything in tx_burst().
> > > > If PMD driver prefer things that way, yes tx_burst() can deal with each and
> > > > possible offload requirement itself, but it shouldn't be mandatory.
> > >
> > > In effect, having to call tx_prepare() otherwise makes this step mandatory
> > > anyway. Looks like we are not going to agree here.
> > >
> > > > > > > Thanks to tx_prepare(), these checks are moved back into PMDs where they
> > > > > > > belong. PMDs that do not need them do not have to provide support for
> > > > > > > tx_prepare() and do not suffer any performance impact as result;
> > > > > > > applications only have to make sure tx_prepare() is always called at some
> > > > > > > point before tx_burst().
> > > > > > >
> > > > > > > Once you reach this stage, you've effectively made tx_prepare() mandatory
> > > > > > > before tx_burst(). If some bug occurs, then perhaps you forgot to call
> > > > > > > tx_prepare(), you just need to add it. The total cost for doing TX is
> > > > > > > therefore tx_prepare() + tx_burst().
> > > > > > >
> > > > > > > I'm perhaps a bit pessimistic mind you, but I do not think tx_prepare() will
> > > > > > > remain optional for long. Sure, PMDs that do not implement it do not care,
> > > > > > > I'm focusing on applications, for which the performance impact of calling
> > > > > > > tx_prepare() followed by tx_burst() is higher than a single tx_burst()
> > > > > > > performing all the necessary preparation at once.
> > > > > > >
> > > > > > > [...]
> > > > > > > > > Following the same logic, why can't such a thing be made part of the TX
> > > > > > > > > burst function as well (through a direct call to rte_phdr_cksum_fix()
> > > > > > > > > whenever necessary). From an application standpoint, what are the advantages
> > > > > > > > > of having to:
> > > > > > > > >
> > > > > > > > > if (tx_prep()) // iterate and update mbufs as needed
> > > > > > > > > tx_burst(); // iterate and send
> > > > > > > > >
> > > > > > > > > Compared to:
> > > > > > > > >
> > > > > > > > > tx_burst(); // iterate, update as needed and send
> > > > > > > >
> > > > > > > > I think that was discussed extensively quite a lot previously here:
> > > > > > > > As Thomas already replied - main motivation is to allow user
> > > > > > > > to execute them on different stages of packet TX pipeline,
> > > > > > > > and probably on different cores.
> > > > > > > > I think that provides better flexibility to the user to when/where
> > > > > > > > do these preparations and hopefully would lead to better performance.
> > > > > > >
> > > > > > > And I agree, I think this use case is valid but does not warrant such a high
> > > > > > > penalty when your application does not need that much flexibility. Simple
> > > > > > > (yet conscious) applications need the highest performance. Complex ones as
> > > > > > > you described already suffer quite a bit from IPCs and won't mind a couple
> > > > > > > of extra CPU cycles right?
> > > > > >
> > > > > > It would mean an extra cache-miss for every packet, so I think performance hit
> > > > > > would be quite significant.
> > > > >
> > > > > A performance hit has to occur somewhere regardless, because something has
> > > > > to be done in order to send packets that need it. Whether this cost is in
> > > > > application code or in a PMD function, it remains part of TX.
> > > >
> > > > Depending on the place the final cost would differ quite a lot.
> > > > If you call tx_prepare() somewhere close to the place where you fill the packet header
> > > > contents, then most likely the data that tx_prepare() has to access will be already in the cache.
> > > > So the performance penalty will be minimal.
> > > > If you'll try to access the same data later (at tx_burst), then the possibility that it would still
> > > > be in cache is much less.
> > > > If you calling tx_burst() from other core then data would for sure be out of cache,
> > > > and even worse can still be in another core cache.
> > >
> > > Well sure, that's why I also think tx_prepare() has its uses, only that
> > > since tx_prepare() is optional, tx_burst() should provide the same
> > > functionality when tx_prepare() is not called.
> >
> > As I understand, to implement what you are proposing (TX_PREPARED mbuf->ol_flag)
> > it will be required:
> >
> > a) Modify all existing applications that do similar to tx_prepare() stuff on their own,
> > otherwise they'll would hit performance penalty.
> > b) Modify at least all Intel PMDs and might be some others too (vmxnet3?).
> >
> > Step b) probably wouldn't cause any significant performance impact straightway,
> > but it's for sure wouldn't make things faster, and would increase tx_burst() code
> > complexity quite a lot.
> > From other side, I can't see any real benefit that we will have in return.
> > So I still opposed to that idea.
>
> Applications gain the ability to perform tx_burst() with offloads without
> having to prepare anything.
What means 'without preparing anything'?
This is just not possible I think.
One way or another application would have to to decide
what exactly it likes to TX and what HW offloads it likes to use for it.
So at least, it still needs to fill relevant mbuf fields:
pkt_len, data_len, nb_segs, ol_flags, tx_offload, etc.
>Currently these applications either cannot use
> offloads at all or need to perform PMD-specific voodoo first.
That's why tx_prepare() is introduced.
> The generic
> alternative to this scenario being tx_prepare(), PMDs have to make this step
> as cheap as possible.
>
> Yes that would slow down existing applications, people may find it
> acceptable since we're modifying the TX API here.
>
> > > > > > About the 'simple' case when tx_prep() and tx_burst() are called on the same core,
> > > > > > Why do you believe that:
> > > > > > tx_prep(); tx_burst(); would be much slower than tx_burst() {tx_prep(), ...}?
> > > > >
> > > > > I mean instead of two function calls with their own loops:
> > > > >
> > > > > tx_prepare() { foreach (pkt) { check(); extra_check(); ... } }
> > > > >
> > > > > tx_burst() { foreach (pkt) { check(); stuff(); ... } }
> > > > >
> > > > > You end up with one:
> > > > >
> > > > > tx_burst() { foreach (pkt) { check(); extra_check(); stuff(); ... } }
> > > > >
> > > > > Which usually is more efficient.
> > > >
> > > > I really doubt that.
> > > > If it would be that, what is the point to process packet in bulks?
> > > > Usually dividing processing into different stages and at each stage processing
> > > > multiple packet at once helps to improve performance.
> > > > At least for IA.
> > > > Look for example how we had to change l3fwd to improve its performance.
> > >
> > > Depends quite a bit on usage pattern. It is less efficient for applications
> > > that do not modify mbuf contents because of the additional function call and
> > > inner loop.
> >
> > If the application doesn't modify mbuf contents that it can simply skip calling tx_prepare().
>
> What if that same application wants to enable some offload as well?
Hmm, wasn't that your use-case when no offloads (modifications) are required just 3 lines above?
>
> > > Note that I'm only pushing for the ability to conveniently address both
> > > cases with maximum performance.
> > >
> > > > > > tx_prep() itself is quite expensive, let say for Intel HW it includes:
> > > > > > - read mbuf fileds (2 cache-lines),
> > > > > > - read packet header (1/2 cache-lines)
> > > > > > - calculate pseudo-header csum
> > > > > > - update packet header
> > > > > > Comparing to that price of extra function call seems neglectable
> > > > > > (if we TX packets in bursts of course).
> > > > >
> > > > > We agree its performance is a critical issue then, sharing half the read
> > > > > steps with tx_burst() would make sense to me.
> > > >
> > > > I didn't understand that sentence.
> > >
> > > I meant this step can be shared (in addition to loop etc):
> > >
> > > - read mbuf fileds (2 cache-lines),
> >
> > Ah ok, you still believe that mixing tx_burst and tx_prepare code together
> > would give us noticeable performance benefit.
> > As I said above, I don't think it would, but you are welcome to try and
> > prove me wrong.
>
> Depends on what you call noticeable. I guess we can at least agree having
> two separate functions and loops cause more instructions to be generated and
> executed.
>
> Now for the number of spent CPU cycles, depends of course whether mbufs are
> still hot into the cache or not, and as I told you in my opinion we'll
> usually see applications calling tx_prepare() just before tx_burst() to
> benefit from offloads.
Honestly, Adrien we are going in cycles here.
Just to be clear:
Current patch introduces tx_prepare() without affecting in any way:
1) existing applications
2) exiting PMD code (tx_burst)
Meanwhile I still believe it is useful and provide a big step forward in terms
of generalizing usage of HW TX offloads.
What you propose requires modifications for both existing applications and existing PMD code
(full-featured tx_burst() for at least all Intel PMDs and vmxnet3 has to be significantly modified).
You believe that with these modifications that new tx_burst() implementation
would be noticeably faster than just current: tx_prepare(); tx_burst();
I personally doubt that it really would (at least on modern IA).
But as I said, you are more than welcome to prove me wrong here.
Let say, provide a patch for ixgbe (or i40e) full-featured tx_burst() implementation,
so that it would combine both tx_prepare() and tx_burst() functionalities into one function.
Then we can run some performance tests with current and yours patches and compare results.
Without that, I don't see any point to discuss your proposition any further.
I just won't agree for such big change in existing PMDs without some solid justification beyond it.
>
> > > > > > > Yes they will, therefore we need a method that satisfies both cases.
> > > > > > >
> > > > > > > As a possible solution, a special mbuf flag could be added to each mbuf
> > > > > > > having gone through tx_prepare(). That way, tx_burst() could skip some
> > > > > > > checks and things it would otherwise have done.
> > > > > >
> > > > > > That's an interesting idea, but it has one drawback:
> > > > > > As I understand, it means that from now on if user doing preparations on his own,
> > > > > > he had to setup this flag, otherwise tx_burst() would do extra unnecessary work.
> > > > > > So any existing applications that using TX offloads and do preparation by themselves
> > > > > > would have to be modified to avoid performance loss.
> > > > >
> > > > > In my opinion, users should not do preparation on their own.
> > > >
> > > > People already do it now.
> > >
> > > But we do not want them to anymore thanks to this new API, for reasons
> > > described in the motivation section of the cover letter, right?
> >
> > We probably wouldn't recommend that, but if people would like to use their own stuff,
> > or shortcuts - I don't want to stop them here.
> >
> > >
> > > > > If we provide a
> > > > > generic method, it has to be fast enough to replace theirs. Perhaps not as
> > > > > fast since it would work with all PMDs (usual trade-off), but acceptably so.
> > > > >
> > > > > > > Another possibility, telling the PMD first that you always intend to use
> > > > > > > tx_prepare() and getting a simpler/faster tx_burst() callback as a result.
> > > > > >
> > > > > > That what we have right now (at least for Intel HW):
> > > > > > it is a user responsibility to do the necessary preparations/checks before calling tx_burst().
> > > > > > With tx_prepare() we just remove from user the headache to implement tx_prepare() on his own.
> > > > > > Now he can use a 'proper' PMD provided function.
> > > > > >
> > > > > > My vote still would be for that model.
> > > > >
> > > > > OK, then in a nutshell:
> > > > >
> > > > > 1. Users are not expected to perform preparation/checks themselves anymore,
> > > > > if they do, it's their problem.
> > > >
> > > > I think we need to be backward compatible here.
> > > > If the existing app doing what tx_prepare() supposed to do, it should keep working.
> > >
> > > It should work, only if they keep doing it as well as call tx_burst()
> > > directly, they will likely get lower performance.
> > >
> > > > > 2. If configured through an API to be defined, tx_burst() can be split in
> > > > > two and applications must call tx_prepare() at some point before
> > > > > tx_burst().
> > > > >
> > > > > 3. Otherwise tx_burst() should perform the necessary preparation and checks
> > > > > on its own by default (when tx_prepare() is not expected).
> > > >
> > > > As I said before, I don't think it should be mandatory for tx_burst() to do what tx_prepare() does.
> > > > If some particular implementation of tx_burst() prefers to do things that way - that's fine.
> > > > But it shouldn't be required to.
> > >
> > > You're right, however applications might find it convenient. I think most
> > > will end up with something like the following:
> > >
> > > if (tx_prepare(pkts))
> > > tx_burst(pkts));
> >
> > Looking at existing DPDK apps - most of them do use some sort of TX bufferization.
> > So, even in a simplistic app it would probably be:
> >
> > tx_prepare(pkts);
> > tx_buffer(pkts);
>
> We're down to my word against yours here I guess, to leave the choice to
> application developers, we'd need to provide tx_prepare() and a simpler
> tx_burst() as well as the ability to call tx_burst() directly and still get
> offloads.
>From what I've seen, most DPDK libs/apps do buffer data packets for TX in one or another way:
mtcp, warp17, seastar.
Not to mention sample apps.
But ok, as said above, if you can prove that tx_burst() you are proposing is really much faster then
tx_prepare(); tx_burst();
I'll be happy to reconsider.
>
> > > > > 4. We probably still need some mbuf flag to mark mbufs that cannot be
> > > > > modified, the refcount could also serve as a hint.
> > > >
> > > > If mbuf can't be modified, you probably just wouldn't call the function that supposed to do that,
> > > > tx_prepare() in that case.
> > >
> > > I think it would be easier to document what offload flags may cause the
> > > tx_burst() function to modify mbuf contents, so applications have the
> > > ability to set or strip these flags on a mbuf basis. That way there is no
> > > need to call tx_prepare() without knowing exactly what it's going to do.
> >
> > Not sure I understand what exactly do you propose in the last paragraph?
>
> That for each TX offload flag, we document whether preparation might cause a
> mbuf to be written to during the tx_prepare()/tx_burst() phase. One of the
> reasons for tx_prepare() being:
>
> 4) Fields in packet may require different initialization (like e.g. will
> require pseudo-header checksum precalculation, sometimes in a
> different way depending on packet type, and so on). Now application
> needs to care about it.
>
> If we determine what offloads may cause mbuf contents to change (all of them
> perhaps?), then applications can easily strip those flags from outgoing
> "const" mbufs. Then it becomes acceptable for tx_burst() to modify mbuf
> contents as per user request, which removes one reason to rely on
> tx_prepare() for these.
Hmm, I didn't get you here.
If let say I don't need TX TCP cksum offload, why would I set this flag inside mbuf at first place?
If I do expect PMD to do TX TCP cksum offload for me, then I have to set that flag,
otherwise how PMD would know that I did require that offload?
Konstantin
^ permalink raw reply
* Re: [PATCH v2 03/12] crypto/armv8: Add core crypto operations for ARMv8
From: Thomas Monjalon @ 2016-12-06 20:29 UTC (permalink / raw)
To: zbigniew.bodek; +Cc: dev, pablo.de.lara.guarch, jerin.jacob, Emery Davis
In-Reply-To: <1481077985-4224-4-git-send-email-zbigniew.bodek@caviumnetworks.com>
2016-12-06 18:32, zbigniew.bodek@caviumnetworks.com:
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> This patch adds core low-level crypto operations
> for ARMv8 processors. The assembly code is a base
> for an optimized PMD and is currently excluded
> from the build.
It's a bit sad that you cannot achieve the same performance with
C code and a good compiler.
Have you tried it? How much is the difference?
^ permalink raw reply
* Re: [PATCH v2 02/12] lib: add cryptodev type for the upcoming ARMv8 PMD
From: Thomas Monjalon @ 2016-12-06 20:27 UTC (permalink / raw)
To: dev; +Cc: zbigniew.bodek, pablo.de.lara.guarch, jerin.jacob, declan.doherty
In-Reply-To: <1481077985-4224-3-git-send-email-zbigniew.bodek@caviumnetworks.com>
2016-12-06 18:32, zbigniew.bodek@caviumnetworks.com:
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> Add type and name for ARMv8 crypto PMD
>
> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
[...]
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -66,6 +66,8 @@
> /**< KASUMI PMD device name */
> #define CRYPTODEV_NAME_ZUC_PMD crypto_zuc
> /**< KASUMI PMD device name */
> +#define CRYPTODEV_NAME_ARMV8_PMD crypto_armv8
> +/**< ARMv8 CM device name */
>
> /** Crypto device type */
> enum rte_cryptodev_type {
> @@ -77,6 +79,7 @@ enum rte_cryptodev_type {
> RTE_CRYPTODEV_KASUMI_PMD, /**< KASUMI PMD */
> RTE_CRYPTODEV_ZUC_PMD, /**< ZUC PMD */
> RTE_CRYPTODEV_OPENSSL_PMD, /**< OpenSSL PMD */
> + RTE_CRYPTODEV_ARMV8_PMD, /**< ARMv8 crypto PMD */
> };
Can we remove all these types and names in the generic crypto API?
^ permalink raw reply
* Re: Hyper-v support
From: Stephen Hemminger @ 2016-12-06 20:25 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Varun, dev
In-Reply-To: <2702523.1trrNuZT35@xps13>
On Thu, 01 Dec 2016 12:25:10 +0100
Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
> (fixed the email, sorry)
>
> 2016-12-01 12:21, Thomas Monjalon:
> > 2016-11-30 14:34, Varun:
> > > Hi,
> > >
> > > I would like to know if the latest DPDK (16.11) supports hyper-v?
> > >
> > > I couldn't find any conclusive evidence online or in dpdk roadmap. Is it
> > > likely that we see it in 17.05?
> >
> > Stephen did a presentation at the last DPDK userspace summit:
> > https://dpdksummit.com/Archive/pdf/2016Userspace/Day01-Session03-StephenHemminger-Userspace2016.pdf
> >
> > Stephen, please, could you confirm the expected release for Hyper-V support?
> > A patch for the roadmap page would be great:
> > http://dpdk.org/dev/roadmap
>
>
Yes, the plan is the same. Since DPDK is moving target, getting merges done has been
a real pain. The Hyper-V UIO generic driver has just gone into upstream next tree.
Therefore the driver will depend on 4.10 kernel initially.
^ permalink raw reply
* Re: [PATCH 1/8] drivers/common/dpaa2: Run time assembler for Descriptor formation
From: Thomas Monjalon @ 2016-12-06 20:23 UTC (permalink / raw)
To: Akhil Goyal, Horia Geanta Neag
Cc: dev, declan.doherty, pablo.de.lara.guarch, hemant.agrawal
In-Reply-To: <20161205125540.6419-2-akhil.goyal@nxp.com>
2016-12-05 18:25, Akhil Goyal:
> FLib is a library which helps in making the descriptors which
> is understood by NXP's SEC hardware.
> This patch provides header files for command words which can be used
> for descritptor formation.
It seems this code is old. Does it exist as a standalone library somewhere?
Where was it hosted before duplicating it in DPDK?
Why do you want to have a common directory drivers/common/dpaa2/flib
instead of a sub-directory in the crypto driver?
^ permalink raw reply
* [PATCH v3] net/i40evf: fix reporting of imissed packets
From: Tom Crugnale @ 2016-12-06 20:16 UTC (permalink / raw)
To: jingjing.wu, helin.zhang; +Cc: dev, Tom Crugnale
Missed packets on RX were erroneously being assigned to the ierrors
struct member. Change it to be assigned to imissed.
Fixes: 4861cde4 ("i40e: new poll mode driver")
Signed-off-by: Tom Crugnale <tcrugnale@sandvine.com>
---
v3:
* Fixed coding style issues
v2:
* Fixed line breaks in original patch submission
---
drivers/net/i40e/i40e_ethdev_vf.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..90876c8 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -952,7 +952,7 @@ struct rte_i40evf_xstats_name_off {
}
static int
-i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40evf_get_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
int ret;
struct i40e_eth_stats *pstats = NULL;
@@ -965,7 +965,7 @@ struct rte_i40evf_xstats_name_off {
pstats->rx_broadcast;
stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
pstats->tx_unicast;
- stats->ierrors = pstats->rx_discards;
+ stats->imissed = pstats->rx_discards;
stats->oerrors = pstats->tx_errors + pstats->tx_discards;
stats->ibytes = pstats->rx_bytes;
stats->obytes = pstats->tx_bytes;
@@ -2277,8 +2277,8 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
static void
i40evf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
- if (i40evf_get_statics(dev, stats))
- PMD_DRV_LOG(ERR, "Get statics failed");
+ if (i40evf_get_stats(dev, stats))
+ PMD_DRV_LOG(ERR, "Get stats failed");
}
static void
--
1.8.3.1
^ permalink raw reply related
* Re: [RFC] ethdev: abstraction layer for QoS hierarchical scheduler
From: Stephen Hemminger @ 2016-12-06 19:51 UTC (permalink / raw)
To: Cristian Dumitrescu; +Cc: dev
In-Reply-To: <1480529810-95280-1-git-send-email-cristian.dumitrescu@intel.com>
On Wed, 30 Nov 2016 18:16:50 +0000
Cristian Dumitrescu <cristian.dumitrescu@intel.com> wrote:
> This RFC proposes an ethdev-based abstraction layer for Quality of Service (QoS)
> hierarchical scheduler. The goal of the abstraction layer is to provide a simple
> generic API that is agnostic of the underlying HW, SW or mixed HW-SW complex
> implementation.
>
> Q1: What is the benefit for having an abstraction layer for QoS hierarchical
> layer?
> A1: There is growing interest in the industry for handling various HW-based,
> SW-based or mixed hierarchical scheduler implementations using a unified DPDK
> API.
>
> Q2: Which devices are targeted by this abstraction layer?
> A2: All current and future devices that expose a hierarchical scheduler feature
> under DPDK, including NICs, FPGAs, ASICs, SOCs, SW libraries.
>
> Q3: Which scheduler hierarchies are supported by the API?
> A3: Hopefully any scheduler hierarchy can be described and covered by the
> current API. Of course, functional correctness, accuracy and performance levels
> depend on the specific implementations of this API.
>
> Q4: Why have this abstraction layer into ethdev as opposed to a new type of
> device (e.g. scheddev) similar to ethdev, cryptodev, eventdev, etc?
> A4: Packets are sent to the Ethernet device using the ethdev API
> rte_eth_tx_burst() function, with the hierarchical scheduling taking place
> automatically (i.e. no SW intervention) in HW implementations. Basically, the
> hierarchical scheduler is done as part of packet TX operation.
> The hierarchical scheduler is typically the last stage before packet TX and it
> is tightly integrated with the TX stage. The hierarchical scheduler is just
> another offload feature of the Ethernet device, which needs to be accommodated
> by the ethdev API similar to any other offload feature (such as RSS, DCB,
> flow director, etc).
> Once the decision to schedule a specific packet has been taken, this packet
> cannot be dropped and it has to be sent over the wire as is, otherwise what
> takes place on the wire is not what was planned at scheduling time, so the
> scheduling is not accurate (Note: there are some devices which allow prepending
> headers to the packet after the scheduling stage at the expense of sending
> correction requests back to the scheduler, but this only strengthens the bond
> between scheduling and TX).
>
> Q5: Given that the packet scheduling takes place automatically for pure HW
> implementations, how does packet scheduling take place for poll-mode SW
> implementations?
> A5: The API provided function rte_sched_run() is designed to take care of this.
> For HW implementations, this function typically does nothing. For SW
> implementations, this function is typically expected to perform dequeue of
> packets from the hierarchical scheduler and their write to Ethernet device TX
> queue, periodic flush of any buffers on enqueue-side into the hierarchical
> scheduler for burst-oriented implementations, etc.
>
> Q6: Which are the scheduling algorithms supported?
> A6: The fundamental scheduling algorithms that are supported are Strict Priority
> (SP) and Weighted Fair Queuing (WFQ). The SP and WFQ algorithms are supported at
> the level of each node of the scheduling hierarchy, regardless of the node
> level/position in the tree. The SP algorithm is used to schedule between sibling
> nodes with different priority, while WFQ is used to schedule between groups of
> siblings that have the same priority.
> Algorithms such as Weighed Round Robin (WRR), byte-level WRR, Deficit WRR
> (DWRR), etc are considered approximations of the ideal WFQ and are therefore
> assimilated to WFQ, although an associated implementation-dependent accuracy,
> performance and resource usage trade-off might exist.
>
> Q7: Which are the supported congestion management algorithms?
> A7: Tail drop, head drop and Weighted Random Early Detection (WRED). They are
> available for every leaf node in the hierarchy, subject to the specific
> implementation supporting them.
>
> Q8: Is traffic shaping supported?
> A8: Yes, there are a number of shapers (rate limiters) that can be supported for
> each node in the hierarchy (built-in limit is currently set to 4 per node). Each
> shaper can be private to a node (used only by that node) or shared between
> multiple nodes.
>
> Q9: What is the purpose of having shaper profiles and WRED profiles?
> A9: In most implementations, many shapers typically share the same configuration
> parameters, so defining shaper profiles simplifies the configuration task. Same
> considerations apply to WRED contexts and profiles.
>
> Q10: How is the scheduling hierarchy defined and created?
> A10: Scheduler hierarchy tree is set up by creating new nodes and connecting
> them to other existing nodes, which thus become parent nodes. The unique ID that
> is assigned to each node when the node is created is further used to update the
> node configuration or to connect children nodes to it. The leaf nodes of the
> scheduler hierarchy are each attached to one of the Ethernet device TX queues.
>
> Q11: Are on-the-fly changes of the scheduling hierarchy allowed by the API?
> A11: Yes. The actual changes take place subject to the specific implementation
> supporting them, otherwise error code is returned.
>
> Q12: What is the typical function call sequence to set up and run the Ethernet
> device scheduler?
> A12: The typical simplified function call sequence is listed below:
> i) Configure the Ethernet device and its TX queues: rte_eth_dev_configure(),
> rte_eth_tx_queue_setup()
> ii) Create WRED profiles and WRED contexts, shaper profiles and shapers:
> rte_eth_sched_wred_profile_add(), rte_eth_sched_wred_context_add(),
> rte_eth_sched_shaper_profile_add(), rte_eth_sched_shaper_add()
> iii) Create the scheduler hierarchy nodes and tree: rte_eth_sched_node_add()
> iv) Freeze the start-up hierarchy and ask the device whether it supports it:
> rte_eth_sched_node_add()
> v) Start the Ethernet port: rte_eth_dev_start()
> vi) Run-time scheduler hierarchy updates: rte_eth_sched_node_add(),
> rte_eth_sched_node_<attribute>_set()
> vii) Run-time packet enqueue into the hierarchical scheduler: rte_eth_tx_burst()
> viii) Run-time support for SW poll-mode implementations (see previous answer):
> rte_sched_run()
>
> Q13: Which are the possible options for the user when the Ethernet port does not
> support the scheduling hierarchy required by the user?
> A13: The following options are available to the user:
> i) abort
> ii) try out a new hierarchy (e.g. with less leaf nodes), if acceptable
> iii) wrap the Ethernet device into a new type of Ethernet device that has a SW
> front-end implementing the hierarchical scheduler (e.g. existing DPDK library
> librte_sched); instantiate the new device type on-the-fly and check if the
> hierarchy requirements can be met by the new device.
>
>
> Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This seems to be more of an abstraction of existing QoS.
Why not something like Linux Qdisc or FreeBSD DummyNet/PF/ALTQ where the Qos
components are stackable objects? And why not make it the same as existing
OS abstractions? Rather than reinventing wheel which seems to be DPDK Standard
Procedure, could an existing abstraction be used?
^ permalink raw reply
* Re: [PATCH 32/32] net/dpaa2: enable stashing for LS2088A devices
From: Ferruh Yigit @ 2016-12-06 19:50 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-33-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Not just specific to this patch, but overall, can you please try to
provide more information in the comment logs.
> ---
> drivers/net/dpaa2/dpaa2_ethdev.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> index 1a25f07..dd8e8fb 100644
> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -229,6 +229,17 @@
> options = options | DPNI_QUEUE_OPT_USER_CTX;
> cfg.user_context = (uint64_t)(dpaa2_q);
>
> + /*if ls2088 or rev2 device, enable the stashing */
> + if ((qbman_get_version() & 0xFFFF0000) > QMAN_REV_4000) {
> + options |= DPNI_QUEUE_OPT_FLC;
> + cfg.flc.stash_control = true;
> + cfg.flc.value &= 0xFFFFFFFFFFFFFFC0;
> + /* 00 00 00 - last 6 bit represent annotation, context stashing,
> + * data stashing setting 01 01 00 (0x14) to enable
> + * 1 line annotation, 1 line context
> + */
> + cfg.flc.value |= 0x14;
> + }
> ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_RX,
> dpaa2_q->tc_index, flow_id, options, &cfg);
> if (ret) {
>
^ permalink raw reply
* Re: [PATCH 28/32] net/dpaa2: add support for physical address usages
From: Ferruh Yigit @ 2016-12-06 19:50 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-29-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> DPAA2 HW accelerators with ARM SMMU can be configured
> to use virtual or physical address from users space.
> Adding support for Physical address (default).
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> config/defconfig_arm64-dpaa2-linuxapp-gcc | 1 +
> drivers/net/dpaa2/Makefile | 1 +
> drivers/net/dpaa2/base/dpaa2_hw_dpbp.c | 1 +
> drivers/net/dpaa2/base/dpaa2_hw_pvt.h | 59 +++++++++++++++++++++++++++++++
> 4 files changed, 62 insertions(+)
>
> diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> index bcb6e88..7dc6d2d 100644
> --- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
> +++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> @@ -50,5 +50,6 @@ CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
> # Compile software PMD backed by NXP DPAA2 files
> #
> CONFIG_RTE_LIBRTE_DPAA2_PMD=y
> +CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
> CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT=n
> CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
> diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
> index 9e693cd..a8c3c04 100644
> --- a/drivers/net/dpaa2/Makefile
> +++ b/drivers/net/dpaa2/Makefile
> @@ -42,6 +42,7 @@ else
> CFLAGS += -O3
> CFLAGS += $(WERROR_FLAGS)
> endif
> +CFLAGS +=-Wno-unused-function
Will this flag be removed when DPAA2_VADDR_TO_IOV and
DPAA2_IOVA_TO_VADDR macros used in next patches?
>
> CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
> CFLAGS += -I$(RTE_SDK)/drivers/common/dpaa2/mc
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpbp.c b/drivers/net/dpaa2/base/dpaa2_hw_dpbp.c
> index 2b30036..5b7d593 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_dpbp.c
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpbp.c
> @@ -322,6 +322,7 @@ int hw_mbuf_alloc_bulk(struct rte_mempool *pool,
> * i.e. first buffer is valid,
> * remaining 6 buffers may be null
> */
> + DPAA2_MODIFY_IOVA_TO_VADDR(bufs[i], uint64_t);
> obj_table[n] = (struct rte_mbuf *)(bufs[i] - mbuf_size);
> rte_mbuf_refcnt_set((struct rte_mbuf *)obj_table[n], 0);
> PMD_TX_LOG(DEBUG, "Acquired %p address %p from BMAN",
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_pvt.h b/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> index d116fcd..a1afa23 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> @@ -169,8 +169,67 @@ struct qbman_fle {
> */
> #define DPAA2_EQ_RESP_ALWAYS 1
>
> +#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
> +/* todo - this is costly, need to write a fast coversion routine */
> +static void *dpaa2_mem_ptov(phys_addr_t paddr)
> +{
> + const struct rte_memseg *memseg = rte_eal_get_physmem_layout();
> + int i;
> +
> + for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) {
> + if (paddr >= memseg[i].phys_addr &&
> + (char *)paddr < (char *)memseg[i].phys_addr + memseg[i].len)
> + return (void *)(memseg[i].addr_64
> + + (paddr - memseg[i].phys_addr));
> + }
> + return NULL;
> +}
> +
> +static phys_addr_t dpaa2_mem_vtop(uint64_t vaddr)
> +{
> + const struct rte_memseg *memseg = rte_eal_get_physmem_layout();
> + int i;
> +
> + for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) {
> + if (vaddr >= memseg[i].addr_64 &&
> + vaddr < memseg[i].addr_64 + memseg[i].len)
> + return memseg[i].phys_addr
> + + (vaddr - memseg[i].addr_64);
> + }
> + return (phys_addr_t)(NULL);
> +}
> +
> +/**
> + * When we are using Physical addresses as IO Virtual Addresses,
> + * Need to call conversion routines dpaa2_mem_vtop & dpaa2_mem_ptov
> + * whereever required.
> + * These routines are called with help of below MACRO's
> + */
> +
> +#define DPAA2_MBUF_VADDR_TO_IOVA(mbuf) (mbuf->buf_physaddr)
> +
> +/**
> + * macro to convert Virtual address to IOVA
> + */
> +#define DPAA2_VADDR_TO_IOVA(_vaddr) dpaa2_mem_vtop((uint64_t)(_vaddr))
> +
> +/**
> + * macro to convert IOVA to Virtual address
> + */
> +#define DPAA2_IOVA_TO_VADDR(_iova) dpaa2_mem_ptov((phys_addr_t)(_iova))
> +
> +/**
> + * macro to convert modify the memory containing IOVA to Virtual address
> + */
> +#define DPAA2_MODIFY_IOVA_TO_VADDR(_mem, _type) \
> + {_mem = (_type)(dpaa2_mem_ptov((phys_addr_t)(_mem))); }
> +
> +#else /* RTE_LIBRTE_DPAA2_USE_PHYS_IOVA */
> +
> #define DPAA2_MBUF_VADDR_TO_IOVA(mbuf) (mbuf->buf_addr)
> #define DPAA2_VADDR_TO_IOVA(_vaddr) (_vaddr)
> #define DPAA2_IOVA_TO_VADDR(_iova) (_iova)
> +#define DPAA2_MODIFY_IOVA_TO_VADDR(_mem, _type)
>
> +#endif /* RTE_LIBRTE_DPAA2_USE_PHYS_IOVA */
> #endif
>
^ permalink raw reply
* Re: [PATCH 21/32] net/dpaa2: add rss flow distribution
From: Ferruh Yigit @ 2016-12-06 19:50 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-22-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> doc/guides/nics/features/dpaa2.ini | 1 +
> drivers/net/dpaa2/Makefile | 3 +-
> drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 287 +++++++++++++++++++++++++++++++++
> drivers/net/dpaa2/base/dpaa2_hw_dpni.h | 15 ++
> drivers/net/dpaa2/base/dpaa2_hw_pvt.h | 2 +
> drivers/net/dpaa2/dpaa2_ethdev.c | 31 +++-
> 6 files changed, 334 insertions(+), 5 deletions(-)
> create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
>
> diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
> index 0b59725..20152a0 100644
> --- a/doc/guides/nics/features/dpaa2.ini
> +++ b/doc/guides/nics/features/dpaa2.ini
> @@ -5,6 +5,7 @@
> ;
> [Features]
> Queue start/stop = Y
> +RSS hash = Y
> Linux VFIO = Y
> ARMv8 = Y
> Usage doc = Y
> diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
> index 45e28d2..4ed0de3 100644
> --- a/drivers/net/dpaa2/Makefile
> +++ b/drivers/net/dpaa2/Makefile
> @@ -57,10 +57,11 @@ LIBABIVER := 1
>
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpio.c
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpbp.c
> +SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpni.c
>
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_vfio.c
> -# Interfaces with DPDK
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_bus.c
> +# Interfaces with DPDK
These kind of things can be fixed where it is introduced at first place.
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
>
> # library dependencies
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
> new file mode 100644
> index 0000000..b26d5a7
> --- /dev/null
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c
> @@ -0,0 +1,287 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Freescale Semiconductor, Inc nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <time.h>
> +#include <net/if.h>
> +
> +#include <rte_mbuf.h>
> +#include <rte_ethdev.h>
> +#include <rte_malloc.h>
> +#include <rte_memcpy.h>
> +#include <rte_string_fns.h>
> +#include <rte_cycles.h>
> +#include <rte_kvargs.h>
> +#include <rte_dev.h>
> +#include <rte_ethdev.h>
> +
> +#include "dpaa2_logs.h"
> +
> +#include <base/dpaa2_hw_pvt.h>
> +#include <base/dpaa2_hw_dpni.h>
> +
> +static void
> +dpaa2_distset_to_dpkg_profile_cfg(
> + uint32_t req_dist_set,
> + struct dpkg_profile_cfg *kg_cfg);
> +
> +int
> +dpaa2_setup_flow_dist(struct rte_eth_dev *eth_dev,
> + uint32_t req_dist_set)
> +{
> + struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
> + struct fsl_mc_io *dpni = priv->hw;
> + struct dpni_rx_tc_dist_cfg tc_cfg;
> + struct dpkg_profile_cfg kg_cfg;
> + void *p_params;
> + int ret, tc_index = 0;
> +
> + p_params = rte_malloc(
> + NULL, DIST_PARAM_IOVA_SIZE, RTE_CACHE_LINE_SIZE);
> + if (!p_params) {
> + RTE_LOG(ERR, PMD, "Memory unavaialble\n");
> + return -ENOMEM;
> + }
> + memset(p_params, 0, DIST_PARAM_IOVA_SIZE);
> + memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
> +
> + dpaa2_distset_to_dpkg_profile_cfg(req_dist_set, &kg_cfg);
> + tc_cfg.key_cfg_iova = (uint64_t)(DPAA2_VADDR_TO_IOVA(p_params));
> + tc_cfg.dist_size = eth_dev->data->nb_rx_queues;
> + tc_cfg.dist_mode = DPNI_DIST_MODE_HASH;
> +
> + ret = dpni_prepare_key_cfg(&kg_cfg, p_params);
> + if (ret) {
> + RTE_LOG(ERR, PMD, "Unable to prepare extract parameters\n");
> + rte_free(p_params);
> + return ret;
> + }
> +
> + ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, priv->token, tc_index,
> + &tc_cfg);
> + rte_free(p_params);
> + if (ret) {
> + RTE_LOG(ERR, PMD, "Setting distribution for Rx failed with"
> + " err code: %d\n", ret);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +int dpaa2_remove_flow_dist(
> + struct rte_eth_dev *eth_dev,
> + uint8_t tc_index)
> +{
> + struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
> + struct fsl_mc_io *dpni = priv->hw;
> + struct dpni_rx_tc_dist_cfg tc_cfg;
> + struct dpkg_profile_cfg kg_cfg;
> + void *p_params;
> + int ret;
> +
> + p_params = rte_malloc(
> + NULL, DIST_PARAM_IOVA_SIZE, RTE_CACHE_LINE_SIZE);
> + if (!p_params) {
> + RTE_LOG(ERR, PMD, "Memory unavaialble\n");
> + return -ENOMEM;
> + }
> + memset(p_params, 0, DIST_PARAM_IOVA_SIZE);
> + memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg));
> +
> + tc_cfg.key_cfg_iova = (uint64_t)(DPAA2_VADDR_TO_IOVA(p_params));
> + tc_cfg.dist_size = 0;
> + tc_cfg.dist_mode = DPNI_DIST_MODE_NONE;
> +
> + ret = dpni_prepare_key_cfg(&kg_cfg, p_params);
> + if (ret) {
> + RTE_LOG(ERR, PMD, "Unable to prepare extract parameters\n");
> + rte_free(p_params);
> + return ret;
> + }
> +
> + ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, priv->token, tc_index,
> + &tc_cfg);
> + rte_free(p_params);
> + if (ret) {
> + RTE_LOG(ERR, PMD, "Setting distribution for Rx failed with"
> + " err code: %d\n", ret);
> + return ret;
> + }
> + return ret;
> +}
> +
> +static void
> +dpaa2_distset_to_dpkg_profile_cfg(
> + uint32_t req_dist_set,
> + struct dpkg_profile_cfg *kg_cfg)
> +{
> + uint32_t loop = 0, i = 0, dist_field = 0;
> + int l2_configured = 0, l3_configured = 0;
> + int l4_configured = 0, sctp_configured = 0;
> +
> + memset(kg_cfg, 0, sizeof(struct dpkg_profile_cfg));
> + while (req_dist_set) {
> + if (req_dist_set % 2 != 0) {
> + dist_field = 1U << loop;
> + switch (dist_field) {
> + case ETH_RSS_L2_PAYLOAD:
> +
> + if (l2_configured)
> + break;
> + l2_configured = 1;
> +
> + kg_cfg->extracts[i].extract.from_hdr.prot =
> + NET_PROT_ETH;
> + kg_cfg->extracts[i].extract.from_hdr.field =
> + NH_FLD_ETH_TYPE;
> + kg_cfg->extracts[i].type =
> + DPKG_EXTRACT_FROM_HDR;
> + kg_cfg->extracts[i].extract.from_hdr.type =
> + DPKG_FULL_FIELD;
> + i++;
> + break;
> +
> + case ETH_RSS_IPV4:
> + case ETH_RSS_FRAG_IPV4:
> + case ETH_RSS_NONFRAG_IPV4_OTHER:
> + case ETH_RSS_IPV6:
> + case ETH_RSS_FRAG_IPV6:
> + case ETH_RSS_NONFRAG_IPV6_OTHER:
> + case ETH_RSS_IPV6_EX:
> +
> + if (l3_configured)
> + break;
> + l3_configured = 1;
> +
> + kg_cfg->extracts[i].extract.from_hdr.prot =
> + NET_PROT_IP;
> + kg_cfg->extracts[i].extract.from_hdr.field =
> + NH_FLD_IP_SRC;
> + kg_cfg->extracts[i].type =
> + DPKG_EXTRACT_FROM_HDR;
> + kg_cfg->extracts[i].extract.from_hdr.type =
> + DPKG_FULL_FIELD;
> + i++;
> +
> + kg_cfg->extracts[i].extract.from_hdr.prot =
> + NET_PROT_IP;
> + kg_cfg->extracts[i].extract.from_hdr.field =
> + NH_FLD_IP_DST;
> + kg_cfg->extracts[i].type =
> + DPKG_EXTRACT_FROM_HDR;
> + kg_cfg->extracts[i].extract.from_hdr.type =
> + DPKG_FULL_FIELD;
> + i++;
> +
> + kg_cfg->extracts[i].extract.from_hdr.prot =
> + NET_PROT_IP;
> + kg_cfg->extracts[i].extract.from_hdr.field =
> + NH_FLD_IP_PROTO;
> + kg_cfg->extracts[i].type =
> + DPKG_EXTRACT_FROM_HDR;
> + kg_cfg->extracts[i].extract.from_hdr.type =
> + DPKG_FULL_FIELD;
> + kg_cfg->num_extracts++;
> + i++;
> + break;
> +
> + case ETH_RSS_NONFRAG_IPV4_TCP:
> + case ETH_RSS_NONFRAG_IPV6_TCP:
> + case ETH_RSS_NONFRAG_IPV4_UDP:
> + case ETH_RSS_NONFRAG_IPV6_UDP:
> + case ETH_RSS_IPV6_TCP_EX:
> + case ETH_RSS_IPV6_UDP_EX:
> +
> + if (l4_configured)
> + break;
> + l4_configured = 1;
> +
> + kg_cfg->extracts[i].extract.from_hdr.prot =
> + NET_PROT_TCP;
> + kg_cfg->extracts[i].extract.from_hdr.field =
> + NH_FLD_TCP_PORT_SRC;
> + kg_cfg->extracts[i].type =
> + DPKG_EXTRACT_FROM_HDR;
> + kg_cfg->extracts[i].extract.from_hdr.type =
> + DPKG_FULL_FIELD;
> + i++;
> +
> + kg_cfg->extracts[i].extract.from_hdr.prot =
> + NET_PROT_TCP;
> + kg_cfg->extracts[i].extract.from_hdr.field =
> + NH_FLD_TCP_PORT_SRC;
> + kg_cfg->extracts[i].type =
> + DPKG_EXTRACT_FROM_HDR;
> + kg_cfg->extracts[i].extract.from_hdr.type =
> + DPKG_FULL_FIELD;
> + i++;
> + break;
> +
> + case ETH_RSS_NONFRAG_IPV4_SCTP:
> + case ETH_RSS_NONFRAG_IPV6_SCTP:
> +
> + if (sctp_configured)
> + break;
> + sctp_configured = 1;
> +
> + kg_cfg->extracts[i].extract.from_hdr.prot =
> + NET_PROT_SCTP;
> + kg_cfg->extracts[i].extract.from_hdr.field =
> + NH_FLD_SCTP_PORT_SRC;
> + kg_cfg->extracts[i].type =
> + DPKG_EXTRACT_FROM_HDR;
> + kg_cfg->extracts[i].extract.from_hdr.type =
> + DPKG_FULL_FIELD;
> + i++;
> +
> + kg_cfg->extracts[i].extract.from_hdr.prot =
> + NET_PROT_SCTP;
> + kg_cfg->extracts[i].extract.from_hdr.field =
> + NH_FLD_SCTP_PORT_DST;
> + kg_cfg->extracts[i].type =
> + DPKG_EXTRACT_FROM_HDR;
> + kg_cfg->extracts[i].extract.from_hdr.type =
> + DPKG_FULL_FIELD;
> + i++;
> + break;
> +
> + default:
> + PMD_DRV_LOG(WARNING, "Bad flow distribution"
> + " option %x\n", dist_field);
> + }
> + }
> + req_dist_set = req_dist_set >> 1;
> + loop++;
> + }
> + kg_cfg->num_extracts = i;
> +}
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.h b/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> index 197fd28..c109396 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> @@ -37,15 +37,22 @@
> #include <fsl_dpni.h>
> #include <fsl_mc_sys.h>
>
> +#define MAX_TCS DPNI_MAX_TC
> #define MAX_RX_QUEUES 16
> #define MAX_TX_QUEUES 16
>
> +/*! Maximum number of flow distributions per traffic class */
> +#define MAX_DIST_PER_TC 16
> +
> /*default tc to be used for ,congestion, distribution etc configuration. */
> #define DPAA2_DEF_TC 0
>
> /*! Global MCP list */
> extern void *(*mcp_ptr_list);
>
> +/* Size of the input SMMU mapped memory required by MC */
> +#define DIST_PARAM_IOVA_SIZE 256
> +
> struct dpaa2_dev_priv {
> void *hw;
> int32_t hw_id;
> @@ -56,7 +63,15 @@ struct dpaa2_dev_priv {
> void *rx_vq[MAX_RX_QUEUES];
> void *tx_vq[MAX_TX_QUEUES];
>
> + uint16_t num_dist_per_tc[MAX_TCS];
> uint8_t num_tc;
> uint8_t flags; /*dpaa2 config flags */
> };
> +
> +int dpaa2_setup_flow_dist(struct rte_eth_dev *eth_dev,
> + uint32_t req_dist_set);
> +
> +int dpaa2_remove_flow_dist(struct rte_eth_dev *eth_dev,
> + uint8_t tc_index);
> +
> #endif /* _DPAA2_DPNI_H_ */
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_pvt.h b/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> index 867611f..abc70ac 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> @@ -93,4 +93,6 @@ struct dpaa2_queue {
> /*! Global MCP list */
> extern void *(*mcp_ptr_list);
>
> +#define DPAA2_VADDR_TO_IOVA(_vaddr) (_vaddr)
> +
> #endif
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> index 45c3f8f..094296a 100644
> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -113,7 +113,8 @@
> }
>
> vq_id = 0;
> - for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) {
> + for (dist_idx = 0; dist_idx < priv->num_dist_per_tc[DPAA2_DEF_TC];
> + dist_idx++) {
> mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id];
> mcq->tc_index = DPAA2_DEF_TC;
> mcq->flow_id = dist_idx;
> @@ -139,6 +140,7 @@
> {
> struct rte_eth_dev_data *data = dev->data;
> struct rte_eth_conf *eth_conf = &data->dev_conf;
> + int ret;
>
> PMD_INIT_FUNC_TRACE();
>
> @@ -150,6 +152,18 @@
> return -1;
> }
>
> + if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) {
> + /* Return in case number of Rx queues is 1 */
> + if (data->nb_rx_queues == 1)
> + return 0;
> + ret = dpaa2_setup_flow_dist(dev,
> + eth_conf->rx_adv_conf.rss_conf.rss_hf);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "unable to set flow distribution."
> + "please check queue config\n");
> + return ret;
> + }
> + }
> return 0;
> }
>
> @@ -181,7 +195,7 @@
> dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */
>
> /*Get the tc id and flow id from given VQ id*/
> - flow_id = rx_queue_id;
> + flow_id = rx_queue_id % priv->num_dist_per_tc[dpaa2_q->tc_index];
> memset(&cfg, 0, sizeof(struct dpni_queue));
>
> options = options | DPNI_QUEUE_OPT_USER_CTX;
> @@ -371,7 +385,7 @@
> struct fsl_mc_io *dpni_dev;
> struct dpni_attr attr;
> struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
> - int ret, hw_id;
> + int i, ret, hw_id;
>
> PMD_INIT_FUNC_TRACE();
>
> @@ -413,7 +427,16 @@
> }
>
> priv->num_tc = attr.num_tcs;
> - priv->nb_rx_queues = attr.num_queues;
> + for (i = 0; i < attr.num_tcs; i++) {
> + priv->num_dist_per_tc[i] = attr.num_queues;
> + break;
> + }
> +
> + /* Distribution is per Tc only,
> + * so choosing RX queues from default TC only
> + */
> + priv->nb_rx_queues = priv->num_dist_per_tc[DPAA2_DEF_TC];
> +
> priv->nb_tx_queues = attr.num_queues;
>
> eth_dev->data->nb_rx_queues = priv->nb_rx_queues;
>
^ permalink raw reply
* Re: [PATCH 22/32] net/dpaa2: configure mac address at init
From: Ferruh Yigit @ 2016-12-06 19:50 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-23-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> drivers/net/dpaa2/base/dpaa2_hw_dpni.h | 3 +++
> drivers/net/dpaa2/dpaa2_ethdev.c | 26 ++++++++++++++++++++++++++
> 2 files changed, 29 insertions(+)
>
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.h b/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> index c109396..70d52b6 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> @@ -63,7 +63,10 @@ struct dpaa2_dev_priv {
> void *rx_vq[MAX_RX_QUEUES];
> void *tx_vq[MAX_TX_QUEUES];
>
> + uint32_t options;
> uint16_t num_dist_per_tc[MAX_TCS];
> + uint8_t max_mac_filters;
> + uint8_t max_vlan_filters;
> uint8_t num_tc;
> uint8_t flags; /*dpaa2 config flags */
> };
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> index 094296a..65c3384 100644
> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -64,8 +64,12 @@
> dev_info->driver_name = drivername;
> dev_info->if_index = priv->hw_id;
>
> + dev_info->max_mac_addrs = priv->max_mac_filters;
> dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues;
> dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues;
> + dev_info->speed_capa = ETH_LINK_SPEED_1G |
> + ETH_LINK_SPEED_2_5G |
> + ETH_LINK_SPEED_10G;
Patch does a little more than what it says, this can be added to prev
patch that introduces dpaa2_dev_info_get()
> }
>
> static int
> @@ -444,6 +448,9 @@
Overall this makes harder to review, there is no function name provided
int the patch, this is same for all patchset. There was a .gitattributes
patch in the mail list for this, can you please get it before sending
next revision of patches.
>
> priv->hw = dpni_dev;
> priv->hw_id = hw_id;
> + priv->options = attr.options;
> + priv->max_mac_filters = attr.mac_filter_entries;
> + priv->max_vlan_filters = attr.vlan_filter_entries;
> priv->flags = 0;
>
> ret = dpaa2_alloc_rx_tx_queues(eth_dev);
> @@ -452,6 +459,25 @@
> return -ret;
> }
>
> + /* Allocate memory for storing MAC addresses */
> + eth_dev->data->mac_addrs = rte_zmalloc("dpni",
> + ETHER_ADDR_LEN * attr.mac_filter_entries, 0);
> + if (eth_dev->data->mac_addrs == NULL) {
> + PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to "
> + "store MAC addresses",
> + ETHER_ADDR_LEN * attr.mac_filter_entries);
> + return -ENOMEM;
> + }
> +
> + ret = dpni_get_primary_mac_addr(dpni_dev, CMD_PRI_LOW,
> + priv->token,
> + (uint8_t *)(eth_dev->data->mac_addrs[0].addr_bytes));
> + if (ret) {
> + PMD_INIT_LOG(ERR, "DPNI get mac address failed:"
> + " Error Code = %d\n", ret);
> + return -ret;
> + }
> +
> eth_dev->dev_ops = &dpaa2_ethdev_ops;
> return 0;
> }
>
^ permalink raw reply
* Re: [PATCH 18/32] net/dpaa2: introducing dpaa2 pmd driver
From: Ferruh Yigit @ 2016-12-06 19:49 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-19-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> add support for dpaa2 architucture fsl-mc bus based dpaa2 pmd driver.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> drivers/net/dpaa2/Makefile | 1 +
> drivers/net/dpaa2/dpaa2_bus.c | 64 ++++++++++++++++++++++++++++++++++++++--
> drivers/net/dpaa2/dpaa2_ethdev.c | 54 +++++++++++++++++++++++++++++++++
> drivers/net/dpaa2/dpaa2_ethdev.h | 39 ++++++++++++++++++++++++
> 4 files changed, 155 insertions(+), 3 deletions(-)
> create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
> create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
>
> diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
> index c4981b2..45e28d2 100644
> --- a/drivers/net/dpaa2/Makefile
> +++ b/drivers/net/dpaa2/Makefile
> @@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpbp.c
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_vfio.c
> # Interfaces with DPDK
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_bus.c
> +SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c
>
> # library dependencies
> DEPDIRS-y += lib/librte_eal
> diff --git a/drivers/net/dpaa2/dpaa2_bus.c b/drivers/net/dpaa2/dpaa2_bus.c
> index fa88599..81eaca8 100644
> --- a/drivers/net/dpaa2/dpaa2_bus.c
> +++ b/drivers/net/dpaa2/dpaa2_bus.c
> @@ -44,6 +44,7 @@
>
> #include "eal_filesystem.h"
> #include "eal_private.h"
> +#include "dpaa2_ethdev.h"
> #include "dpaa2_vfio.h"
>
> #define DPAA2_BUS_LOG(level, fmt, args...) \
> @@ -77,10 +78,67 @@
> rte_eal_bus_remove_driver(&driver->driver);
> }
>
> -int rte_dpaa2_probe(struct rte_driver *driver __rte_unused,
> - struct rte_device *device __rte_unused)
> +static void
> +dpaa2_device_name(struct rte_dpaa2_device *dev __rte_unused, char *ethdev_name,
> + unsigned int len)
> {
> - return 0;
> + /* Fill the name of the ethernet device based on the device info
> + */
> + /* TODO This is dummy */
> + strncpy(ethdev_name, "dpaa2_device", len);
> +}
> +
> +int rte_dpaa2_probe(struct rte_driver *drv, struct rte_device *dev)
> +{
> + struct eth_driver *eth_drv;
> + struct rte_eth_dev *eth_dev;
> + struct rte_dpaa2_driver *dpaa2_drv;
> + struct rte_dpaa2_device *dpaa2_dev;
> + char ethdev_name[RTE_ETH_NAME_MAX_LEN];
> +
> + int diag;
> +
> + dpaa2_drv = container_of(drv, struct rte_dpaa2_driver, driver);
> + dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
> +
> + eth_drv = (struct eth_driver *)dpaa2_drv;
> +
> + dpaa2_device_name(dpaa2_dev, ethdev_name, sizeof(ethdev_name));
> +
> + eth_dev = rte_eth_dev_allocate(ethdev_name);
> + if (eth_dev == NULL)
> + return -ENOMEM;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + eth_dev->data->dev_private = rte_zmalloc(
> + "ethdev private structure",
> + eth_drv->dev_private_size,
> + RTE_CACHE_LINE_SIZE);
> + if (eth_dev->data->dev_private == NULL)
> + rte_panic("Cannot allocate memzone for private port"
> + " data\n");
Should this error kill all app, or return an error for this PMD that is
probed.
> + }
> + eth_dev->device = &dpaa2_dev->device;
> + eth_dev->driver = eth_drv;
> + eth_dev->data->rx_mbuf_alloc_failed = 0;
> +
> + /* init user callbacks */
> + TAILQ_INIT(ð_dev->link_intr_cbs);
> +
> + /*
> + * Set the default MTU.
> + */
> + eth_dev->data->mtu = ETHER_MTU;
> +
> + /* Invoke PMD device initialization function */
> + diag = dpaa2_dev_init(eth_dev);
This should call PMD specific init "eth_drv->eth_dev_init()" instead of
direct call the PMD function, right? What will happen if there are
multiple device/drivers in the bus?
> + if (diag == 0)
> + return 0;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> + rte_free(eth_dev->data->dev_private);
> + rte_eth_dev_release_port(eth_dev);
> + return diag;
> }
>
> int rte_dpaa2_scan(struct rte_bus *bus_d)
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> new file mode 100644
> index 0000000..17dfff6
> --- /dev/null
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -0,0 +1,54 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Freescale Semiconductor, Inc nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <time.h>
> +#include <net/if.h>
> +
> +#include <rte_mbuf.h>
> +#include <rte_ethdev.h>
> +#include <rte_malloc.h>
> +#include <rte_memcpy.h>
> +#include <rte_string_fns.h>
> +#include <rte_cycles.h>
> +#include <rte_kvargs.h>
> +#include <rte_dev.h>
> +#include <rte_ethdev.h>
> +
> +/* DPDK Interfaces */
> +#include <dpaa2_ethdev.h>
> +
> +int
> +dpaa2_dev_init(struct rte_eth_dev *eth_dev __rte_unused)
> +{
> + return 0;
> +}
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
> new file mode 100644
> index 0000000..0295868
> --- /dev/null
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.h
> @@ -0,0 +1,39 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Freescale Semiconductor, Inc nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _DPAA2_ETHDEV_H
> +#define _DPAA2_ETHDEV_H
> +
> +int dpaa2_dev_init(struct rte_eth_dev *eth_dev);
> +
> +#endif /* _DPAA2_ETHDEV_H */
>
^ permalink raw reply
* Re: [PATCH 20/32] net/dpaa2: add queue configuration support
From: Ferruh Yigit @ 2016-12-06 19:49 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-21-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> doc/guides/nics/features/dpaa2.ini | 1 +
> drivers/net/dpaa2/base/dpaa2_hw_dpni.h | 14 +-
> drivers/net/dpaa2/base/dpaa2_hw_pvt.h | 21 +++
> drivers/net/dpaa2/dpaa2_ethdev.c | 254 ++++++++++++++++++++++++++++++++-
> 4 files changed, 288 insertions(+), 2 deletions(-)
>
> diff --git a/doc/guides/nics/features/dpaa2.ini b/doc/guides/nics/features/dpaa2.ini
> index b176208..0b59725 100644
> --- a/doc/guides/nics/features/dpaa2.ini
> +++ b/doc/guides/nics/features/dpaa2.ini
> @@ -4,6 +4,7 @@
> ; Refer to default.ini for the full list of available PMD features.
> ;
> [Features]
> +Queue start/stop = Y
> Linux VFIO = Y
> ARMv8 = Y
> Usage doc = Y
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.h b/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> index 1b655e4..197fd28 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> @@ -36,15 +36,27 @@
>
> #include <fsl_dpni.h>
> #include <fsl_mc_sys.h>
> +
> +#define MAX_RX_QUEUES 16
> +#define MAX_TX_QUEUES 16
> +
> +/*default tc to be used for ,congestion, distribution etc configuration. */
> +#define DPAA2_DEF_TC 0
> +
> /*! Global MCP list */
> extern void *(*mcp_ptr_list);
>
> -
> struct dpaa2_dev_priv {
> void *hw;
> int32_t hw_id;
> + int32_t qdid;
> uint16_t token;
> + uint8_t nb_tx_queues;
> + uint8_t nb_rx_queues;
> + void *rx_vq[MAX_RX_QUEUES];
> + void *tx_vq[MAX_TX_QUEUES];
>
> + uint8_t num_tc;
> uint8_t flags; /*dpaa2 config flags */
> };
> #endif /* _DPAA2_DPNI_H_ */
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_pvt.h b/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> index 5038209..867611f 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> @@ -37,9 +37,12 @@
> #include <fsl_mc_sys.h>
> #include <fsl_qbman_portal.h>
>
> +#define DPAA2_DQRR_RING_SIZE 16
> + /** <Maximum number of slots available in RX ring*/
>
> #define MC_PORTAL_INDEX 0
> #define NUM_DPIO_REGIONS 2
> +#define NUM_DQS_PER_QUEUE 2
>
> #define MEMPOOL_F_HW_PKT_POOL 0x8000 /**< mpool flag to check offloaded pool */
>
> @@ -70,6 +73,24 @@ struct dpaa2_dpio_dev {
> int32_t hw_id; /**< An unique ID of this DPIO device instance */
> };
>
> +struct queue_storage_info_t {
> + struct qbman_result *dq_storage[NUM_DQS_PER_QUEUE];
> +};
> +
> +struct dpaa2_queue {
> + struct rte_mempool *mb_pool; /**< mbuf pool to populate RX ring. */
> + void *dev;
> + int32_t eventfd; /*!< Event Fd of this queue */
> + uint32_t fqid; /*!< Unique ID of this queue */
> + uint8_t tc_index; /*!< traffic class identifier */
> + uint16_t flow_id; /*!< To be used by DPAA2 frmework */
> + uint64_t rx_pkts;
> + uint64_t tx_pkts;
> + uint64_t err_pkts;
> + struct queue_storage_info_t *q_storage;
> +};
> +
> /*! Global MCP list */
> extern void *(*mcp_ptr_list);
> +
> #endif
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> index daf59c1..45c3f8f 100644
> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -46,10 +46,94 @@
> #include <rte_dpaa2.h>
>
> #include <dpaa2_logs.h>
> +#include <base/dpaa2_hw_pvt.h>
> #include <base/dpaa2_hw_dpni.h>
> /* DPDK Interfaces */
> #include <dpaa2_ethdev.h>
>
> +/* Name of the DPAA2 Net PMD */
> +static const char *drivername = "DPNI PMD";
> +
> +static void
> +dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
> +{
> + struct dpaa2_dev_priv *priv = dev->data->dev_private;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + dev_info->driver_name = drivername;
Please check patches
http://dpdk.org/dev/patchwork/patch/17170/
http://dpdk.org/dev/patchwork/patch/17171/
> + dev_info->if_index = priv->hw_id;
> +
> + dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues;
> + dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues;
> +}
> +
> +static int
> +dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev)
> +{
> + struct dpaa2_dev_priv *priv = dev->data->dev_private;
> + uint16_t dist_idx;
> + uint32_t vq_id;
> + struct dpaa2_queue *mc_q, *mcq;
> + uint32_t tot_queues;
> + int i;
> + struct dpaa2_queue *dpaa2_q;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + tot_queues = priv->nb_rx_queues + priv->nb_tx_queues;
> + mc_q = rte_malloc(NULL, sizeof(struct dpaa2_queue) * tot_queues,
> + RTE_CACHE_LINE_SIZE);
> + if (!mc_q) {
> + PMD_INIT_LOG(ERR, "malloc failed for rx/tx queues\n");
> + return -1;
> + }
> +
> + for (i = 0; i < priv->nb_rx_queues; i++) {
> + mc_q->dev = dev;
> + priv->rx_vq[i] = mc_q++;
> + dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
> + dpaa2_q->q_storage = rte_malloc("dq_storage",
> + sizeof(struct queue_storage_info_t),
> + RTE_CACHE_LINE_SIZE);
> + if (!dpaa2_q->q_storage)
> + goto fail;
> +
> + memset(dpaa2_q->q_storage, 0,
> + sizeof(struct queue_storage_info_t));
> + dpaa2_q->q_storage->dq_storage[0] = rte_malloc(NULL,
> + DPAA2_DQRR_RING_SIZE * sizeof(struct qbman_result),
> + RTE_CACHE_LINE_SIZE);
> + }
> +
> + for (i = 0; i < priv->nb_tx_queues; i++) {
> + mc_q->dev = dev;
> + mc_q->flow_id = DPNI_NEW_FLOW_ID;
> + priv->tx_vq[i] = mc_q++;
> + }
> +
> + vq_id = 0;
> + for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) {
> + mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id];
> + mcq->tc_index = DPAA2_DEF_TC;
> + mcq->flow_id = dist_idx;
> + vq_id++;
> + }
> +
> + return 0;
> +fail:
> + i -= 1;
> + mc_q = priv->rx_vq[0];
> + while (i >= 0) {
> + dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
> + rte_free(dpaa2_q->q_storage->dq_storage[0]);
> + rte_free(dpaa2_q->q_storage);
> + priv->rx_vq[i--] = NULL;
> + }
> + rte_free(mc_q);
> + return -1;
> +}
> +
> static int
> dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
> {
> @@ -69,15 +153,134 @@
> return 0;
> }
>
> +/* Function to setup RX flow information. It contains traffic class ID,
> + * flow ID, destination configuration etc.
> + */
> static int
> -dpaa2_dev_start(struct rte_eth_dev *dev)
> +dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
> + uint16_t rx_queue_id,
> + uint16_t nb_rx_desc __rte_unused,
> + unsigned int socket_id __rte_unused,
> + const struct rte_eth_rxconf *rx_conf __rte_unused,
> + struct rte_mempool *mb_pool)
> {
> struct dpaa2_dev_priv *priv = dev->data->dev_private;
> struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
> + struct dpaa2_queue *dpaa2_q;
> + struct dpni_queue cfg;
> + uint8_t options = 0;
> + uint8_t flow_id;
> + int ret;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + PMD_INIT_LOG(DEBUG, "dev =%p, queue =%d, pool = %p, conf =%p",
> + dev, rx_queue_id, mb_pool, rx_conf);
> +
> + dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[rx_queue_id];
> + dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */
> +
> + /*Get the tc id and flow id from given VQ id*/
> + flow_id = rx_queue_id;
> + memset(&cfg, 0, sizeof(struct dpni_queue));
> +
> + options = options | DPNI_QUEUE_OPT_USER_CTX;
> + cfg.user_context = (uint64_t)(dpaa2_q);
> +
> + ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_RX,
> + dpaa2_q->tc_index, flow_id, options, &cfg);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Error in setting the rx flow: = %d\n", ret);
> + return -1;
> + }
> +
> + dev->data->rx_queues[rx_queue_id] = dpaa2_q;
> + return 0;
> +}
> +
> +static int
> +dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,
> + uint16_t tx_queue_id,
> + uint16_t nb_tx_desc __rte_unused,
> + unsigned int socket_id __rte_unused,
> + const struct rte_eth_txconf *tx_conf __rte_unused)
> +{
> + struct dpaa2_dev_priv *priv = dev->data->dev_private;
> + struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)
> + priv->tx_vq[tx_queue_id];
> + struct fsl_mc_io *dpni = priv->hw;
> + struct dpni_queue tx_conf_cfg;
> + struct dpni_queue tx_flow_cfg;
> + uint8_t options = 0, flow_id;
> + uint32_t tc_id;
> int ret;
>
> PMD_INIT_FUNC_TRACE();
>
> + /* Return if queue already configured */
> + if (dpaa2_q->flow_id != DPNI_NEW_FLOW_ID)
> + return 0;
> +
> + memset(&tx_conf_cfg, 0, sizeof(struct dpni_queue));
> + memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue));
> +
> + tc_id = 0;
> + flow_id = tx_queue_id;
> +
> + ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,
> + tc_id, flow_id, options, &tx_flow_cfg);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Error in setting the tx flow: "
> + "tc_id=%d, flow =%d ErrorCode = %x\n",
> + tc_id, flow_id, -ret);
> + return -1;
> + }
> +
> + dpaa2_q->flow_id = flow_id;
> +
> + if (tx_queue_id == 0) {
> + /*Set tx-conf and error configuration*/
> + ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW,
> + priv->token,
> + DPNI_CONF_DISABLE);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Error in set tx conf mode settings"
> + " ErrorCode = %x", ret);
> + return -1;
> + }
> + }
> + dpaa2_q->tc_index = tc_id;
> +
> + dev->data->tx_queues[tx_queue_id] = dpaa2_q;
> + return 0;
> +}
> +
> +static void
> +dpaa2_dev_rx_queue_release(void *q __rte_unused)
> +{
> + PMD_INIT_FUNC_TRACE();
> +}
> +
> +static void
> +dpaa2_dev_tx_queue_release(void *q __rte_unused)
> +{
> + PMD_INIT_FUNC_TRACE();
> +}
> +
> +static int
> +dpaa2_dev_start(struct rte_eth_dev *dev)
> +{
> + struct rte_eth_dev_data *data = dev->data;
> + struct dpaa2_dev_priv *priv = data->dev_private;
> + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
> + struct dpni_queue cfg;
> + uint16_t qdid;
> + struct dpni_queue_id qid;
> + struct dpaa2_queue *dpaa2_q;
> + int ret, i;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);
> if (ret) {
> PMD_INIT_LOG(ERR, "Failure %d in enabling dpni %d device\n",
> @@ -85,6 +288,27 @@
> return ret;
> }
>
> + ret = dpni_get_qdid(dpni, CMD_PRI_LOW, priv->token,
> + DPNI_QUEUE_TX, &qdid);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Error to get qdid:ErrorCode = %d\n", ret);
> + return ret;
> + }
> + priv->qdid = qdid;
> +
> + for (i = 0; i < data->nb_rx_queues; i++) {
> + dpaa2_q = (struct dpaa2_queue *)data->rx_queues[i];
> + ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,
> + DPNI_QUEUE_RX, dpaa2_q->tc_index,
> + dpaa2_q->flow_id, &cfg, &qid);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Error to get flow "
> + "information Error code = %d\n", ret);
> + return ret;
> + }
> + dpaa2_q->fqid = qid.fqid;
> + }
> +
> return 0;
> }
>
> @@ -132,6 +356,11 @@
> .dev_start = dpaa2_dev_start,
> .dev_stop = dpaa2_dev_stop,
> .dev_close = dpaa2_dev_close,
> + .dev_infos_get = dpaa2_dev_info_get,
> + .rx_queue_setup = dpaa2_dev_rx_queue_setup,
> + .rx_queue_release = dpaa2_dev_rx_queue_release,
> + .tx_queue_setup = dpaa2_dev_tx_queue_setup,
> + .tx_queue_release = dpaa2_dev_tx_queue_release,
> };
>
> int
> @@ -140,6 +369,7 @@
> struct rte_device *dev = eth_dev->device;
> struct rte_dpaa2_device *dpaa2_dev;
> struct fsl_mc_io *dpni_dev;
> + struct dpni_attr attr;
> struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
> int ret, hw_id;
>
> @@ -175,8 +405,30 @@
> return -1;
> }
>
> + ret = dpni_get_attributes(dpni_dev, CMD_PRI_LOW, priv->token, &attr);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Failure in getting dpni@%d attribute, "
> + " error code %d\n", hw_id, ret);
> + return -1;
> + }
> +
> + priv->num_tc = attr.num_tcs;
> + priv->nb_rx_queues = attr.num_queues;
> + priv->nb_tx_queues = attr.num_queues;
> +
> + eth_dev->data->nb_rx_queues = priv->nb_rx_queues;
> + eth_dev->data->nb_tx_queues = priv->nb_tx_queues;
> +
> priv->hw = dpni_dev;
> priv->hw_id = hw_id;
> + priv->flags = 0;
> +
> + ret = dpaa2_alloc_rx_tx_queues(eth_dev);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "dpaa2_alloc_rx_tx_queuesFailed\n");
> + return -ret;
> + }
> +
> eth_dev->dev_ops = &dpaa2_ethdev_ops;
> return 0;
> }
>
^ permalink raw reply
* Re: [PATCH 19/32] net/dpaa2: adding eth ops to dpaa2
From: Ferruh Yigit @ 2016-12-06 19:49 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-20-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> drivers/net/dpaa2/base/dpaa2_hw_dpni.h | 50 +++++++++++++
> drivers/net/dpaa2/dpaa2_ethdev.c | 130 ++++++++++++++++++++++++++++++++-
> 2 files changed, 179 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.h
>
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.h b/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> new file mode 100644
> index 0000000..1b655e4
> --- /dev/null
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.h
> @@ -0,0 +1,50 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Freescale Semiconductor, Inc nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _DPAA2_HW_DPNI_H_
> +#define _DPAA2_HW_DPNI_H_
> +
> +#include <fsl_dpni.h>
> +#include <fsl_mc_sys.h>
> +/*! Global MCP list */
> +extern void *(*mcp_ptr_list);
extern keyword not needed.
> +
> +
> +struct dpaa2_dev_priv {
Any reason this is not in dpaa2_ethdev.h but in a new header file, since
this looks like ethernet device private data. Just asking.
> + void *hw;
> + int32_t hw_id;
> + uint16_t token;
> +
> + uint8_t flags; /*dpaa2 config flags */
> +};
> +#endif /* _DPAA2_DPNI_H_ */
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> index 17dfff6..daf59c1 100644
> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -43,12 +43,140 @@
> #include <rte_kvargs.h>
> #include <rte_dev.h>
> #include <rte_ethdev.h>
> +#include <rte_dpaa2.h>
>
> +#include <dpaa2_logs.h>
> +#include <base/dpaa2_hw_dpni.h>
> /* DPDK Interfaces */
> #include <dpaa2_ethdev.h>
>
> +static int
> +dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
> +{
> + struct rte_eth_dev_data *data = dev->data;
> + struct rte_eth_conf *eth_conf = &data->dev_conf;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + /* Check for correct configuration */
> + if (eth_conf->rxmode.mq_mode != ETH_MQ_RX_RSS &&
> + data->nb_rx_queues > 1) {
> + PMD_INIT_LOG(ERR, "Distribution is not enabled, "
> + "but Rx queues more than 1\n");
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +dpaa2_dev_start(struct rte_eth_dev *dev)
> +{
> + struct dpaa2_dev_priv *priv = dev->data->dev_private;
> + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
> + int ret;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Failure %d in enabling dpni %d device\n",
> + ret, priv->hw_id);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * This routine disables all traffic on the adapter by issuing a
> + * global reset on the MAC.
> + */
> +static void
> +dpaa2_dev_stop(struct rte_eth_dev *dev)
> +{
> + struct dpaa2_dev_priv *priv = dev->data->dev_private;
> + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
> + int ret;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + ret = dpni_disable(dpni, CMD_PRI_LOW, priv->token);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Failure (ret %d) in disabling dpni %d dev\n",
> + ret, priv->hw_id);
> + return;
> + }
> +}
> +
> +static void
> +dpaa2_dev_close(struct rte_eth_dev *dev)
> +{
> + struct dpaa2_dev_priv *priv = dev->data->dev_private;
> + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
> + int ret;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + /* Clean the device first */
> + ret = dpni_reset(dpni, CMD_PRI_LOW, priv->token);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Failure cleaning dpni device with"
> + " error code %d\n", ret);
> + return;
> + }
> +}
> +
> +static struct eth_dev_ops dpaa2_ethdev_ops = {
> + .dev_configure = dpaa2_eth_dev_configure,
> + .dev_start = dpaa2_dev_start,
> + .dev_stop = dpaa2_dev_stop,
> + .dev_close = dpaa2_dev_close,
> +};
> +
> int
> -dpaa2_dev_init(struct rte_eth_dev *eth_dev __rte_unused)
> +dpaa2_dev_init(struct rte_eth_dev *eth_dev)
> {
> + struct rte_device *dev = eth_dev->device;
> + struct rte_dpaa2_device *dpaa2_dev;
> + struct fsl_mc_io *dpni_dev;
> + struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
> + int ret, hw_id;
> +
> + PMD_INIT_FUNC_TRACE();
> +
> + /* For secondary processes, the primary has done all the work */
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> + return 0;
> +
> + dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
> +
> + hw_id = dpaa2_dev->object_id;
> +
> + dpni_dev = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io));
> + if (!dpni_dev) {
> + PMD_INIT_LOG(ERR, "malloc failed for dpni device\n");
> + return -1;
> + }
> +
> + dpni_dev->regs = mcp_ptr_list[0];
> + ret = dpni_open(dpni_dev, CMD_PRI_LOW, hw_id, &priv->token);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Failure in opening dpni@%d device with"
> + " error code %d\n", hw_id, ret);
> + return -1;
> + }
> +
> + /* Clean the device first */
> + ret = dpni_reset(dpni_dev, CMD_PRI_LOW, priv->token);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Failure cleaning dpni@%d device with"
> + " error code %d\n", hw_id, ret);
> + return -1;
> + }
Is rte_eth_copy_pci_info() equivalent something required here, to set
some default values?
> +
> + priv->hw = dpni_dev;
> + priv->hw_id = hw_id;
> + eth_dev->dev_ops = &dpaa2_ethdev_ops;
> return 0;
> }
>
^ permalink raw reply
* Re: [PATCH 17/32] net/dpaa2: dpbp based mempool hw offload driver
From: Ferruh Yigit @ 2016-12-06 19:49 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-18-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> DPBP represent a buffer pool instance in DPAA2-QBMAN
> HW accelerator.
>
> All buffers needs to be programmed in the HW accelerator.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> config/defconfig_arm64-dpaa2-linuxapp-gcc | 5 +
> drivers/net/dpaa2/Makefile | 2 +
> drivers/net/dpaa2/base/dpaa2_hw_dpbp.c | 366 ++++++++++++++++++++++++++++++
> drivers/net/dpaa2/base/dpaa2_hw_dpbp.h | 101 +++++++++
> drivers/net/dpaa2/base/dpaa2_hw_pvt.h | 7 +
> drivers/net/dpaa2/dpaa2_vfio.c | 13 +-
> 6 files changed, 493 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpbp.c
> create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpbp.h
>
> diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> index 5ff884b..bcb6e88 100644
> --- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
> +++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> @@ -42,6 +42,11 @@ CONFIG_RTE_ARCH_ARM_TUNE="cortex-a57+fp+simd"
> CONFIG_RTE_MAX_LCORE=8
> CONFIG_RTE_MAX_NUMA_NODES=1
>
> +CONFIG_RTE_PKTMBUF_HEADROOM=256
Some comment to explain why default value overwritten can be good.
> +# FSL DPAA2 based hw mempool
> +#
> +CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="dpaa2"
> +
> # Compile software PMD backed by NXP DPAA2 files
> #
> CONFIG_RTE_LIBRTE_DPAA2_PMD=y
> diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
> index b04c3d2..c4981b2 100644
> --- a/drivers/net/dpaa2/Makefile
> +++ b/drivers/net/dpaa2/Makefile
> @@ -56,6 +56,8 @@ EXPORT_MAP := rte_pmd_dpaa2_version.map
> LIBABIVER := 1
>
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpio.c
> +SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpbp.c
> +
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_vfio.c
> # Interfaces with DPDK
> SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_bus.c
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpbp.c b/drivers/net/dpaa2/base/dpaa2_hw_dpbp.c
> new file mode 100644
> index 0000000..2b30036
> --- /dev/null
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpbp.c
> @@ -0,0 +1,366 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Freescale Semiconductor, Inc nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +
> +#include <rte_mbuf.h>
> +#include <rte_ethdev.h>
> +#include <rte_malloc.h>
> +#include <rte_memcpy.h>
> +#include <rte_string_fns.h>
> +#include <rte_cycles.h>
> +#include <rte_kvargs.h>
> +#include <rte_dev.h>
> +#include <rte_ethdev.h>
> +
> +#include "dpaa2_logs.h"
> +#include <base/dpaa2_hw_pvt.h>
> +#include <base/dpaa2_hw_dpio.h>
> +#include <base/dpaa2_hw_dpbp.h>
> +#include <fsl_dpbp.h>
> +
> +static struct dpbp_node *g_dpbp_list;
> +static struct dpbp_node *avail_dpbp;
> +
> +struct dpaa2_bp_info bpid_info[MAX_BPID];
> +
> +struct dpaa2_bp_list *h_bp_list;
> +
> +int
> +dpaa2_create_dpbp_device(
> + int dpbp_id)
> +{
> + struct dpbp_node *dpbp_node;
> + int ret;
> +
> + /* Allocate DPAA2 dpbp handle */
> + dpbp_node = (struct dpbp_node *)malloc(sizeof(struct dpbp_node));
> + if (!dpbp_node) {
> + PMD_INIT_LOG(ERR, "Memory allocation failed for DPBP Device");
> + return -1;
> + }
> +
> + /* Open the dpbp object */
> + dpbp_node->dpbp.regs = mcp_ptr_list[MC_PORTAL_INDEX];
> + ret = dpbp_open(&dpbp_node->dpbp,
> + CMD_PRI_LOW, dpbp_id, &dpbp_node->token);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Resource alloc failure with err code: %d",
> + ret);
> + free(dpbp_node);
> + return -1;
> + }
> +
> + /* Clean the device first */
> + ret = dpbp_reset(&dpbp_node->dpbp, CMD_PRI_LOW, dpbp_node->token);
> + if (ret) {
> + PMD_INIT_LOG(ERR, "Failure cleaning dpbp device with"
> + " error code %d\n", ret);
> + return -1;
> + }
> +
> + dpbp_node->dpbp_id = dpbp_id;
> + /* Add the dpbp handle into the global list */
> + dpbp_node->next = g_dpbp_list;
> + g_dpbp_list = dpbp_node;
> + avail_dpbp = g_dpbp_list;
> +
> + PMD_INIT_LOG(DEBUG, "Buffer pool resource initialized %d", dpbp_id);
> +
> + return 0;
> +}
> +
> +static int
> +hw_mbuf_create_pool(struct rte_mempool *mp)
> +{
> + struct dpaa2_bp_list *bp_list;
> + struct dpbp_attr dpbp_attr;
> + uint32_t bpid;
> + int ret;
> +
> + if (!avail_dpbp) {
> + PMD_DRV_LOG(ERR, "DPAA2 resources not available");
> + return -1;
> + }
> +
> + ret = dpbp_enable(&avail_dpbp->dpbp, CMD_PRI_LOW, avail_dpbp->token);
> + if (ret != 0) {
> + PMD_INIT_LOG(ERR, "Resource enable failure with"
> + " err code: %d\n", ret);
> + return -1;
> + }
> +
> + ret = dpbp_get_attributes(&avail_dpbp->dpbp, CMD_PRI_LOW,
> + avail_dpbp->token, &dpbp_attr);
> + if (ret != 0) {
> + PMD_INIT_LOG(ERR, "Resource read failure with"
> + " err code: %d\n", ret);
> + ret = dpbp_disable(&avail_dpbp->dpbp, CMD_PRI_LOW,
> + avail_dpbp->token);
> + return -1;
> + }
> +
> + /* Allocate the bp_list which will be added into global_bp_list */
> + bp_list = (struct dpaa2_bp_list *)malloc(sizeof(struct dpaa2_bp_list));
> + if (!bp_list) {
> + PMD_INIT_LOG(ERR, "No heap memory available");
> + return -1;
> + }
> +
> + /* Set parameters of buffer pool list */
> + bp_list->buf_pool.num_bufs = mp->size;
> + bp_list->buf_pool.size = mp->elt_size
> + - sizeof(struct rte_mbuf) - rte_pktmbuf_priv_size(mp);
> + bp_list->buf_pool.bpid = dpbp_attr.bpid;
> + bp_list->buf_pool.h_bpool_mem = NULL;
> + bp_list->buf_pool.mp = mp;
> + bp_list->buf_pool.dpbp_node = avail_dpbp;
> + bp_list->next = h_bp_list;
> +
> + bpid = dpbp_attr.bpid;
> +
> + /* Increment the available DPBP */
> + avail_dpbp = avail_dpbp->next;
> +
> + bpid_info[bpid].meta_data_size = sizeof(struct rte_mbuf)
> + + rte_pktmbuf_priv_size(mp);
> + bpid_info[bpid].bp_list = bp_list;
> + bpid_info[bpid].bpid = bpid;
> +
> + mp->pool_data = (void *)&bpid_info[bpid];
> +
> + PMD_INIT_LOG(DEBUG, "BP List created for bpid =%d", dpbp_attr.bpid);
> +
> + h_bp_list = bp_list;
> + /* Identification for our offloaded pool_data structure
> + */
> + mp->flags |= MEMPOOL_F_HW_PKT_POOL;
> + return 0;
> +}
> +
> +static void
> +hw_mbuf_free_pool(struct rte_mempool *mp __rte_unused)
> +{
> + /* TODO:
> + * 1. Release bp_list memory allocation
> + * 2. opposite of dpbp_enable()
> + * <More>
> + */
> + struct dpaa2_bp_list *bp;
> +
> + /* Iterate over h_bp_list linked list and release each element */
> + while (h_bp_list) {
> + bp = h_bp_list;
> + h_bp_list = bp->next;
> +
> + /* TODO: Should be changed to rte_free */
> + free(bp);
> + }
> +}
> +
> +static
> +void dpaa2_mbuf_release(struct rte_mempool *pool __rte_unused,
> + void * const *obj_table,
> + uint32_t bpid,
> + uint32_t meta_data_size,
> + int count)
> +{
> + struct qbman_release_desc releasedesc;
> + struct qbman_swp *swp;
> + int ret;
> + int i, n;
> + uint64_t bufs[DPAA2_MBUF_MAX_ACQ_REL];
> +
> + if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
> + ret = dpaa2_affine_qbman_swp();
> + if (ret != 0) {
> + RTE_LOG(ERR, PMD, "Failed to allocate IO portal");
> + return;
> + }
> + }
> + swp = DPAA2_PER_LCORE_PORTAL;
> +
> + /* Create a release descriptor required for releasing
> + * buffers into QBMAN
> + */
> + qbman_release_desc_clear(&releasedesc);
> + qbman_release_desc_set_bpid(&releasedesc, bpid);
> +
> + n = count % DPAA2_MBUF_MAX_ACQ_REL;
> +
> + /* convert mbuf to buffers for the remainder*/
> + for (i = 0; i < n ; i++) {
> +#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
> + bufs[i] = (uint64_t)rte_mempool_virt2phy(pool, obj_table[i])
> + + meta_data_size;
> +#else
> + bufs[i] = (uint64_t)obj_table[i] + meta_data_size;
> +#endif
> + }
> + /* feed them to bman*/
> + do {
> + ret = qbman_swp_release(swp, &releasedesc, bufs, n);
> + } while (ret == -EBUSY);
> +
> + /* if there are more buffers to free */
> + while (n < count) {
> + /* convert mbuf to buffers */
> + for (i = 0; i < DPAA2_MBUF_MAX_ACQ_REL; i++) {
> +#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
As far as I can see this config option not added yet, it can be good to
add with this release.
> + bufs[i] = (uint64_t)
> + rte_mempool_virt2phy(pool, obj_table[n + i])
> + + meta_data_size;
> +#else
> + bufs[i] = (uint64_t)obj_table[n + i] + meta_data_size;
> +#endif
> + }
> +
> + do {
> + ret = qbman_swp_release(swp, &releasedesc, bufs,
> + DPAA2_MBUF_MAX_ACQ_REL);
> + } while (ret == -EBUSY);
> + n += DPAA2_MBUF_MAX_ACQ_REL;
> + }
> +}
> +
> +int hw_mbuf_alloc_bulk(struct rte_mempool *pool,
> + void **obj_table, unsigned count)
> +{
> +#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
> + static int alloc;
> +#endif
> + struct qbman_swp *swp;
> + uint32_t mbuf_size;
> + uint16_t bpid;
> + uint64_t bufs[DPAA2_MBUF_MAX_ACQ_REL];
> + int i, ret;
> + unsigned n = 0;
> + struct dpaa2_bp_info *bp_info;
> +
> + bp_info = mempool_to_bpinfo(pool);
> +
> + if (!(bp_info->bp_list)) {
> + RTE_LOG(ERR, PMD, "DPAA2 buffer pool not configured\n");
> + return -2;
> + }
> +
> + bpid = bp_info->bpid;
> +
> + if (unlikely(!DPAA2_PER_LCORE_DPIO)) {
> + ret = dpaa2_affine_qbman_swp();
> + if (ret != 0) {
> + RTE_LOG(ERR, PMD, "Failed to allocate IO portal");
> + return -1;
> + }
> + }
> + swp = DPAA2_PER_LCORE_PORTAL;
> +
> + mbuf_size = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(pool);
> +
> + while (n < count) {
> + /* Acquire is all-or-nothing, so we drain in 7s,
> + * then the remainder.
> + */
> + if ((count - n) > DPAA2_MBUF_MAX_ACQ_REL) {
> + ret = qbman_swp_acquire(swp, bpid, bufs,
> + DPAA2_MBUF_MAX_ACQ_REL);
> + } else {
> + ret = qbman_swp_acquire(swp, bpid, bufs,
> + count - n);
> + }
> + /* In case of less than requested number of buffers available
> + * in pool, qbman_swp_acquire returns 0
> + */
> + if (ret <= 0) {
> + PMD_TX_LOG(ERR, "Buffer acquire failed with"
> + " err code: %d", ret);
> + /* The API expect the exact number of requested bufs */
> + /* Releasing all buffers allocated */
> + dpaa2_mbuf_release(pool, obj_table, bpid,
> + bp_info->meta_data_size, n);
> + return -1;
> + }
> + /* assigning mbuf from the acquired objects */
> + for (i = 0; (i < ret) && bufs[i]; i++) {
> + /* TODO-errata - observed that bufs may be null
> + * i.e. first buffer is valid,
> + * remaining 6 buffers may be null
> + */
> + obj_table[n] = (struct rte_mbuf *)(bufs[i] - mbuf_size);
> + rte_mbuf_refcnt_set((struct rte_mbuf *)obj_table[n], 0);
> + PMD_TX_LOG(DEBUG, "Acquired %p address %p from BMAN",
> + (void *)bufs[i], (void *)obj_table[n]);
> + n++;
> + }
> + }
> +
> +#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
> + alloc += n;
> + PMD_TX_LOG(DEBUG, "Total = %d , req = %d done = %d",
> + alloc, count, n);
> +#endif
> + return 0;
> +}
> +
> +static int
> +hw_mbuf_free_bulk(struct rte_mempool *pool,
> + void * const *obj_table, unsigned n)
> +{
> + struct dpaa2_bp_info *bp_info;
> +
> + bp_info = mempool_to_bpinfo(pool);
> + if (!(bp_info->bp_list)) {
> + RTE_LOG(ERR, PMD, "DPAA2 buffer pool not configured");
> + return -1;
> + }
> + dpaa2_mbuf_release(pool, obj_table, bp_info->bpid,
> + bp_info->meta_data_size, n);
> +
> + return 0;
> +}
> +
> +struct rte_mempool_ops dpaa2_mpool_ops = {
> + .name = "dpaa2",
> + .alloc = hw_mbuf_create_pool,
> + .free = hw_mbuf_free_pool,
> + .enqueue = hw_mbuf_free_bulk,
> + .dequeue = hw_mbuf_alloc_bulk,
> +};
> +
> +MEMPOOL_REGISTER_OPS(dpaa2_mpool_ops);
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpbp.h b/drivers/net/dpaa2/base/dpaa2_hw_dpbp.h
> new file mode 100644
> index 0000000..6efe24f
> --- /dev/null
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpbp.h
> @@ -0,0 +1,101 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Freescale Semiconductor, Inc nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _DPAA2_HW_DPBP_H_
> +#define _DPAA2_HW_DPBP_H_
> +
> +#define DPAA2_MAX_BUF_POOLS 8
> +
> +struct dpbp_node {
> + struct dpbp_node *next;
> + struct fsl_mc_io dpbp;
> + uint16_t token;
> + int dpbp_id;
> +};
> +
> +struct buf_pool_cfg {
> + void *addr; /*!< The address from where DPAA2 will carve out the
> + * buffers. 'addr' should be 'NULL' if user wants
> + * to create buffers from the memory which user
> + * asked DPAA2 to reserve during 'nadk init' */
> + phys_addr_t phys_addr; /*!< corresponding physical address
> + * of the memory provided in addr */
> + uint32_t num; /*!< number of buffers */
> + uint32_t size; /*!< size of each buffer. 'size' should include
> + * any headroom to be reserved and alignment */
> + uint16_t align; /*!< Buffer alignment (in bytes) */
> + uint16_t bpid; /*!< The buffer pool id. This will be filled
> + *in by DPAA2 for each buffer pool */
> +};
> +
> +struct buf_pool {
> + uint32_t size;
> + uint32_t num_bufs;
> + uint16_t bpid;
> + uint8_t *h_bpool_mem;
> + struct rte_mempool *mp;
> + struct dpbp_node *dpbp_node;
> +};
> +
> +/*!
> + * Buffer pool list configuration structure. User need to give DPAA2 the
> + * valid number of 'num_buf_pools'.
> + */
> +struct dpaa2_bp_list_cfg {
> + struct buf_pool_cfg buf_pool; /* Configuration
> + * of each buffer pool */
> +};
> +
> +struct dpaa2_bp_list {
> + struct dpaa2_bp_list *next;
> + struct rte_mempool *mp;
> + struct buf_pool buf_pool;
> +};
> +
> +struct dpaa2_bp_info {
> + uint32_t meta_data_size;
> + uint32_t bpid;
> + struct dpaa2_bp_list *bp_list;
> +};
> +
> +#define mempool_to_bpinfo(mp) ((struct dpaa2_bp_info *)mp->pool_data)
> +#define mempool_to_bpid(mp) ((mempool_to_bpinfo(mp))->bpid)
> +
> +extern struct dpaa2_bp_info bpid_info[MAX_BPID];
> +
> +int dpaa2_create_dpbp_device(int dpbp_id);
> +
> +int hw_mbuf_alloc_bulk(struct rte_mempool *pool,
> + void **obj_table, unsigned count);
> +
> +#endif /* _DPAA2_HW_DPBP_H_ */
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_pvt.h b/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> index 7dffd5d..5038209 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_pvt.h
> @@ -41,6 +41,13 @@
> #define MC_PORTAL_INDEX 0
> #define NUM_DPIO_REGIONS 2
>
> +#define MEMPOOL_F_HW_PKT_POOL 0x8000 /**< mpool flag to check offloaded pool */
> +
> +/* Maximum release/acquire from QBMAN */
> +#define DPAA2_MBUF_MAX_ACQ_REL 7
> +
> +#define MAX_BPID 256
> +
> struct dpaa2_dpio_dev {
> TAILQ_ENTRY(dpaa2_dpio_dev) next;
> /**< Pointer to Next device instance */
> diff --git a/drivers/net/dpaa2/dpaa2_vfio.c b/drivers/net/dpaa2/dpaa2_vfio.c
> index 71b491b..946a444 100644
> --- a/drivers/net/dpaa2/dpaa2_vfio.c
> +++ b/drivers/net/dpaa2/dpaa2_vfio.c
> @@ -62,7 +62,10 @@
> #include <rte_dpaa2.h>
>
> #include "dpaa2_vfio.h"
> +/* DPAA2 Base interface files */
> +#include <base/dpaa2_hw_pvt.h>
> #include <base/dpaa2_hw_dpio.h>
> +#include <base/dpaa2_hw_dpbp.h>
>
> #define VFIO_MAX_CONTAINERS 1
>
> @@ -272,7 +275,7 @@ int dpaa2_vfio_process_group(struct rte_bus *bus)
> char path[PATH_MAX];
> int64_t v_addr;
> int ndev_count;
> - int dpio_count = 0;
> + int dpio_count = 0, dpbp_count = 0;
> struct dpaa2_vfio_group *group = &vfio_groups[0];
> static int process_once;
>
> @@ -423,12 +426,20 @@ int dpaa2_vfio_process_group(struct rte_bus *bus)
> if (!ret)
> dpio_count++;
> }
> + if (!strcmp(object_type, "dpbp")) {
> + ret = dpaa2_create_dpbp_device(object_id);
> + if (!ret)
> + dpbp_count++;
> + }
> }
> closedir(d);
>
> ret = dpaa2_affine_qbman_swp();
> if (ret)
> DPAA2_VFIO_LOG(DEBUG, "Error in affining qbman swp %d", ret);
> +
> + RTE_LOG(INFO, PMD, "DPAA2: Added dpbp_count = %d dpio_count=%d\n",
> + dpbp_count, dpio_count);
> return 0;
>
> FAILURE:
>
^ permalink raw reply
* Re: [PATCH 15/32] net/dpaa2: dpio routine to affine to crypto threads
From: Ferruh Yigit @ 2016-12-06 19:49 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-16-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> drivers/net/dpaa2/base/dpaa2_hw_dpio.c | 45 ++++++++++++++++++++++++++++++++++
> drivers/net/dpaa2/base/dpaa2_hw_dpio.h | 3 +++
> 2 files changed, 48 insertions(+)
>
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpio.c b/drivers/net/dpaa2/base/dpaa2_hw_dpio.c
> index 4a0a638..9c6eb96 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_dpio.c
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpio.c
> @@ -275,6 +275,51 @@ static inline struct dpaa2_dpio_dev *dpaa2_get_qbman_swp(void)
> }
>
> int
> +dpaa2_affine_qbman_swp_sec(void)
> +{
> + unsigned lcore_id = rte_lcore_id();
> + uint64_t tid = syscall(SYS_gettid);
> +
> + if (lcore_id == LCORE_ID_ANY)
> + lcore_id = rte_get_master_lcore();
> + /* if the core id is not supported */
> + else if (lcore_id >= RTE_MAX_LCORE)
> + return -1;
> +
> + if (dpaa2_io_portal[lcore_id].sec_dpio_dev) {
> + PMD_DRV_LOG(INFO, "DPAA Portal=0x%x (%d) is being shared"
> + " between thread %lu and current %lu",
> + dpaa2_io_portal[lcore_id].sec_dpio_dev,
> + dpaa2_io_portal[lcore_id].sec_dpio_dev->index,
> + dpaa2_io_portal[lcore_id].sec_tid,
> + tid);
> + RTE_PER_LCORE(_dpaa2_io).sec_dpio_dev
> + = dpaa2_io_portal[lcore_id].sec_dpio_dev;
> + rte_atomic16_inc(&dpaa2_io_portal
> + [lcore_id].sec_dpio_dev->ref_count);
> + dpaa2_io_portal[lcore_id].sec_tid = tid;
> +
> + PMD_DRV_LOG(DEBUG, "Old Portal=0x%x (%d) affined thread - %lu",
> + dpaa2_io_portal[lcore_id].sec_dpio_dev,
> + dpaa2_io_portal[lcore_id].sec_dpio_dev->index,
> + tid);
> + return 0;
> + }
> +
> + /* Populate the dpaa2_io_portal structure */
> + dpaa2_io_portal[lcore_id].sec_dpio_dev = dpaa2_get_qbman_swp();
> +
> + if (dpaa2_io_portal[lcore_id].sec_dpio_dev) {
> + RTE_PER_LCORE(_dpaa2_io).sec_dpio_dev
> + = dpaa2_io_portal[lcore_id].sec_dpio_dev;
> + dpaa2_io_portal[lcore_id].sec_tid = tid;
> + return 0;
> + } else {
> + return -1;
> + }
> +}
> +
> +int
> dpaa2_create_dpio_device(struct dpaa2_vfio_device *vdev,
> struct vfio_device_info *obj_info,
> int object_id)
> diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpio.h b/drivers/net/dpaa2/base/dpaa2_hw_dpio.h
> index d90b900..8480ce3 100644
> --- a/drivers/net/dpaa2/base/dpaa2_hw_dpio.h
> +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpio.h
> @@ -57,6 +57,9 @@ struct dpaa2_io_portal_t {
> /* Affine a DPIO portal to current processing thread */
> int dpaa2_affine_qbman_swp(void);
>
> +/* Affine additional DPIO portal to current crypto processing thread */
> +int dpaa2_affine_qbman_swp_sec(void);
Why crypto related code in net driver base folder? Shouldn't these go to
common folder?
> +
> /* create dpio device */
> int dpaa2_create_dpio_device(struct dpaa2_vfio_device *vdev,
> struct vfio_device_info *obj_info,
>
^ permalink raw reply
* Re: [PATCH 13/32] net/dpaa2: add debug log macros
From: Ferruh Yigit @ 2016-12-06 19:49 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-14-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> config/defconfig_arm64-dpaa2-linuxapp-gcc | 2 +
> drivers/net/dpaa2/Makefile | 5 ++
> drivers/net/dpaa2/dpaa2_logs.h | 77 +++++++++++++++++++++++++++++++
> 3 files changed, 84 insertions(+)
> create mode 100644 drivers/net/dpaa2/dpaa2_logs.h
>
> diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> index 00f207e..5ff884b 100644
> --- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
> +++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> @@ -45,3 +45,5 @@ CONFIG_RTE_MAX_NUMA_NODES=1
> # Compile software PMD backed by NXP DPAA2 files
> #
> CONFIG_RTE_LIBRTE_DPAA2_PMD=y
> +CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT=n
> +CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
> diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
> index ab17143..3032708 100644
> --- a/drivers/net/dpaa2/Makefile
> +++ b/drivers/net/dpaa2/Makefile
> @@ -35,8 +35,13 @@ include $(RTE_SDK)/mk/rte.vars.mk
> #
> LIB = librte_pmd_dpaa2.a
>
> +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT),y)
> +CFLAGS += -O0 -g
> +CFLAGS += "-Wno-error"
> +else
> CFLAGS += -O3
> CFLAGS += $(WERROR_FLAGS)
> +endif
>
> CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
> CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/
> diff --git a/drivers/net/dpaa2/dpaa2_logs.h b/drivers/net/dpaa2/dpaa2_logs.h
> new file mode 100644
> index 0000000..956a940
> --- /dev/null
> +++ b/drivers/net/dpaa2/dpaa2_logs.h
> @@ -0,0 +1,77 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Freescale Semiconductor, Inc nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _DPAA2_LOGS_H_
> +#define _DPAA2_LOGS_H_
> +
> +#define PMD_INIT_LOG(level, fmt, args...) \
> + RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ##args)
> +
> +#ifdef RTE_LIBRTE_DPAA2_DEBUG_INIT
> +#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
> +#else
> +#define PMD_INIT_FUNC_TRACE() do { } while (0)
> +#endif
> +
> +#ifdef RTE_LIBRTE_DPAA2_DEBUG_RX
What do you think adding these config option to the config file in this
patch?
> +#define PMD_RX_LOG(level, fmt, args...) \
> + RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
> +#else
> +#define PMD_RX_LOG(level, fmt, args...) do { } while (0)
> +#endif
> +
> +#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX
> +#define PMD_TX_LOG(level, fmt, args...) \
> + RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
> +#else
> +#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
> +#endif
> +
> +#ifdef RTE_LIBRTE_DPAA2_DEBUG_TX_FREE
This config option was not documented?
> +#define PMD_TX_FREE_LOG(level, fmt, args...) \
> + RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
> +#else
> +#define PMD_TX_FREE_LOG(level, fmt, args...) do { } while (0)
> +#endif
> +
> +#ifdef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
> +#define PMD_DRV_LOG_RAW(level, fmt, args...) \
> + RTE_LOG(level, PMD, "%s(): " fmt, __func__, ## args)
> +#else
> +#define PMD_DRV_LOG_RAW(level, fmt, args...) do { } while (0)
> +#endif
> +
> +#define PMD_DRV_LOG(level, fmt, args...) \
> + PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
> +
> +#endif /* _DPAA2_LOGS_H_ */
>
^ permalink raw reply
* Re: [PATCH 10/32] net/dpaa2: introducing dpaa2 bus driver for fsl-mc bus
From: Ferruh Yigit @ 2016-12-06 19:49 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-11-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> The DPAA2 bus driver is a rte_bus driver which scans the fsl-mc bus.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> drivers/net/Makefile | 2 +-
> drivers/net/dpaa2/Makefile | 60 ++++++++++++++
> drivers/net/dpaa2/dpaa2_bus.c | 99 +++++++++++++++++++++++
> drivers/net/dpaa2/rte_dpaa2.h | 121 ++++++++++++++++++++++++++++
> drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
> mk/rte.app.mk | 1 +
> 6 files changed, 286 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/dpaa2/Makefile
> create mode 100644 drivers/net/dpaa2/dpaa2_bus.c
> create mode 100644 drivers/net/dpaa2/rte_dpaa2.h
> create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
>
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index bc93230..2bcf67b 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -55,7 +55,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
> DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
> DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
> -
> +DIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2
Add as alphabetically sorted manner please.
> ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += vhost
> endif # $(CONFIG_RTE_LIBRTE_VHOST)
> diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile
> new file mode 100644
> index 0000000..a99ce22
> --- /dev/null
> +++ b/drivers/net/dpaa2/Makefile
> @@ -0,0 +1,60 @@
> +# BSD LICENSE
> +#
> +# Copyright (c) 2016 NXP. All rights reserved.
> +#
> +# Redistribution and use in source and binary forms, with or without
> +# modification, are permitted provided that the following conditions
> +# are met:
> +#
> +# * Redistributions of source code must retain the above copyright
> +# notice, this list of conditions and the following disclaimer.
> +# * Redistributions in binary form must reproduce the above copyright
> +# notice, this list of conditions and the following disclaimer in
> +# the documentation and/or other materials provided with the
> +# distribution.
> +# * Neither the name of NXP nor the names of its
> +# contributors may be used to endorse or promote products derived
> +# from this software without specific prior written permission.
> +#
> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +#
> +# library name
> +#
> +LIB = librte_pmd_dpaa2.a
> +
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +
> +CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2
> +CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/
> +CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
Last two shouldn't be required.
> +
> +# versioning export map
> +EXPORT_MAP := rte_pmd_dpaa2_version.map
> +
> +# library version
> +LIBABIVER := 1
> +
> +
> +# Interfaces with DPDK
> +SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_bus.c
> +
> +# library dependencies
> +DEPDIRS-y += lib/librte_eal
> +DEPDIRS-y += drivers/common/dpaa/mc
> +DEPDIRS-y += drivers/common/dpaa/qbman
Again for consistency, DEPDIRS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) +=
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/drivers/net/dpaa2/dpaa2_bus.c b/drivers/net/dpaa2/dpaa2_bus.c
> new file mode 100644
> index 0000000..571066c
> --- /dev/null
> +++ b/drivers/net/dpaa2/dpaa2_bus.c
> @@ -0,0 +1,99 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of NXP nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <string.h>
> +#include <dirent.h>
> +
> +#include <rte_log.h>
> +#include <rte_bus.h>
> +#include <rte_dpaa2.h>
> +#include <rte_eal_memconfig.h>
> +#include <rte_malloc.h>
> +#include <rte_devargs.h>
> +#include <rte_memcpy.h>
> +#include <rte_ethdev.h>
> +
> +#include "eal_filesystem.h"
> +#include "eal_private.h"
> +
> +void
> +rte_dpaa2_register(struct rte_dpaa2_driver *driver)
> +{
> + struct rte_bus *bus;
> +
> + bus = rte_eal_get_bus("dpaa2");
> + if (!bus) {
> + RTE_LOG(ERR, EAL, "DPAA2 bus not registered\n");
> + return;
> + }
> +
> + rte_eal_bus_add_driver(bus, &driver->driver);
> +}
> +
> +void
> +rte_dpaa2_unregister(struct rte_dpaa2_driver *driver)
> +{
> + struct rte_bus *bus;
> +
> + bus = driver->driver.bus;
> + if (!bus) {
> + RTE_LOG(ERR, EAL, "Unable to find bus for device\n");
> + return;
> + }
> +
> + rte_eal_bus_remove_driver(&driver->driver);
> +}
> +
> +int rte_dpaa2_probe(struct rte_driver *driver __rte_unused,
> + struct rte_device *device __rte_unused)
> +{
> + return 0;
> +}
> +
> +int rte_dpaa2_scan(struct rte_bus *bus_d __rte_unused)
> +{
> + return 0;
> +}
> +
> +int rte_dpaa2_match(struct rte_driver *driver __rte_unused,
> + struct rte_device *device __rte_unused)
> +{
> + return 0;
> +}
> +
> +struct rte_bus dpaa2_bus = {
> + .scan = rte_dpaa2_scan,
> + .match = rte_dpaa2_match,
> + .probe = rte_dpaa2_probe,
> +};
> +
> +RTE_REGISTER_BUS(dpaa2, dpaa2_bus);
> diff --git a/drivers/net/dpaa2/rte_dpaa2.h b/drivers/net/dpaa2/rte_dpaa2.h
> new file mode 100644
> index 0000000..b36eed8
> --- /dev/null
> +++ b/drivers/net/dpaa2/rte_dpaa2.h
> @@ -0,0 +1,121 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright (c) 2016 NXP. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of NXP nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _RTE_DPAA2_H_
> +#define _RTE_DPAA2_H_
> +
> +/**
> + * @file
> + *
> + * RTE DPAA2 Interface
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <limits.h>
> +#include <errno.h>
> +#include <sys/queue.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +
> +#include <rte_debug.h>
> +#include <rte_interrupts.h>
> +#include <rte_dev.h>
> +
> +
> +struct rte_dpaa2_driver;
> +/**
> + * A structure describing a DPAA2 device.
> + */
> +struct rte_dpaa2_device {
> + TAILQ_ENTRY(rte_dpaa2_device) next; /**< Next probed DPAA2 device. */
> + struct rte_device device; /**< Inherit core device */
> + uint16_t dev_type; /**< Device Type */
> + uint16_t object_id; /**< DPAA2 Object ID */
> + struct rte_intr_handle intr_handle; /**< Interrupt handle */
> + struct rte_dpaa2_driver *driver; /**< Associated driver */
> +};
> +
> +/**
> + * A structure describing a DPAA2 driver.
> + */
> +struct rte_dpaa2_driver {
> + TAILQ_ENTRY(rte_dpaa2_driver) next; /**< Next in list. */
> + struct rte_driver driver; /**< Inherit core driver. */
> + uint32_t drv_flags; /**< Flags contolling handling of device. */
> +};
> +
> +/**
> + * Register a DPAA2 driver.
> + *
> + * @param driver
> + * A pointer to a rte_dpaa2_driver structure describing the driver
> + * to be registered.
> + */
> +void rte_dpaa2_register(struct rte_dpaa2_driver *driver);
> +
> +/**
> + * Unregister a DPAA2 driver.
> + *
> + * @param driver
> + * A pointer to a rte_dpaa2_driver structure describing the driver
> + * to be unregistered.
> + */
> +void rte_dpaa2_unregister(struct rte_dpaa2_driver *driver);
> +
> +/**
> + *
> + */
> +int rte_dpaa2_probe(struct rte_driver *driver, struct rte_device *device);
> +int rte_dpaa2_match(struct rte_driver *driver, struct rte_device *device);
> +int rte_dpaa2_scan(struct rte_bus *bus);
Shouldn't these functions be static?
> +
> +/** Helper for DPAA2 device registration from driver (eth, crypto) instance */
> +#define RTE_PMD_REGISTER_DPAA2(nm, dpaa2_drv) \
> +RTE_INIT(dpaa2initfn_ ##nm); \
> +static void dpaa2initfn_ ##nm(void) \
> +{\
> + (dpaa2_drv).driver.name = RTE_STR(nm);\
> + rte_dpaa2_register(&dpaa2_drv); \
> +} \
> +RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
> +
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_DPAA2_H_ */
> diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
> new file mode 100644
> index 0000000..31eca32
> --- /dev/null
> +++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
> @@ -0,0 +1,4 @@
> +DPDK_17.02 {
> +
> + local: *;
> +};
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index f75f0e2..9e1c17c 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -101,6 +101,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
>
> _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
> _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lrte_pmd_xenvirt -lxenstore
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2 -ldpaa2_mc -ldpaa2_qbman
This should go within no shared library case (below), in a sorted manner
please.
btw, for shared compilation, PMDs loaded dynamically, as plugins. For
dpaa case, there will be multiple libraries, not if it will work with
multiple -d params for each lib, it worth testing.
>
> ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
> # plugins (link only if static libraries)
>
^ permalink raw reply
* Re: [PATCH 09/32] lib/ether: add rte_device in rte_eth_dev
From: Ferruh Yigit @ 2016-12-06 19:48 UTC (permalink / raw)
To: Hemant Agrawal, dev; +Cc: thomas.monjalon, bruce.richardson, shreyansh.jain
In-Reply-To: <1480875447-23680-10-git-send-email-hemant.agrawal@nxp.com>
On 12/4/2016 6:17 PM, Hemant Agrawal wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> lib/librte_ether/rte_ethdev.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 3c45a1f..6f5673f 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -1626,6 +1626,7 @@ struct rte_eth_dev {
> eth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */
> eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
> struct rte_eth_dev_data *data; /**< Pointer to device data */
> + struct rte_device *device;
I believe this change should not be part of a PMD patchset. This change
is more generic than the PMD.
Won't Shreyansh's patch already do this?
> const struct eth_driver *driver;/**< Driver for this device */
> const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
> struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox