linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
@ 2019-02-06  2:27 Paul Zimmerman
  2019-02-06  2:52 ` Joe Perches
  0 siblings, 1 reply; 16+ messages in thread
From: Paul Zimmerman @ 2019-02-06  2:27 UTC (permalink / raw)
  To: Joe Perches; +Cc: Eric Dumazet, Heiner Kallweit, David Miller, linux-kernel

On Tue, 2019-02-05, Joe Perches wrote:
> On Tue, 2019-02-05 at 12:04 -0800, Eric Dumazet wrote:
>> 
>> On 02/05/2019 10:42 AM, Joe Perches wrote:
>> > It's declared after a pointer so it is already is 2 byte aligned.
>> > 
>> > A lot of drivers wouldn't work otherwise.
>> 
>> Maybe these drivers are only used on arches where this does not matter.
>
> Possible.
>
> I had only grepped through the sources looking for
> declarations using:
>
> $ git grep -B1 '\[ETH_ALEN\];' -- '*.c' | grep -A1 '\*'
>
> It's quite a few files in net/ too btw.
> 
> I still think adding __align(<even#>) is unnecessary here unless
> it follows something like a bool or a u8.

Um, guys, this is practically C-101.

From C99, 6.7.2.1:

> 13/ Within a structure object, the non-bit-field members and the units in
> which bit-fields reside have addresses that increase in the order in which
> they are declared. A pointer to a structure object, suitably converted,
> points to its initial member (or if that member is a bit-field, then to the
> unit in which it resides), and vice versa. There may be unnamed padding
> within a structure object, but not at its beginning.

AFAIK there is no such language in the spec regarding variable layout on
the stack. So Joe, you are totally off-base here.

-- Paul

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-06  2:27 [PATCH v2 2/2] r8169: Avoid pointer aliasing Paul Zimmerman
@ 2019-02-06  2:52 ` Joe Perches
  2019-02-06  3:25   ` Paul Zimmerman
  0 siblings, 1 reply; 16+ messages in thread
From: Joe Perches @ 2019-02-06  2:52 UTC (permalink / raw)
  To: Paul Zimmerman; +Cc: Eric Dumazet, Heiner Kallweit, David Miller, linux-kernel

On Tue, 2019-02-05 at 19:27 -0700, Paul Zimmerman wrote:
> On Tue, 2019-02-05, Joe Perches wrote:
> > On Tue, 2019-02-05 at 12:04 -0800, Eric Dumazet wrote:
> > > On 02/05/2019 10:42 AM, Joe Perches wrote:
> > > > It's declared after a pointer so it is already is 2 byte aligned.
> > > > 
> > > > A lot of drivers wouldn't work otherwise.
> > > 
> > > Maybe these drivers are only used on arches where this does not matter.
> > 
> > Possible.
> > 
> > I had only grepped through the sources looking for
> > declarations using:
> > 
> > $ git grep -B1 '\[ETH_ALEN\];' -- '*.c' | grep -A1 '\*'
> > 
> > It's quite a few files in net/ too btw.
> > 
> > I still think adding __align(<even#>) is unnecessary here unless
> > it follows something like a bool or a u8.
> 
> Um, guys, this is practically C-101.
> 
> From C99, 6.7.2.1:
> 
> > 13/ Within a structure object, the non-bit-field members and the units in
> > which bit-fields reside have addresses that increase in the order in which
> > they are declared. A pointer to a structure object, suitably converted,
> > points to its initial member (or if that member is a bit-field, then to the
> > unit in which it resides), and vice versa. There may be unnamed padding
> > within a structure object, but not at its beginning.
> 
> AFAIK there is no such language in the spec regarding variable layout on
> the stack. So Joe, you are totally off-base here.

We're not talking about the spec, see the void * arithmetic
bit, we're talking about what gcc and clang actually do.

This spec regarding variable layout structure members could
also apply to any of the unpacked protocol headers like in
include/uapi/linux/ip.h (struct iphdr for instance)

So, it's not me that's off here.
I do understand the c90 spec pretty well.

Eric's comment about stack layout randomization certainly applies.

Perhaps it's reasonable to add some __aligned(<even#>) to the
appropriate [ETH_ALEN] declarations.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-06  2:52 ` Joe Perches
@ 2019-02-06  3:25   ` Paul Zimmerman
  2019-02-06  3:49     ` Joe Perches
  0 siblings, 1 reply; 16+ messages in thread
From: Paul Zimmerman @ 2019-02-06  3:25 UTC (permalink / raw)
  To: Joe Perches
  Cc: Eric Dumazet, Heiner Kallweit, David Miller, linux-kernel, linux-netdev

On Tue, 05 Feb 2019 18:52:18 -0800, Joe Perches <joe@perches.com> wrote:
> On Tue, 2019-02-05 at 19:27 -0700, Paul Zimmerman wrote:
>> On Tue, 2019-02-05, Joe Perches wrote:
>>> On Tue, 2019-02-05 at 12:04 -0800, Eric Dumazet wrote:
>>> > On 02/05/2019 10:42 AM, Joe Perches wrote:
>>> > > It's declared after a pointer so it is already is 2 byte aligned.
>>> > > 
>>> > > A lot of drivers wouldn't work otherwise.
>>> > 
>>> > Maybe these drivers are only used on arches where this does not matter.
>>> 
>>> Possible.
>>> 
>>> I had only grepped through the sources looking for
>>> declarations using:
>>> 
>>> $ git grep -B1 '\[ETH_ALEN\];' -- '*.c' | grep -A1 '\*'
>>> 
>>> It's quite a few files in net/ too btw.
>>> 
>>> I still think adding __align(<even#>) is unnecessary here unless
>>> it follows something like a bool or a u8.
>> 
>> Um, guys, this is practically C-101.
>> 
>> From C99, 6.7.2.1:
>> 
>> > 13/ Within a structure object, the non-bit-field members and the units in
>> > which bit-fields reside have addresses that increase in the order in which
>> > they are declared. A pointer to a structure object, suitably converted,
>> > points to its initial member (or if that member is a bit-field, then to the
>> > unit in which it resides), and vice versa. There may be unnamed padding
>> > within a structure object, but not at its beginning.
>> 
>> AFAIK there is no such language in the spec regarding variable layout on
>> the stack. So Joe, you are totally off-base here.
> 
> We're not talking about the spec, see the void * arithmetic
> bit, we're talking about what gcc and clang actually do.

Sorry, I see I was a bit unclear. In an earlier message, which I neglected
to quote, you said:

> It's declared after a pointer so it is already is 2 byte aligned.
> A lot of drivers wouldn't work otherwise.

But it's declared after a pointer *on the stack* (local variable), not in
a structure. I was trying to say that there is nothing in the C spec that
says that local variables have any kind of ordering guarantee, unlike struct
members. And I have never seen any kernel code that relies on the ordering
of local variables to work correctly.

I used to work a lot with low-level C/assembly code, and I know for a fact
that GCC does not lay out stack variables in the same order that they are
declared.

-- Paul

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-06  3:25   ` Paul Zimmerman
@ 2019-02-06  3:49     ` Joe Perches
  0 siblings, 0 replies; 16+ messages in thread
From: Joe Perches @ 2019-02-06  3:49 UTC (permalink / raw)
  To: Paul Zimmerman
  Cc: Eric Dumazet, Heiner Kallweit, David Miller, linux-kernel, linux-netdev

On Tue, 2019-02-05 at 20:25 -0700, Paul Zimmerman wrote:
> GCC does not lay out stack variables in the same order that they are
> declared.

True. Most stack variables could be assigned to a register.

cheers, Joe



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-05 19:19         ` Joe Perches
@ 2019-02-06  7:25           ` Michal Kubecek
  0 siblings, 0 replies; 16+ messages in thread
From: Michal Kubecek @ 2019-02-06  7:25 UTC (permalink / raw)
  To: netdev
  Cc: Joe Perches, David Miller, thierry.reding, hkallweit1, andrew,
	nic_swsd, linux-kernel

On Tue, Feb 05, 2019 at 11:19:04AM -0800, Joe Perches wrote:
> On Tue, 2019-02-05 at 11:14 -0800, David Miller wrote:
> > From: Joe Perches <joe@perches.com>
> > Date: Tue, 05 Feb 2019 10:42:54 -0800
> > 
> > > On Mon, 2019-02-04 at 19:20 -0800, David Miller wrote:
> > >> From: Thierry Reding <thierry.reding@gmail.com>
> > >> Date: Mon,  4 Feb 2019 17:42:13 +0100
> > >> 
> > >> > @@ -7316,7 +7325,7 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp)
> > >> >  static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> > >> >  {
> > >> >       const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
> > >> > -     u8 mac_addr[ETH_ALEN] __aligned(4) = {};
> > >> > +     u8 mac_addr[ETH_ALEN] = {};
> > >> >       struct rtl8169_private *tp;
> > >> 
> > >> I agree with Heiner, you have to provide at least 2 byte alignment for this
> > >> buffer due to the reasons he stated.
> > > 
> > > It's declared after a pointer so it is already is 2 byte aligned.
> > > 
> > > A lot of drivers wouldn't work otherwise.
> > 
> > That's assuming a lot about what the compiler will do when nit allocates
> > local variables to the stack.
> 
> It's also assuming what a compiler will do when
> it defines a struct.

This is not a structure member, it's a local variable. I'm not aware of
any C norm requirement for ordering of local variables on the stack.
After all, some of them might not be on the stack at all and use only
registers or be optimized out completely.

Michal Kubecek

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-05 20:18         ` Joe Perches
  2019-02-05 20:23           ` Eric Dumazet
@ 2019-02-05 20:23           ` Heiner Kallweit
  1 sibling, 0 replies; 16+ messages in thread
From: Heiner Kallweit @ 2019-02-05 20:23 UTC (permalink / raw)
  To: Joe Perches, Eric Dumazet, David Miller, thierry.reding
  Cc: andrew, nic_swsd, netdev, linux-kernel

On 05.02.2019 21:18, Joe Perches wrote:
> On Tue, 2019-02-05 at 12:04 -0800, Eric Dumazet wrote:
>>
>> On 02/05/2019 10:42 AM, Joe Perches wrote:
>>> It's declared after a pointer so it is already is 2 byte aligned.
>>>
>>> A lot of drivers wouldn't work otherwise.
>>
>> Maybe these drivers are only used on arches where this does not matter.
> 
> Possible.
> 
> I had only grepped through the sources looking for
> declarations using:
> 
> $ git grep -B1 '\[ETH_ALEN\];' -- '*.c' | grep -A1 '\*'
> 
> It's quite a few files in net/ too btw.
> 
> I still think adding __align(<even#>) is unnecessary here unless
> it follows something like a bool or a u8.
> 
> 
I there's such a controversy, then it may be better to stay with
the current code, or?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-05 20:18         ` Joe Perches
@ 2019-02-05 20:23           ` Eric Dumazet
  2019-02-05 20:23           ` Heiner Kallweit
  1 sibling, 0 replies; 16+ messages in thread
From: Eric Dumazet @ 2019-02-05 20:23 UTC (permalink / raw)
  To: Joe Perches, David Miller, thierry.reding
  Cc: hkallweit1, andrew, nic_swsd, netdev, linux-kernel



On 02/05/2019 12:18 PM, Joe Perches wrote:

> I still think adding __align(<even#>) is unnecessary here unless
> it follows something like a bool or a u8.

This would be some historical side effect, and we do not want to rely on that.

A security feature could in fact ask a compiler to perform random
shuffling of automatic variables.

( a la __randomize_layout )



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-05 20:04       ` Eric Dumazet
@ 2019-02-05 20:18         ` Joe Perches
  2019-02-05 20:23           ` Eric Dumazet
  2019-02-05 20:23           ` Heiner Kallweit
  0 siblings, 2 replies; 16+ messages in thread
From: Joe Perches @ 2019-02-05 20:18 UTC (permalink / raw)
  To: Eric Dumazet, David Miller, thierry.reding
  Cc: hkallweit1, andrew, nic_swsd, netdev, linux-kernel

On Tue, 2019-02-05 at 12:04 -0800, Eric Dumazet wrote:
> 
> On 02/05/2019 10:42 AM, Joe Perches wrote:
> > It's declared after a pointer so it is already is 2 byte aligned.
> > 
> > A lot of drivers wouldn't work otherwise.
> 
> Maybe these drivers are only used on arches where this does not matter.

Possible.

I had only grepped through the sources looking for
declarations using:

$ git grep -B1 '\[ETH_ALEN\];' -- '*.c' | grep -A1 '\*'

It's quite a few files in net/ too btw.

I still think adding __align(<even#>) is unnecessary here unless
it follows something like a bool or a u8.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-05 18:42     ` Joe Perches
  2019-02-05 19:14       ` David Miller
@ 2019-02-05 20:04       ` Eric Dumazet
  2019-02-05 20:18         ` Joe Perches
  1 sibling, 1 reply; 16+ messages in thread
From: Eric Dumazet @ 2019-02-05 20:04 UTC (permalink / raw)
  To: Joe Perches, David Miller, thierry.reding
  Cc: hkallweit1, andrew, nic_swsd, netdev, linux-kernel



On 02/05/2019 10:42 AM, Joe Perches wrote:
> 
> It's declared after a pointer so it is already is 2 byte aligned.
> 
> A lot of drivers wouldn't work otherwise.

Maybe these drivers are only used on arches where this does not matter.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-05 19:14       ` David Miller
@ 2019-02-05 19:19         ` Joe Perches
  2019-02-06  7:25           ` Michal Kubecek
  0 siblings, 1 reply; 16+ messages in thread
From: Joe Perches @ 2019-02-05 19:19 UTC (permalink / raw)
  To: David Miller
  Cc: thierry.reding, hkallweit1, andrew, nic_swsd, netdev, linux-kernel

On Tue, 2019-02-05 at 11:14 -0800, David Miller wrote:
> From: Joe Perches <joe@perches.com>
> Date: Tue, 05 Feb 2019 10:42:54 -0800
> 
> > On Mon, 2019-02-04 at 19:20 -0800, David Miller wrote:
> >> From: Thierry Reding <thierry.reding@gmail.com>
> >> Date: Mon,  4 Feb 2019 17:42:13 +0100
> >> 
> >> > @@ -7316,7 +7325,7 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp)
> >> >  static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> >> >  {
> >> >       const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
> >> > -     u8 mac_addr[ETH_ALEN] __aligned(4) = {};
> >> > +     u8 mac_addr[ETH_ALEN] = {};
> >> >       struct rtl8169_private *tp;
> >> 
> >> I agree with Heiner, you have to provide at least 2 byte alignment for this
> >> buffer due to the reasons he stated.
> > 
> > It's declared after a pointer so it is already is 2 byte aligned.
> > 
> > A lot of drivers wouldn't work otherwise.
> 
> That's assuming a lot about what the compiler will do when nit allocates
> local variables to the stack.

It's also assuming what a compiler will do when
it defines a struct.

> I want it _explicit_.

Your choice, but there are a _lot_ of existing uses
and I think requiring it is as senseless as requiring
void * arithmetic to be cast to char * as gcc and
clang already do not add padding after a pointer.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-05 18:42     ` Joe Perches
@ 2019-02-05 19:14       ` David Miller
  2019-02-05 19:19         ` Joe Perches
  2019-02-05 20:04       ` Eric Dumazet
  1 sibling, 1 reply; 16+ messages in thread
From: David Miller @ 2019-02-05 19:14 UTC (permalink / raw)
  To: joe; +Cc: thierry.reding, hkallweit1, andrew, nic_swsd, netdev, linux-kernel

From: Joe Perches <joe@perches.com>
Date: Tue, 05 Feb 2019 10:42:54 -0800

> On Mon, 2019-02-04 at 19:20 -0800, David Miller wrote:
>> From: Thierry Reding <thierry.reding@gmail.com>
>> Date: Mon,  4 Feb 2019 17:42:13 +0100
>> 
>> > @@ -7316,7 +7325,7 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp)
>> >  static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>> >  {
>> >       const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
>> > -     u8 mac_addr[ETH_ALEN] __aligned(4) = {};
>> > +     u8 mac_addr[ETH_ALEN] = {};
>> >       struct rtl8169_private *tp;
>> 
>> I agree with Heiner, you have to provide at least 2 byte alignment for this
>> buffer due to the reasons he stated.
> 
> It's declared after a pointer so it is already is 2 byte aligned.
> 
> A lot of drivers wouldn't work otherwise.

That's assuming a lot about what the compiler will do when it allocates
local variables to the stack.

I want it _explicit_.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-05  3:20   ` David Miller
@ 2019-02-05 18:42     ` Joe Perches
  2019-02-05 19:14       ` David Miller
  2019-02-05 20:04       ` Eric Dumazet
  0 siblings, 2 replies; 16+ messages in thread
From: Joe Perches @ 2019-02-05 18:42 UTC (permalink / raw)
  To: David Miller, thierry.reding
  Cc: hkallweit1, andrew, nic_swsd, netdev, linux-kernel

On Mon, 2019-02-04 at 19:20 -0800, David Miller wrote:
> From: Thierry Reding <thierry.reding@gmail.com>
> Date: Mon,  4 Feb 2019 17:42:13 +0100
> 
> > @@ -7316,7 +7325,7 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp)
> >  static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> >  {
> >       const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
> > -     u8 mac_addr[ETH_ALEN] __aligned(4) = {};
> > +     u8 mac_addr[ETH_ALEN] = {};
> >       struct rtl8169_private *tp;
> 
> I agree with Heiner, you have to provide at least 2 byte alignment for this
> buffer due to the reasons he stated.

It's declared after a pointer so it is already is 2 byte aligned.

A lot of drivers wouldn't work otherwise.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-04 16:42 ` [PATCH v2 2/2] r8169: Avoid pointer aliasing Thierry Reding
  2019-02-04 16:59   ` Andrew Lunn
  2019-02-04 18:44   ` Heiner Kallweit
@ 2019-02-05  3:20   ` David Miller
  2019-02-05 18:42     ` Joe Perches
  2 siblings, 1 reply; 16+ messages in thread
From: David Miller @ 2019-02-05  3:20 UTC (permalink / raw)
  To: thierry.reding; +Cc: hkallweit1, andrew, nic_swsd, netdev, linux-kernel

From: Thierry Reding <thierry.reding@gmail.com>
Date: Mon,  4 Feb 2019 17:42:13 +0100

> @@ -7316,7 +7325,7 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp)
>  static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>  {
>  	const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
> -	u8 mac_addr[ETH_ALEN] __aligned(4) = {};
> +	u8 mac_addr[ETH_ALEN] = {};
>  	struct rtl8169_private *tp;

I agree with Heiner, you have to provide at least 2 byte alignment for this
buffer due to the reasons he stated.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-04 16:42 ` [PATCH v2 2/2] r8169: Avoid pointer aliasing Thierry Reding
  2019-02-04 16:59   ` Andrew Lunn
@ 2019-02-04 18:44   ` Heiner Kallweit
  2019-02-05  3:20   ` David Miller
  2 siblings, 0 replies; 16+ messages in thread
From: Heiner Kallweit @ 2019-02-04 18:44 UTC (permalink / raw)
  To: Thierry Reding, David S. Miller, Andrew Lunn
  Cc: Realtek linux nic maintainers, netdev, linux-kernel

On 04.02.2019 17:42, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> Read MAC address 32-bit at a time and manually extract the individual
> bytes. This avoids pointer aliasing and gives the compiler a better
> chance of optimizing the operation.
> 
> Suggested-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
> Applies to net-next.
> 
> I tested this on a Jetson TX2 with an add-in Realtek ethernet card that
> has a properly programmed OTP to verify that I got the endianess right.
> Seems like everything works and the device behaves the same with or
> without this patch.
> 
>  drivers/net/ethernet/realtek/r8169.c | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
> index 501891be7c56..192fbb36bc9f 100644
> --- a/drivers/net/ethernet/realtek/r8169.c
> +++ b/drivers/net/ethernet/realtek/r8169.c
> @@ -7113,12 +7113,21 @@ static int rtl_alloc_irq(struct rtl8169_private *tp)
>  static void rtl_read_mac_address(struct rtl8169_private *tp,
>  				 u8 mac_addr[ETH_ALEN])
>  {
> +	u32 value;
> +
>  	/* Get MAC address */
>  	switch (tp->mac_version) {
>  	case RTL_GIGA_MAC_VER_35 ... RTL_GIGA_MAC_VER_38:
>  	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
> -		*(u32 *)&mac_addr[0] = rtl_eri_read(tp, 0xe0, ERIAR_EXGMAC);
> -		*(u16 *)&mac_addr[4] = rtl_eri_read(tp, 0xe4, ERIAR_EXGMAC);
> +		value = rtl_eri_read(tp, 0xe0, ERIAR_EXGMAC);
> +		mac_addr[0] = (value >>  0) & 0xff;
> +		mac_addr[1] = (value >>  8) & 0xff;
> +		mac_addr[2] = (value >> 16) & 0xff;
> +		mac_addr[3] = (value >> 24) & 0xff;
> +
> +		value = rtl_eri_read(tp, 0xe4, ERIAR_EXGMAC);
> +		mac_addr[4] = (value >>  0) & 0xff;
> +		mac_addr[5] = (value >>  8) & 0xff;
>  		break;
>  	default:
>  		break;
> @@ -7316,7 +7325,7 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp)
>  static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>  {
>  	const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
> -	u8 mac_addr[ETH_ALEN] __aligned(4) = {};
> +	u8 mac_addr[ETH_ALEN] = {};
>  	struct rtl8169_private *tp;
>  	struct net_device *dev;
>  	int chipset, region, i;
> 
I just have one concern / question:

After this there's a call to is_valid_ether_addr(mac_addr) and kernel-doc of
is_valid_ether_addr() states that argument must be u16-aligned.
AFAIK that's not guaranteed for a byte array.

Heiner

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-04 16:42 ` [PATCH v2 2/2] r8169: Avoid pointer aliasing Thierry Reding
@ 2019-02-04 16:59   ` Andrew Lunn
  2019-02-04 18:44   ` Heiner Kallweit
  2019-02-05  3:20   ` David Miller
  2 siblings, 0 replies; 16+ messages in thread
From: Andrew Lunn @ 2019-02-04 16:59 UTC (permalink / raw)
  To: Thierry Reding
  Cc: David S. Miller, Heiner Kallweit, Realtek linux nic maintainers,
	netdev, linux-kernel

On Mon, Feb 04, 2019 at 05:42:13PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> Read MAC address 32-bit at a time and manually extract the individual
> bytes. This avoids pointer aliasing and gives the compiler a better
> chance of optimizing the operation.
> 
> Suggested-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Thierry Reding <treding@nvidia.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 2/2] r8169: Avoid pointer aliasing
  2019-02-04 16:42 [PATCH v2 1/2] r8169: Load MAC address from device tree if present Thierry Reding
@ 2019-02-04 16:42 ` Thierry Reding
  2019-02-04 16:59   ` Andrew Lunn
                     ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Thierry Reding @ 2019-02-04 16:42 UTC (permalink / raw)
  To: David S. Miller
  Cc: Heiner Kallweit, Andrew Lunn, Realtek linux nic maintainers,
	netdev, linux-kernel

From: Thierry Reding <treding@nvidia.com>

Read MAC address 32-bit at a time and manually extract the individual
bytes. This avoids pointer aliasing and gives the compiler a better
chance of optimizing the operation.

Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Applies to net-next.

I tested this on a Jetson TX2 with an add-in Realtek ethernet card that
has a properly programmed OTP to verify that I got the endianess right.
Seems like everything works and the device behaves the same with or
without this patch.

 drivers/net/ethernet/realtek/r8169.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 501891be7c56..192fbb36bc9f 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -7113,12 +7113,21 @@ static int rtl_alloc_irq(struct rtl8169_private *tp)
 static void rtl_read_mac_address(struct rtl8169_private *tp,
 				 u8 mac_addr[ETH_ALEN])
 {
+	u32 value;
+
 	/* Get MAC address */
 	switch (tp->mac_version) {
 	case RTL_GIGA_MAC_VER_35 ... RTL_GIGA_MAC_VER_38:
 	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
-		*(u32 *)&mac_addr[0] = rtl_eri_read(tp, 0xe0, ERIAR_EXGMAC);
-		*(u16 *)&mac_addr[4] = rtl_eri_read(tp, 0xe4, ERIAR_EXGMAC);
+		value = rtl_eri_read(tp, 0xe0, ERIAR_EXGMAC);
+		mac_addr[0] = (value >>  0) & 0xff;
+		mac_addr[1] = (value >>  8) & 0xff;
+		mac_addr[2] = (value >> 16) & 0xff;
+		mac_addr[3] = (value >> 24) & 0xff;
+
+		value = rtl_eri_read(tp, 0xe4, ERIAR_EXGMAC);
+		mac_addr[4] = (value >>  0) & 0xff;
+		mac_addr[5] = (value >>  8) & 0xff;
 		break;
 	default:
 		break;
@@ -7316,7 +7325,7 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp)
 static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
-	u8 mac_addr[ETH_ALEN] __aligned(4) = {};
+	u8 mac_addr[ETH_ALEN] = {};
 	struct rtl8169_private *tp;
 	struct net_device *dev;
 	int chipset, region, i;
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2019-02-06  7:25 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-06  2:27 [PATCH v2 2/2] r8169: Avoid pointer aliasing Paul Zimmerman
2019-02-06  2:52 ` Joe Perches
2019-02-06  3:25   ` Paul Zimmerman
2019-02-06  3:49     ` Joe Perches
  -- strict thread matches above, loose matches on Subject: below --
2019-02-04 16:42 [PATCH v2 1/2] r8169: Load MAC address from device tree if present Thierry Reding
2019-02-04 16:42 ` [PATCH v2 2/2] r8169: Avoid pointer aliasing Thierry Reding
2019-02-04 16:59   ` Andrew Lunn
2019-02-04 18:44   ` Heiner Kallweit
2019-02-05  3:20   ` David Miller
2019-02-05 18:42     ` Joe Perches
2019-02-05 19:14       ` David Miller
2019-02-05 19:19         ` Joe Perches
2019-02-06  7:25           ` Michal Kubecek
2019-02-05 20:04       ` Eric Dumazet
2019-02-05 20:18         ` Joe Perches
2019-02-05 20:23           ` Eric Dumazet
2019-02-05 20:23           ` Heiner Kallweit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).