This series intended to add support for placing CPDMA descriptors into DDR by
introducing new DT property "descs_pool_size" to specify buffer descriptor's
pool size. The "descs_pool_size" defines total number of CPDMA
CPPI descriptors to be used for both ingress/egress packets
processing. If not specified - the default value 256 will be used
which will allow to place descriptor's pool into the internal CPPI
RAM.
This allows significantly to reduce UDP packets drop rate
for bandwidth >301 Mbits/sec (am57x).
Before enabling this feature, the am437x SoC has to be fixed as it's proved
that it's not working when CPDMA descriptors placed in DDR.
So, the patch 1 fixes this issue.
Grygorii Strashko (7):
net: ethernet: ti: cpdma: am437x: allow descs to be plased in ddr
net: ethernet: ti: cpdma: fix desc re-queuing
net: ethernet: ti: cpdma: minimize number of parameters in
cpdma_desc_pool_create/destroy()
net: ethernet: ti: cpdma: use devm_ioremap
Documentation: DT: net: cpsw: allow to specify descriptors pool size
net: ethernet: ti: cpsw: add support for descs_pool_size dt property
Documentation: DT: net: cpsw: remove no_bd_ram property
Documentation/devicetree/bindings/net/cpsw.txt | 8 ++-
arch/arm/boot/dts/am33xx.dtsi | 1 -
arch/arm/boot/dts/am4372.dtsi | 1 -
arch/arm/boot/dts/dm814x.dtsi | 1 -
arch/arm/boot/dts/dra7.dtsi | 1 -
drivers/net/ethernet/ti/cpsw.c | 5 ++
drivers/net/ethernet/ti/cpsw.h | 1 +
drivers/net/ethernet/ti/davinci_cpdma.c | 90 +++++++++++++++-----------
drivers/net/ethernet/ti/davinci_cpdma.h | 1 +
9 files changed, 63 insertions(+), 46 deletions(-)
--
2.10.1
It's observed that cpsw/cpdma is not working properly when CPPI
descriptors are placed in DDR instead of internal CPPI RAM on am437x
SoC:
- rx/tx silently stops processing packets;
- or - after boot it's working for sometime, but stuck once Network
load is increased (ping is working, but iperf is not).
(The same issue has not been reproduced on am335x and am57xx).
It seems that write to HDP register processed faster by interconnect
than writing of descriptor memory buffer in DDR, which is probably
caused by store buffer / write buffer differences as these function
are implemented differently across devices. So, to fix this i come up
with two changes:
1) all accesses to the channel register HDP/CP/RXFREE registers should
be done using sync IO accessors readl()/writel(), because all previous
memory writes writes have to be completed before starting channel
(write to HDP) or completing desc processing.
2) the change 1 only doesn't work on am437x and additional reading of
desc's field is required right after the new descriptor was filled
with data and before pointer on it will be stored in
prev_desc->hw_next field or HDP register.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
Update cpdma_desc_pool_create/destroy() to accept only one parameter
struct cpdma_ctlr*, as this structure contains all required
information for pool creation/destruction.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 66 ++++++++++++++++-----------------
1 file changed, 33 insertions(+), 33 deletions(-)
The currently processing cpdma descriptor with EOQ flag set may
contain two values in Next Descriptor Pointer field:
- valid pointer: means CPDMA missed addition of new desc in queue;
- null: no more descriptors in queue.
In the later case, it's not required to write to HDP register, but now
CPDMA does it.
Hence, add additional check for Next Descriptor Pointer != null in
cpdma_chan_process() function before writing in HDP register.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Add optional property "descs_pool_size" to specify buffer descriptor's
pool size. The "descs_pool_size" should define total number of CPDMA
CPPI descriptors to be used for both ingress/egress packets
processing. If not specified - the default value 256 will be used
which will allow to place descriptor's pool into the internal CPPI
RAM on most of TI SoC.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/cpsw.txt | 5 +++++
1 file changed, 5 insertions(+)
@@ -35,6 +35,11 @@ Optional properties: For example in dra72x-evm, pcf gpio has to be driven low so that cpsw slave 0 and phy data lines are connected via mux.+- descs_pool_size : total number of CPDMA CPPI descriptors to be used for+ both ingress/egress packets processing. if not+ specified the default value 256 will be used which+ will allow to place descriptors pool into the+ internal CPPI RAM. Slave Properties:
The CPSW CPDMA can process buffer descriptors placed as in internal
CPPI RAM as in DDR. This patch adds support in CPSW and CPDMA for
descs_pool_size DT property, which defines total number of CPDMA CPPI
descriptors to be used for both ingress/egress packets processing:
- memory size required for CPDMA descriptor pool is calculated basing
on number of descriptors specified by user in descs_pool_size and
CPDMA descriptor size;
- allocate CPDMA descriptor pool in DDR if pool memory size >
internal CPPI RAM or use internal CPPI RAM otherwise;
- if descs_pool_size not specified in DT - the default value 256 will
be used which will allow to place CPDMA descriptors pool into the
internal CPPI RAM (current default behaviour);
- CPDMA will ignore descs_pool_size if descs_pool_size = 0 for
backward comaptiobility with davinci_emac.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpsw.c | 5 +++++
drivers/net/ethernet/ti/cpsw.h | 1 +
drivers/net/ethernet/ti/davinci_cpdma.c | 12 ++++++++++++
drivers/net/ethernet/ti/davinci_cpdma.h | 1 +
4 files changed, 19 insertions(+)
@@ -38,6 +38,7 @@ struct cpsw_platform_data {u32mac_control;/* Mac control register */u16default_vlan;/* Def VLAN for ALE lookup in VLAN aware mode*/booldual_emac;/* Enable Dual EMAC mode */+u32descs_pool_size;/* Number of Rx/Tx Descriptios */};voidcpsw_phy_sel(structdevice*dev,phy_interface_tphy_mode,intslave);
Even if no_bd_ram property is described in TI CPSW bindings the
support for it has never been introduced in CPSW driver, so there are
no real users of it. Hence, remove no_bd_ram property.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/cpsw.txt | 3 ---
arch/arm/boot/dts/am33xx.dtsi | 1 -
arch/arm/boot/dts/am4372.dtsi | 1 -
arch/arm/boot/dts/dm814x.dtsi | 1 -
arch/arm/boot/dts/dra7.dtsi | 1 -
5 files changed, 7 deletions(-)
@@ -25,7 +25,6 @@ Required properties: Optional properties: - ti,hwmods : Must be "cpgmac0"-- no_bd_ram : Must be 0 or 1 - dual_emac : Specifies Switch to act as Dual EMAC - syscon : Phandle to the system control device node, which is the control module device of the am33x
From: Ivan Khoronzhuk <hidden> Date: 2016-12-02 11:03:29
On Thu, Dec 01, 2016 at 05:34:27PM -0600, Grygorii Strashko wrote:
The currently processing cpdma descriptor with EOQ flag set may
contain two values in Next Descriptor Pointer field:
- valid pointer: means CPDMA missed addition of new desc in queue;
It shouldn't happen in normal circumstances, right?
So, why it happens only for egress channels? And Does that mean
there is some resynchronization between submit and process function,
or this is h/w issue?
quoted hunk
- null: no more descriptors in queue.
In the later case, it's not required to write to HDP register, but now
CPDMA does it.
Hence, add additional check for Next Descriptor Pointer != null in
cpdma_chan_process() function before writing in HDP register.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Ivan Khoronzhuk <hidden> Date: 2016-12-02 11:28:45
On Thu, Dec 01, 2016 at 05:34:30PM -0600, Grygorii Strashko wrote:
quoted hunk
Add optional property "descs_pool_size" to specify buffer descriptor's
pool size. The "descs_pool_size" should define total number of CPDMA
CPPI descriptors to be used for both ingress/egress packets
processing. If not specified - the default value 256 will be used
which will allow to place descriptor's pool into the internal CPPI
RAM on most of TI SoC.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/cpsw.txt | 5 +++++
1 file changed, 5 insertions(+)
@@ -35,6 +35,11 @@ Optional properties: For example in dra72x-evm, pcf gpio has to be driven low so that cpsw slave 0 and phy data lines are connected via mux.+- descs_pool_size : total number of CPDMA CPPI descriptors to be used for+ both ingress/egress packets processing. if not+ specified the default value 256 will be used which+ will allow to place descriptors pool into the+ internal CPPI RAM.
Does it describe h/w? Why now module parameter? or even smth like ethtool num
ring entries?
On Thu, Dec 01, 2016 at 05:34:27PM -0600, Grygorii Strashko wrote:
quoted
The currently processing cpdma descriptor with EOQ flag set may
contain two values in Next Descriptor Pointer field:
- valid pointer: means CPDMA missed addition of new desc in queue;
It shouldn't happen in normal circumstances, right?
it might happen, because desc push compete with desc pop.
You can check stats values:
chan->stats.misqueued
chan->stats.requeue
under different types of net-loads.
TRM:
"
If the pNext pointer is initially NULL, and more packets need to be queued for transmit, the software
application may alter this pointer to point to a newly appended descriptor. The EMAC will use the new
pointer value and proceed to the next descriptor unless the pNext value has already been read. In this
latter case, the transmitter will halt on the transmit channel in question, and the software application may
restart it at that time. The software can detect this case by checking for an end of queue (EOQ) condition
flag on the updated packet descriptor when it is returned by the EMAC.
"
So, why it happens only for egress channels? And Does that mean
there is some resynchronization between submit and process function,
or this is h/w issue?
no hw issues. this patch just removes one unnecessary I/O access
quoted
- null: no more descriptors in queue.
In the later case, it's not required to write to HDP register, but now
CPDMA does it.
Hence, add additional check for Next Descriptor Pointer != null in
cpdma_chan_process() function before writing in HDP register.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
On Thu, Dec 01, 2016 at 05:34:30PM -0600, Grygorii Strashko wrote:
quoted
Add optional property "descs_pool_size" to specify buffer descriptor's
pool size. The "descs_pool_size" should define total number of CPDMA
CPPI descriptors to be used for both ingress/egress packets
processing. If not specified - the default value 256 will be used
which will allow to place descriptor's pool into the internal CPPI
RAM on most of TI SoC.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/cpsw.txt | 5 +++++
1 file changed, 5 insertions(+)
@@ -35,6 +35,11 @@ Optional properties: For example in dra72x-evm, pcf gpio has to be driven low so that cpsw slave 0 and phy data lines are connected via mux.+- descs_pool_size : total number of CPDMA CPPI descriptors to be used for+ both ingress/egress packets processing. if not+ specified the default value 256 will be used which+ will allow to place descriptors pool into the+ internal CPPI RAM.
Does it describe h/w? Why now module parameter? or even smth like ethtool num
ring entries?
It can be module parameter too. in general this is expected to be
one-time boot setting only.
----- OR
So, do you propose to use
ethtool -g ethX
ethtool -G ethX [rx N] [tx N]
?
Now cpdma has one pool for all RX/TX channels, so changing this settings
by ethtool will require: pause interfaces, reallocate cpdma pool,
re-arrange buffers between channels, resume interface. Correct?
How do you think - we can move forward with one pool or better to have two (Rx and Tx)?
Wouldn't it be reasonable to still have DT (or module) parameter to avoid
cpdma reconfiguration on system startup (pause/resume interfaces) (faster boot)?
How about cpdma re-allocation policy (with expectation that is shouldn't happen too often)?
- increasing of Rx, Tx will grow total number of physically allocated buffers (total_desc_num)
- decreasing of Rx, Tx will just change number of available buffers (no memory re-allocation)
----- OR ----
Can we move forward with current patch (total number of CPDMA CPPI descriptors defined in DT)
and add ethtool -G ethX [rx N] [tx N] which will allow to re-split descs between RX and TX?
--
regards,
-grygorii
On Thu, Dec 01, 2016 at 05:34:30PM -0600, Grygorii Strashko wrote:
quoted
Add optional property "descs_pool_size" to specify buffer descriptor's
pool size. The "descs_pool_size" should define total number of CPDMA
CPPI descriptors to be used for both ingress/egress packets
processing. If not specified - the default value 256 will be used
which will allow to place descriptor's pool into the internal CPPI
RAM on most of TI SoC.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/cpsw.txt | 5 +++++
1 file changed, 5 insertions(+)
@@ -35,6 +35,11 @@ Optional properties: For example in dra72x-evm, pcf gpio has to be driven low so that cpsw slave 0 and phy data lines are connected via mux.+- descs_pool_size : total number of CPDMA CPPI descriptors to be used for+ both ingress/egress packets processing. if not+ specified the default value 256 will be used which+ will allow to place descriptors pool into the+ internal CPPI RAM.
Does it describe h/w? Why now module parameter? or even smth like ethtool num
ring entries?
It can be module parameter too. for the use cases i'm aware of -
this is one-time boot setting only.
----- OR
So, do you propose to use
ethtool -g ethX
ethtool -G ethX [rx N] [tx N]
?
Now cpdma has one pool for all RX/TX channels, so changing this settings
by ethtool will require: pause interfaces, reallocate cpdma pool,
re-arrange buffers between channels, resume interface. Correct?
How do you think - we can move forward with one pool or better to have two (Rx and Tx)?
Wouldn't it be reasonable to still have DT (or module) parameter to avoid
cpdma reconfiguration on system startup (pause/resume interfaces) (faster boot)?
How about cpdma re-allocation policy (with expectation that is shouldn't happen too often)?
- increasing of Rx, Tx will grow total number of physically allocated buffers (total_desc_num)
- decreasing of Rx, Tx will just change number of available buffers (no memory re-allocation)
----- OR ----
Can we move forward with current patch (total number of CPDMA CPPI descriptors defined in DT)
and add ethtool -G ethX [rx N] [tx N] which will allow to re-split descs between RX and TX?
--
regards,
-grygorii
From: Ivan Khoronzhuk <hidden> Date: 2016-12-02 23:28:29
On Fri, Dec 02, 2016 at 10:45:07AM -0600, Grygorii Strashko wrote:
On 12/02/2016 05:03 AM, Ivan Khoronzhuk wrote:
quoted
On Thu, Dec 01, 2016 at 05:34:27PM -0600, Grygorii Strashko wrote:
quoted
The currently processing cpdma descriptor with EOQ flag set may
contain two values in Next Descriptor Pointer field:
- valid pointer: means CPDMA missed addition of new desc in queue;
It shouldn't happen in normal circumstances, right?
it might happen, because desc push compete with desc pop.
You can check stats values:
chan->stats.misqueued
chan->stats.requeue
under different types of net-loads.
I've done this, of-course.
By whole logic the misqueued counter has to cover all cases.
But that's not true.
TRM:
"
If the pNext pointer is initially NULL, and more packets need to be queued for transmit, the software
application may alter this pointer to point to a newly appended descriptor. The EMAC will use the new
pointer value and proceed to the next descriptor unless the pNext value has already been read. In this
latter case, the transmitter will halt on the transmit channel in question, and the software application may
restart it at that time. The software can detect this case by checking for an end of queue (EOQ) condition
flag on the updated packet descriptor when it is returned by the EMAC.
"
That's true. No issues in desc.
In the code no any place to update next_desc except submit function.
And this case is supposed to be caught here:
For submit:
cpdma_chan_submit()
spin_lock_irqsave(&chan->lock);
...
--->__cpdma_chan_submit()
...
------> desc_write(prev, hw_next, desc_dma); // here next pointer is updated, it can be not in time
...
------> mode = desc_read(prev, hw_mode); // pay attention, it's read after updating next pointer
------> if ((mode & CPDMA_DESC_EOQ) &&
------> (chan->state == CPDMA_STATE_ACTIVE)) { // here checked if it was late update
---------> chan_write(chan, hdp, desc_dma); // here transmit is restarted, if needed
For process it only caught the fact of late update, but it has to be caught in
submit() already:
__cpdma_chan_process()
spin_lock_irqsave(&chan->lock);
------> if (mode & CPDMA_DESC_EOQ) // here transmit is restarted, if needed
---------> chan_write(chan, hdp, desc_dma); // but w/o updating next pointer
Seems there is no place where hw_next is updated w/o updating hdp :-| in case
of late hw_next set. And that is strange. I know it happens, I've checked it
before of-course. Then I thought, maybe there is some problem with write order,
thus out of sync, nothing more.
quoted
So, why it happens only for egress channels? And Does that mean
there is some resynchronization between submit and process function,
or this is h/w issue?
no hw issues. this patch just removes one unnecessary I/O access
No objections against patch. Anyway it's better then before.
Just want to know the real reason why it happens, maybe there is smth else.
quoted
quoted
- null: no more descriptors in queue.
In the later case, it's not required to write to HDP register, but now
CPDMA does it.
Hence, add additional check for Next Descriptor Pointer != null in
cpdma_chan_process() function before writing in HDP register.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Ivan Khoronzhuk <hidden> Date: 2016-12-03 00:37:10
On Fri, Dec 02, 2016 at 11:22:28AM -0600, Grygorii Strashko wrote:
On 12/02/2016 05:28 AM, Ivan Khoronzhuk wrote:
quoted
On Thu, Dec 01, 2016 at 05:34:30PM -0600, Grygorii Strashko wrote:
quoted
Add optional property "descs_pool_size" to specify buffer descriptor's
pool size. The "descs_pool_size" should define total number of CPDMA
CPPI descriptors to be used for both ingress/egress packets
processing. If not specified - the default value 256 will be used
which will allow to place descriptor's pool into the internal CPPI
RAM on most of TI SoC.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/cpsw.txt | 5 +++++
1 file changed, 5 insertions(+)
@@ -35,6 +35,11 @@ Optional properties: For example in dra72x-evm, pcf gpio has to be driven low so that cpsw slave 0 and phy data lines are connected via mux.+- descs_pool_size : total number of CPDMA CPPI descriptors to be used for+ both ingress/egress packets processing. if not+ specified the default value 256 will be used which+ will allow to place descriptors pool into the+ internal CPPI RAM.
Does it describe h/w? Why now module parameter? or even smth like ethtool num
ring entries?
It can be module parameter too. in general this is expected to be
one-time boot setting only.
----- OR
So, do you propose to use
ethtool -g ethX
ethtool -G ethX [rx N] [tx N]
?
It has a little different names, but yes, why not?
No need, maybe, but....It's just a proposition, at least I was thinking
about it after proposition from +cc Schuyler Patton to leave rx desc num
property. In this case it's possible to tune tx/rx desc num ratio, even
with SRAM descs.
Now cpdma has one pool for all RX/TX channels, so changing this settings
by ethtool will require: pause interfaces, reallocate cpdma pool,
Pause can lead to losts only for rx, and only for very short time, so
it's not very bad, especially when user knows what he is doing.
re-arrange buffers between channels, resume interface. Correct?
correct.
But, some alternative variants can be used, like replacing descriptors.
Shrink num of desc for every channels to 1, replace/add others, and expand.
In this case no losts, but it's harder to debug issues after....
How do you think - we can move forward with one pool or better to have two (Rx and Tx)?
I think one is enough, just split, if no harm on perf.
Wouldn't it be reasonable to still have DT (or module) parameter to avoid
cpdma reconfiguration on system startup (pause/resume interfaces) (faster boot)?
Would be, your choice, but it's not flexible.
How about cpdma re-allocation policy (with expectation that is shouldn't happen too often)?
- increasing of Rx, Tx will grow total number of physically allocated buffers (total_desc_num)
- decreasing of Rx, Tx will just change number of available buffers (no memory re-allocation)
----- OR ----
Can we move forward with current patch (total number of CPDMA CPPI descriptors defined in DT)
and add ethtool -G ethX [rx N] [tx N] which will allow to re-split descs between RX and TX?
No objections, It anyway requires re-allocations. Re-split of Rx and Tx will
not have a lot changes as most code exists already.
Unless you want to keep running into subtle errors all over the
place wrt. register vs. memory write ordering, I strong suggest
you use strongly ordered readl/writel for all register accesses.
I see no tangible, worthwhile, advantage to using these relaxed
ordering primitives. The only result is potential bugs.
People who use the relaxed ordering primitives properly are only
doing so in extremely carefully coded sequences where a series
of writes has no dependency on main memory operations and is
explicitly completed with a barrier operation such as a read
back of a register in the same device.
That's not at all what is going on here, instead the driver is wildly
using relaxed ordered register accesses for basically everything.
This is extremely unwise and it's why you ran into this bug in the
first place.
Therefore, I absolutely require that you fix this by eliminating
any and all usese of relaxed ordering I/O accessors in this driver.
Thank you.
Unless you want to keep running into subtle errors all over the
place wrt. register vs. memory write ordering, I strong suggest
you use strongly ordered readl/writel for all register accesses.
I see no tangible, worthwhile, advantage to using these relaxed
ordering primitives. The only result is potential bugs.
People who use the relaxed ordering primitives properly are only
doing so in extremely carefully coded sequences where a series
of writes has no dependency on main memory operations and is
explicitly completed with a barrier operation such as a read
back of a register in the same device.
That's not at all what is going on here, instead the driver is wildly
using relaxed ordered register accesses for basically everything.
This is extremely unwise and it's why you ran into this bug in the
first place.
Therefore, I absolutely require that you fix this by eliminating
any and all usese of relaxed ordering I/O accessors in this driver.
Thanks for your comments - that's what I've tried first, but that decided
to find out minimal change which still works.
I'll update it.
--
regards,
-grygorii
On Fri, Dec 02, 2016 at 10:45:07AM -0600, Grygorii Strashko wrote:
quoted
On 12/02/2016 05:03 AM, Ivan Khoronzhuk wrote:
quoted
On Thu, Dec 01, 2016 at 05:34:27PM -0600, Grygorii Strashko wrote:
quoted
The currently processing cpdma descriptor with EOQ flag set may
contain two values in Next Descriptor Pointer field:
- valid pointer: means CPDMA missed addition of new desc in queue;
It shouldn't happen in normal circumstances, right?
it might happen, because desc push compete with desc pop.
You can check stats values:
chan->stats.misqueued
chan->stats.requeue
under different types of net-loads.
I've done this, of-course.
By whole logic the misqueued counter has to cover all cases.
But that's not true.
quoted
TRM:
"
If the pNext pointer is initially NULL, and more packets need to be queued for transmit, the software
application may alter this pointer to point to a newly appended descriptor. The EMAC will use the new
pointer value and proceed to the next descriptor unless the pNext value has already been read. In this
latter case, the transmitter will halt on the transmit channel in question, and the software application may
restart it at that time. The software can detect this case by checking for an end of queue (EOQ) condition
flag on the updated packet descriptor when it is returned by the EMAC.
"
That's true. No issues in desc.
In the code no any place to update next_desc except submit function.
And this case is supposed to be caught here:
For submit:
cpdma_chan_submit()
spin_lock_irqsave(&chan->lock);
...
--->__cpdma_chan_submit()
...
------> desc_write(prev, hw_next, desc_dma); // here next pointer is updated, it can be not in time
...
------> mode = desc_read(prev, hw_mode); // pay attention, it's read after updating next pointer
------> if ((mode & CPDMA_DESC_EOQ) &&
------> (chan->state == CPDMA_STATE_ACTIVE)) { // here checked if it was late update
---------> chan_write(chan, hdp, desc_dma); // here transmit is restarted, if needed
You've forgot about CPPI hw itself - it's not sync by sw, and so continue run in
background - as result, CPPI might read "next" already, but flags are not updated yet.
For process it only caught the fact of late update, but it has to be caught in
submit() already:
__cpdma_chan_process()
spin_lock_irqsave(&chan->lock);
------> if (mode & CPDMA_DESC_EOQ) // here transmit is restarted, if needed
---------> chan_write(chan, hdp, desc_dma); // but w/o updating next pointer
Seems there is no place where hw_next is updated w/o updating hdp :-| in case
of late hw_next set. And that is strange. I know it happens, I've checked it
before of-course. Then I thought, maybe there is some problem with write order,
thus out of sync, nothing more.
quoted
quoted
So, why it happens only for egress channels? And Does that mean
there is some resynchronization between submit and process function,
or this is h/w issue?
no hw issues. this patch just removes one unnecessary I/O access
No objections against patch. Anyway it's better then before.
Just want to know the real reason why it happens, maybe there is smth else.
quoted
quoted
quoted
- null: no more descriptors in queue.
In the later case, it's not required to write to HDP register, but now
CPDMA does it.
Hence, add additional check for Next Descriptor Pointer != null in
cpdma_chan_process() function before writing in HDP register.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
On Thu, Dec 01, 2016 at 05:34:30PM -0600, Grygorii Strashko wrote:
quoted
Add optional property "descs_pool_size" to specify buffer descriptor's
pool size. The "descs_pool_size" should define total number of CPDMA
CPPI descriptors to be used for both ingress/egress packets
processing. If not specified - the default value 256 will be used
which will allow to place descriptor's pool into the internal CPPI
RAM on most of TI SoC.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/cpsw.txt | 5 +++++
1 file changed, 5 insertions(+)
@@ -35,6 +35,11 @@ Optional properties: For example in dra72x-evm, pcf gpio has to be driven low so that cpsw slave 0 and phy data lines are connected via mux.+- descs_pool_size : total number of CPDMA CPPI descriptors to be used for+ both ingress/egress packets processing. if not+ specified the default value 256 will be used which+ will allow to place descriptors pool into the+ internal CPPI RAM.
Does it describe h/w? Why now module parameter? or even smth like ethtool num
ring entries?
It can be module parameter too. for the use cases i'm aware of -
this is one-time boot setting only.
----- OR
So, do you propose to use
ethtool -g ethX
ethtool -G ethX [rx N] [tx N]
?
Now cpdma has one pool for all RX/TX channels, so changing this settings
by ethtool will require: pause interfaces, reallocate cpdma pool,
re-arrange buffers between channels, resume interface. Correct?
How do you think - we can move forward with one pool or better to have two (Rx and Tx)?
Wouldn't it be reasonable to still have DT (or module) parameter to avoid
cpdma reconfiguration on system startup (pause/resume interfaces) (faster boot)?
How about cpdma re-allocation policy (with expectation that is shouldn't happen too often)?
- increasing of Rx, Tx will grow total number of physically allocated buffers (total_desc_num)
- decreasing of Rx, Tx will just change number of available buffers (no memory re-allocation)
----- OR ----
Can we move forward with current patch (total number of CPDMA CPPI descriptors defined in DT)
and add ethtool -G ethX [rx N] [tx N] which will allow to re-split descs between RX and TX?
if no comments here, I'll rework patches to use module parameter for descs_pool_size and
will add possibility to re-split RX/TX buffers using ethtool -G ethX [rx N] [tx N]
--
regards,
-grygorii