diff mbox

[RFC,net-next] etherdevice: Use ether_addr_copy to copy an Ethernet address

Message ID 1389741527.24849.68.camel@joe-AO722
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Joe Perches Jan. 14, 2014, 11:18 p.m. UTC
Some systems can use the normally known u16 alignment of
Ethernet addresses to save some code/text bytes and cycles.

This does not change currently emitted code on x86 by gcc 4.8.

Signed-off-by: Joe Perches <joe@perches.com>
---

Yes, it's a trivial change, but maybe slightly useful...

For instance: with netpoll.c memcpy changed to ether_addr_copy:

arm old (4.6.3):
	memcpy(eth->h_source, np->dev->dev_addr, ETH_ALEN);
    27e0:	e4973042 	ldr	r3, [r7], #66	; 0x42
    27e4:	e2860006 	add	r0, r6, #6
    27e8:	e3a02006 	mov	r2, #6
    27ec:	e59311e8 	ldr	r1, [r3, #488]	; 0x1e8
    27f0:	ebfffffe 	bl	0 <memcpy>
			27f0: R_ARM_CALL	memcpy
	memcpy(eth->h_dest, np->remote_mac, ETH_ALEN);
    27f4:	e1a00006 	mov	r0, r6
    27f8:	e1a01007 	mov	r1, r7
    27fc:	e3a02006 	mov	r2, #6
    2800:	ebfffffe 	bl	0 <memcpy>
			2800: R_ARM_CALL	memcpy

arm new:

	*(u32 *)dst = *(const u32 *)src;
    27dc:	e5932000 	ldr	r2, [r3]
    27e0:	e5802006 	str	r2, [r0, #6]
	*(u16 *)(dst + 4) = *(const u16 *)(src + 4);
    27e4:	e1d330b4 	ldrh	r3, [r3, #4]
    27e8:	e1c030ba 	strh	r3, [r0, #10]
 * Please note: dst & src must both be aligned to u16.
 */
static inline void ether_addr_copy(u8 *dst, const u8 *src)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
	*(u32 *)dst = *(const u32 *)src;
    27ec:	e5953042 	ldr	r3, [r5, #66]	; 0x42
    27f0:	e5803000 	str	r3, [r0]
	*(u16 *)(dst + 4) = *(const u16 *)(src + 4);
    27f4:	e1d534b6 	ldrh	r3, [r5, #70]	; 0x46
    27f8:	e1c030b4 	strh	r3, [r0, #4]

 include/linux/etherdevice.h | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)



--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

David Miller Jan. 15, 2014, 11:39 p.m. UTC | #1
From: Joe Perches <joe@perches.com>
Date: Tue, 14 Jan 2014 15:18:47 -0800

> Some systems can use the normally known u16 alignment of
> Ethernet addresses to save some code/text bytes and cycles.
> 
> This does not change currently emitted code on x86 by gcc 4.8.
> 
> Signed-off-by: Joe Perches <joe@perches.com>

This looks fine, in fact I'll apply it.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Joe Perches Jan. 16, 2014, 12:07 a.m. UTC | #2
On Wed, 2014-01-15 at 15:39 -0800, David Miller wrote:
> From: Joe Perches <joe@perches.com>
> Date: Tue, 14 Jan 2014 15:18:47 -0800
> 
> > Some systems can use the normally known u16 alignment of
> > Ethernet addresses to save some code/text bytes and cycles.
> > 
> > This does not change currently emitted code on x86 by gcc 4.8.
> > 
> > Signed-off-by: Joe Perches <joe@perches.com>
> 
> This looks fine, in fact I'll apply it.

OK, good.

There are a couple thousand memcpy(foo, bar, ETH_ALEN)
in the kernel tree that could be converted.

Some will have a small performance improvement for
arm and powerpc.

If you want the ones for net-next net/ now (but not
for batman-adv, that maybe could use a new function like
ether_addr_copy_unaligned) here's a changestat.

Otherwise, I'll wait for the next cycle.

(done via coccinelle)

 net/8021q/vlan.c                          |  2 +-
 net/8021q/vlan_dev.c                      |  6 ++--
 net/appletalk/aarp.c                      | 10 +++---
 net/atm/lec.c                             |  9 ++---
 net/atm/mpc.c                             |  2 +-
 net/bluetooth/bnep/core.c                 | 19 +++++-----
 net/bluetooth/bnep/netdev.c               | 14 ++++----
 net/bridge/br_device.c                    |  4 +--
 net/bridge/br_fdb.c                       |  4 +--
 net/bridge/br_multicast.c                 |  4 +--
 net/bridge/br_netfilter.c                 |  2 +-
 net/bridge/br_stp_if.c                    | 10 +++---
 net/bridge/netfilter/ebt_among.c          |  2 +-
 net/bridge/netfilter/ebt_dnat.c           |  2 +-
 net/bridge/netfilter/ebt_redirect.c       |  6 ++--
 net/bridge/netfilter/ebt_snat.c           |  2 +-
 net/caif/caif_usb.c                       |  4 +--
 net/core/netpoll.c                        |  4 +--
 net/core/pktgen.c                         |  8 ++---
 net/decnet/dn_dev.c                       |  2 +-
 net/decnet/dn_neigh.c                     |  6 ++--
 net/decnet/dn_route.c                     |  6 ++--
 net/dsa/slave.c                           |  2 +-
 net/ethernet/eth.c                        | 18 +++++-----
 net/hsr/hsr_device.c                      |  8 ++---
 net/hsr/hsr_framereg.c                    | 21 +++++------
 net/hsr/hsr_main.c                        |  4 +--
 net/ipv4/netfilter/ipt_CLUSTERIP.c        |  2 +-
 net/mac80211/agg-rx.c                     | 10 +++---
 net/mac80211/agg-tx.c                     | 18 +++++-----
 net/mac80211/cfg.c                        | 34 +++++++++---------
 net/mac80211/debugfs_netdev.c             | 12 +++----
 net/mac80211/ht.c                         | 16 ++++-----
 net/mac80211/ibss.c                       | 14 ++++----
 net/mac80211/iface.c                      | 27 +++++++-------
 net/mac80211/mesh.c                       | 30 ++++++++--------
 net/mac80211/mesh_hwmp.c                  | 32 ++++++++---------
 net/mac80211/mesh_pathtbl.c               | 20 +++++------
 net/mac80211/mesh_plink.c                 |  6 ++--
 net/mac80211/mesh_ps.c                    |  2 +-
 net/mac80211/mlme.c                       | 32 ++++++++---------
 net/mac80211/rx.c                         | 14 ++++----
 net/mac80211/spectmgmt.c                  |  6 ++--
 net/mac80211/sta_info.c                   |  8 ++---
 net/mac80211/tx.c                         | 60 +++++++++++++++----------------
 net/mac80211/util.c                       | 22 ++++++------
 net/mac80211/wpa.c                        |  4 +--
 net/netfilter/ipset/ip_set_bitmap_ipmac.c |  6 ++--
 net/openvswitch/actions.c                 |  4 +--
 net/openvswitch/flow.c                    | 16 ++++-----
 net/openvswitch/flow_netlink.c            | 14 ++++----
 net/tipc/eth_media.c                      |  2 +-
 net/wireless/core.c                       |  2 +-
 net/wireless/ibss.c                       | 11 +++---
 net/wireless/lib80211_crypt_ccmp.c        |  4 +--
 net/wireless/lib80211_crypt_tkip.c        | 18 +++++-----
 net/wireless/mlme.c                       |  2 +-
 net/wireless/nl80211.c                    |  6 ++--
 net/wireless/scan.c                       |  6 ++--
 net/wireless/sme.c                        | 18 +++++-----
 net/wireless/util.c                       | 42 +++++++++++-----------
 net/wireless/wext-compat.c                |  8 ++---
 net/wireless/wext-sme.c                   |  5 +--
 net/wireless/wext-spy.c                   |  8 ++---
 64 files changed, 365 insertions(+), 357 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller Jan. 16, 2014, 12:45 a.m. UTC | #3
From: Joe Perches <joe@perches.com>
Date: Wed, 15 Jan 2014 16:07:58 -0800

> If you want the ones for net-next net/ now (but not
> for batman-adv, that maybe could use a new function like
> ether_addr_copy_unaligned) here's a changestat.
> 
> Otherwise, I'll wait for the next cycle.

This looks fine, why don't you toss it my way over the weekend as I
still have some backlog to process at the moment?

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Joe Perches Jan. 20, 2014, 5:52 p.m. UTC | #4
On Wed, 2014-01-15 at 16:45 -0800, David Miller wrote:
From: Joe Perches <joe@perches.com>
> Date: Wed, 15 Jan 2014 16:07:58 -0800
> 
> > If you want the ones for net-next net/ now (but not
> > for batman-adv, that maybe could use a new function like
> > ether_addr_copy_unaligned) here's a changestat.
> > 
> > Otherwise, I'll wait for the next cycle.
> 
> This looks fine, why don't you toss it my way over the weekend as I
> still have some backlog to process at the moment?
 
I didn't get that done this weekend, so next cycle
for most of net/.

I don't want to introduce any breakage this late and
there are possible unaligned memcpy(foo, bar, ETH_ALEN)
where one or both of foo/bar are stack pointers where
the alignment is hard to verify.

There are also statics declared without __aligned(2)
that will need updating.

Maybe ether_addr_copy_unaligned should be added too.

Here are the ones I could easily verify...
No worries if it's this cycle or next.

Joe Perches (7):
  8021q: Use ether_addr_copy
  appletalk: Use ether_addr_copy
  atm: Use ether_addr_copy
  caif_usb: Use ether_addr_copy
  netpoll: Use ether_addr_copy
  pktgen: Use ether_addr_copy
  dsa: Use ether_addr_copy

 net/8021q/vlan.c     |  2 +-
 net/8021q/vlan_dev.c |  6 +++---
 net/appletalk/aarp.c | 12 ++++++------
 net/atm/lec.c        |  9 +++++----
 net/atm/mpc.c        |  2 +-
 net/caif/caif_usb.c  |  4 ++--
 net/core/netpoll.c   |  4 ++--
 net/core/pktgen.c    |  8 ++++----
 net/dsa/slave.c      |  2 +-
 9 files changed, 25 insertions(+), 24 deletions(-)
diff mbox

Patch

diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index f344ac0..1f26c55 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -218,6 +218,28 @@  static inline void eth_hw_addr_random(struct net_device *dev)
 }
 
 /**
+ * ether_addr_copy - Copy an Ethernet address
+ * @dst: Pointer to a six-byte array Ethernet address destination
+ * @src: Pointer to a six-byte array Ethernet address source
+ *
+ * Please note: dst & src must both be aligned to u16.
+ */
+static inline void ether_addr_copy(u8 *dst, const u8 *src)
+{
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+	*(u32 *)dst = *(const u32 *)src;
+	*(u16 *)(dst + 4) = *(const u16 *)(src + 4);
+#else
+	u16 *a = (u16 *)dst;
+	const u16 *b = (const u16 *)src;
+
+	a[0] = b[0];
+	a[1] = b[1];
+	a[2] = b[2];
+#endif
+}
+
+/**
  * eth_hw_addr_inherit - Copy dev_addr from another net_device
  * @dst: pointer to net_device to copy dev_addr to
  * @src: pointer to net_device to copy dev_addr from
@@ -229,7 +251,7 @@  static inline void eth_hw_addr_inherit(struct net_device *dst,
 				       struct net_device *src)
 {
 	dst->addr_assign_type = src->addr_assign_type;
-	memcpy(dst->dev_addr, src->dev_addr, ETH_ALEN);
+	ether_addr_copy(dst->dev_addr, src->dev_addr);
 }
 
 /**