[6/7] e1000: eliminate duplicate barriers on weakly-ordered archs

Message ID 1520997629-17361-6-git-send-email-okaya@codeaurora.org
State Changes Requested
Delegated to: David Miller
Headers show
Series
  • [1/7] i40e/i40evf: Eliminate duplicate barriers on weakly-ordered archs
Related show

Commit Message

Sinan Kaya March 14, 2018, 3:20 a.m.
Code includes wmb() followed by writel(). writel() already has a barrier
on some architectures like arm64.

This ends up CPU observing two barriers back to back before executing the
register write.

Since code already has an explicit barrier call, changing writel() to
writel_relaxed().

Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
---
 drivers/net/ethernet/intel/e1000/e1000_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Alexander Duyck March 15, 2018, 1:41 a.m. | #1
On Tue, Mar 13, 2018 at 8:20 PM, Sinan Kaya <okaya@codeaurora.org> wrote:
> Code includes wmb() followed by writel(). writel() already has a barrier
> on some architectures like arm64.
>
> This ends up CPU observing two barriers back to back before executing the
> register write.
>
> Since code already has an explicit barrier call, changing writel() to
> writel_relaxed().
>
> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
> ---
>  drivers/net/ethernet/intel/e1000/e1000_main.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
> index 3dd4aeb..e0e583a 100644
> --- a/drivers/net/ethernet/intel/e1000/e1000_main.c
> +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
> @@ -4573,7 +4573,7 @@ e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
>                  * such as IA-64).
>                  */
>                 wmb();
> -               writel(i, adapter->hw.hw_addr + rx_ring->rdt);
> +               writel_relaxed(i, adapter->hw.hw_addr + rx_ring->rdt);
>         }
>  }
>
> @@ -4688,7 +4688,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
>                  * such as IA-64).
>                  */
>                 wmb();
> -               writel(i, hw->hw_addr + rx_ring->rdt);
> +               writel_relaxed(i, hw->hw_addr + rx_ring->rdt);
>         }
>  }
>

So you missed the writel in e1000_xmit_frame. You should probably get
that one too while you are doing these updates. The wmb() is in
e1000_tx_queue().
Sinan Kaya March 15, 2018, 11:30 p.m. | #2
On 3/14/2018 9:41 PM, Alexander Duyck wrote:
>>  }
>>
> So you missed the writel in e1000_xmit_frame. You should probably get
> that one too while you are doing these updates. The wmb() is in
> e1000_tx_queue().
> 

I brought wmb() outside along with the next descriptor assignment to be
similar to the rest of the other code.

if wmb() and writel() are not visible in the same function, let's not touch
the code.
Alexander Duyck March 16, 2018, 12:25 a.m. | #3
On Thu, Mar 15, 2018 at 4:30 PM, Sinan Kaya <okaya@codeaurora.org> wrote:
> On 3/14/2018 9:41 PM, Alexander Duyck wrote:
>>>  }
>>>
>> So you missed the writel in e1000_xmit_frame. You should probably get
>> that one too while you are doing these updates. The wmb() is in
>> e1000_tx_queue().
>>
>
> I brought wmb() outside along with the next descriptor assignment to be
> similar to the rest of the other code.
>
> if wmb() and writel() are not visible in the same function, let's not touch
> the code.

Maybe for e1000 we should just skip the driver entirely. Odds are you
aren't going to have any e1000 parts running on ARM anyway since most
of them are legacy PCI or PCI-X parts that were made over 10 years
ago. Most of your efforts would probably be best spent on igb, igbvf,
ixgbe, ixgbevf, i40e, i40evf, and fm10k.
Sinan Kaya March 16, 2018, 12:50 a.m. | #4
On 3/15/2018 8:25 PM, Alexander Duyck wrote:
> On Thu, Mar 15, 2018 at 4:30 PM, Sinan Kaya <okaya@codeaurora.org> wrote:
>> On 3/14/2018 9:41 PM, Alexander Duyck wrote:
>>>>  }
>>>>
>>> So you missed the writel in e1000_xmit_frame. You should probably get
>>> that one too while you are doing these updates. The wmb() is in
>>> e1000_tx_queue().
>>>
>>
>> I brought wmb() outside along with the next descriptor assignment to be
>> similar to the rest of the other code.
>>
>> if wmb() and writel() are not visible in the same function, let's not touch
>> the code.
> 
> Maybe for e1000 we should just skip the driver entirely. Odds are you
> aren't going to have any e1000 parts running on ARM anyway since most
> of them are legacy PCI or PCI-X parts that were made over 10 years
> ago. Most of your efforts would probably be best spent on igb, igbvf,
> ixgbe, ixgbevf, i40e, i40evf, and fm10k.
> 

Sure. I'll drop it.

Patch

diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 3dd4aeb..e0e583a 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -4573,7 +4573,7 @@  e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
 		 * such as IA-64).
 		 */
 		wmb();
-		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
+		writel_relaxed(i, adapter->hw.hw_addr + rx_ring->rdt);
 	}
 }
 
@@ -4688,7 +4688,7 @@  static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
 		 * such as IA-64).
 		 */
 		wmb();
-		writel(i, hw->hw_addr + rx_ring->rdt);
+		writel_relaxed(i, hw->hw_addr + rx_ring->rdt);
 	}
 }