etherdevice: Use ether_addr_copy to copy an Ethernet address
Subsystems (5)
RFC PATCH 1/1 etherdevice: Use ether_addr_copy to copy an Ethernet address
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.
---
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 memcpyarm 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(-)
include/linux/etherdevice.h +23 -1
@@ -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); }/**
David Miller
maintainerFrom: Joe Perches <[email protected]>
Date: Tue, 14 Jan 2014 15:18:47 -0800
Quoted 6 lines
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 <[email protected]>
This looks fine, in fact I'll apply it.
Quoted 11 lines · David Miller
From: Joe Perches <[email protected]>
Date: Tue, 14 Jan 2014 15:18:47 -0800Quoted 6 lines
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 <[email protected]>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(-)
David Miller
maintainerFrom: Joe Perches <[email protected]>
Date: Wed, 15 Jan 2014 16:07:58 -0800
Quoted 5 lines
If you want the ones for net-next
net/now (but not for batman-adv, that maybe could use a new function likeether_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.
cover net: Convert aligned memcpy to ether_addr_copy
On Wed, 2014-01-15 at 16:45 -0800, David Miller wrote:
From: Joe Perches <[email protected]>
Quoted 10 lines
Date: Wed, 15 Jan 2014 16:07:58 -0800
Quoted 5 lines
If you want the ones for net-next
net/now (but not for batman-adv, that maybe could use a new function likeether_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(-)
Signature · 1 line
1.8.1.2.459.gbcd45b4.dirty
PATCH 1/7 8021q: Use ether_addr_copy
Use ether_addr_copy instead of memcpy(a, b, ETH_ALEN) to save some cycles on arm and powerpc.
--- net/8021q/vlan.c | 2 +- net/8021q/vlan_dev.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
net/8021q/vlan.c +1 -1
@@ -301,7 +301,7 @@ static void vlan_sync_address(struct net_device *dev, !ether_addr_equal(vlandev->dev_addr, dev->dev_addr))dev_uc_add (dev, vlandev->dev_addr); -memcpy (vlan->real_dev_addr, dev->dev_addr,ETH_ALEN ); +ether_addr_copy (vlan->real_dev_addr, dev->dev_addr); } static void vlan_transfer_features(struct net_device *dev,
net/8021q/vlan_dev.c +3 -3
@@ -61,7 +61,7 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb)pr_debug ("%s: unable to resolve type %X addresses\n" , dev->name,ntohs (veth->h_vlan_encapsulated_proto)); -memcpy (veth->h_source, dev->dev_addr,ETH_ALEN ); +ether_addr_copy (veth->h_source, dev->dev_addr);break ; }
@@ -303,7 +303,7 @@ static int vlan_dev_open(struct net_device *dev) goto clear_allmulti; } -memcpy (vlan->real_dev_addr, real_dev->dev_addr,ETH_ALEN ); +ether_addr_copy (vlan->real_dev_addr, real_dev->dev_addr);if (vlan->flags &VLAN_FLAG_GVRP )vlan_gvrp_request_join (dev);
@@ -367,7 +367,7 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p)dev_uc_del (real_dev, dev->dev_addr); out: -memcpy (dev->dev_addr, addr->sa_data,ETH_ALEN ); +ether_addr_copy (dev->dev_addr, addr->sa_data);return 0 ; }
Signature · 1 line
1.8.1.2.459.gbcd45b4.dirty
David Miller
maintainerRe: [PATCH 1/7] 8021q: Use ether_addr_copy
All 7 patches applied, thanks Joe.
PATCH 2/7 appletalk: Use ether_addr_copy
In reply to Joe PerchesUse ether_addr_copy instead of memcpy(a, b, ETH_ALEN) to save some cycles on arm and powerpc.
Convert struct aarp_entry.hwaddr[6] to hwaddr[ETH_ALEN].
--- net/appletalk/aarp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
net/appletalk/aarp.c +6 -6
@@ -67,7 +67,7 @@ struct aarp_entry {unsigned long expires_at;struct atalk_addr target_addr;struct net_device *dev; -char hwaddr[6 ]; +char hwaddr[ETH_ALEN ];unsigned short xmit_count;struct aarp_entry *next; };
@@ -134,7 +134,7 @@ static void __aarp_send_query(struct aarp_entry *a) eah->pa_len =AARP_PA_ALEN ; eah->function =htons (AARP_REQUEST ); -memcpy (eah->hw_src, dev->dev_addr,ETH_ALEN ); +ether_addr_copy (eah->hw_src, dev->dev_addr); eah->pa_src_zero =0 ; eah->pa_src_net = sat->s_net;
@@ -181,7 +181,7 @@ static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us, eah->pa_len =AARP_PA_ALEN ; eah->function =htons (AARP_REPLY ); -memcpy (eah->hw_src, dev->dev_addr,ETH_ALEN ); +ether_addr_copy (eah->hw_src, dev->dev_addr); eah->pa_src_zero =0 ; eah->pa_src_net = us->s_net;
@@ -190,7 +190,7 @@ static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us,if (!sha)memset (eah->hw_dst,'\0' ,ETH_ALEN );else -memcpy (eah->hw_dst, sha,ETH_ALEN ); +ether_addr_copy (eah->hw_dst, sha); eah->pa_dst_zero =0 ; eah->pa_dst_net = them->s_net;
@@ -232,7 +232,7 @@ static void aarp_send_probe(struct net_device *dev, struct atalk_addr *us) eah->pa_len =AARP_PA_ALEN ; eah->function =htons (AARP_PROBE ); -memcpy (eah->hw_src, dev->dev_addr,ETH_ALEN ); +ether_addr_copy (eah->hw_src, dev->dev_addr); eah->pa_src_zero =0 ; eah->pa_src_net = us->s_net;
@@ -790,7 +790,7 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,break ;/* We can fill one in - this is good. */ -memcpy (a->hwaddr, ea->hw_src,ETH_ALEN ); +ether_addr_copy (a->hwaddr, ea->hw_src);__aarp_resolved (&unresolved[hash], a, hash);if (!unresolved_count) mod_timer(&aarp_timer,
Signature · 1 line
1.8.1.2.459.gbcd45b4.dirty
PATCH 3/7 atm: Use ether_addr_copy
In reply to Joe PerchesUse ether_addr_copy instead of memcpy(a, b, ETH_ALEN) to save some cycles on arm and powerpc.
--- net/atm/lec.c | 9 +++++---- net/atm/mpc.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-)
net/atm/lec.c +5 -4
@@ -521,7 +521,7 @@ send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,if (data !=NULL ) mesg->sizeoftlvs = data->len;if (mac_addr) -memcpy (&mesg->content.normal.mac_addr, mac_addr,ETH_ALEN ); +ether_addr_copy (&mesg->content.normal.mac_addr, mac_addr);else mesg->content.normal.targetless_le_arp =1 ;if (atm_addr)
@@ -1565,7 +1565,7 @@ static struct lec_arp_table *make_entry(struct lec_priv *priv,pr_info ("LEC: Arp entry kmalloc failed\n" );return NULL ; } -memcpy (to_return->mac_addr, mac_addr,ETH_ALEN ); +ether_addr_copy (to_return->mac_addr, mac_addr);INIT_HLIST_NODE (&to_return->next);setup_timer (&to_return->timer, lec_arp_expire_arp, (unsigned long )to_return);
@@ -1887,7 +1887,8 @@ lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr, entry = tmp; }else { entry->status =ESI_FORWARD_DIRECT ; -memcpy (entry->mac_addr, mac_addr,ETH_ALEN ); +ether_addr_copy (entry->mac_addr, + mac_addr); entry->last_used = jiffies;lec_arp_add (priv, entry); }
@@ -2263,7 +2264,7 @@ lec_arp_check_empties(struct lec_priv *priv, &priv->lec_arp_empty_ones, next) {if (vcc == entry->vcc) {del_timer (&entry->timer); -memcpy (entry->mac_addr, src,ETH_ALEN ); +ether_addr_copy (entry->mac_addr, src); entry->status =ESI_FORWARD_DIRECT ; entry->last_used = jiffies;/* We might have got an entry */
net/atm/mpc.c +1 -1
@@ -478,7 +478,7 @@ static const uint8_t *copy_macs(struct mpoa_client *mpc,return NULL ; } } -memcpy (mpc->mps_macs, router_mac,ETH_ALEN ); +ether_addr_copy (mpc->mps_macs, router_mac); tlvs +=20 ;if (device_type ==MPS_AND_MPC ) tlvs +=20 ;if (mps_macs >0 )memcpy (mpc->mps_macs, tlvs, mps_macs*ETH_ALEN );
Signature · 1 line
1.8.1.2.459.gbcd45b4.dirty
PATCH 4/7 caif_usb: Use ether_addr_copy
In reply to Joe PerchesUse ether_addr_copy instead of memcpy(a, b, ETH_ALEN) to save some cycles on arm and powerpc.
--- net/caif/caif_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/caif/caif_usb.c +2 -2
@@ -105,8 +105,8 @@ static struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN],* 5-11 source address * 12-13 protocol type */ -memcpy (&this->tx_eth_hdr[ETH_ALEN ], braddr,ETH_ALEN ); -memcpy (&this->tx_eth_hdr[ETH_ALEN ], ethaddr,ETH_ALEN ); +ether_addr_copy (&this->tx_eth_hdr[ETH_ALEN ], braddr); +ether_addr_copy (&this->tx_eth_hdr[ETH_ALEN ], ethaddr); this->tx_eth_hdr[12 ] =cpu_to_be16 (ETH_P_802_EX1 ) &0xff ; this->tx_eth_hdr[13 ] = (cpu_to_be16 (ETH_P_802_EX1 ) >>8 ) &0xff ; pr_debug("caif ethernet TX-header dst:%pM src:%pM type:%02x%02x\n",
Signature · 1 line
1.8.1.2.459.gbcd45b4.dirty
PATCH 5/7 netpoll: Use ether_addr_copy
In reply to Joe PerchesUse ether_addr_copy instead of memcpy(a, b, ETH_ALEN) to save some cycles on arm and powerpc.
--- net/core/netpoll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/core/netpoll.c +2 -2
@@ -520,8 +520,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) skb->protocol = eth->h_proto =htons (ETH_P_IP ); } -memcpy (eth->h_source, np->dev->dev_addr,ETH_ALEN ); -memcpy (eth->h_dest, np->remote_mac,ETH_ALEN ); +ether_addr_copy (eth->h_source, np->dev->dev_addr); +ether_addr_copy (eth->h_dest, np->remote_mac); skb->dev = np->dev;
Signature · 1 line
1.8.1.2.459.gbcd45b4.dirty
PATCH 6/7 pktgen: Use ether_addr_copy
In reply to Joe PerchesUse ether_addr_copy instead of memcpy(a, b, ETH_ALEN) to save some cycles on arm and powerpc.
--- net/core/pktgen.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/core/pktgen.c +4 -4
@@ -1440,7 +1440,7 @@ static ssize_t pktgen_if_write(struct file *file,if (!mac_pton (valstr, pkt_dev->dst_mac))return -EINVAL ;/* Set up Dest MAC */ -memcpy (&pkt_dev->hh[0 ], pkt_dev->dst_mac,ETH_ALEN ); +ether_addr_copy (&pkt_dev->hh[0 ], pkt_dev->dst_mac);sprintf (pg_result,"OK: dstmac %pM" , pkt_dev->dst_mac);return count;
@@ -1457,7 +1457,7 @@ static ssize_t pktgen_if_write(struct file *file,if (!mac_pton (valstr, pkt_dev->src_mac))return -EINVAL ;/* Set up Src MAC */ -memcpy (&pkt_dev->hh[6 ], pkt_dev->src_mac,ETH_ALEN ); +ether_addr_copy (&pkt_dev->hh[6 ], pkt_dev->src_mac);sprintf (pg_result,"OK: srcmac %pM" , pkt_dev->src_mac);return count;
@@ -2060,10 +2060,10 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)/* Default to the interface's mac if not explicitly set. */ if (is_zero_ether_addr (pkt_dev->src_mac)) -memcpy (&(pkt_dev->hh[6 ]), pkt_dev->odev->dev_addr,ETH_ALEN ); +ether_addr_copy (&(pkt_dev->hh[6 ]), pkt_dev->odev->dev_addr);/* Set up Dest MAC */ -memcpy (&(pkt_dev->hh[0 ]), pkt_dev->dst_mac,ETH_ALEN ); +ether_addr_copy (&(pkt_dev->hh[0 ]), pkt_dev->dst_mac);if (pkt_dev->flags &F_IPV6 ) {int i, set =0 , err =1 ;
Signature · 1 line
1.8.1.2.459.gbcd45b4.dirty
PATCH 7/7 dsa: Use ether_addr_copy
In reply to Joe PerchesUse ether_addr_copy instead of memcpy(a, b, ETH_ALEN) to save some cycles on arm and powerpc.
--- net/dsa/slave.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/dsa/slave.c +1 -1
@@ -156,7 +156,7 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a)dev_uc_del (master, dev->dev_addr); out: -memcpy (dev->dev_addr, addr->sa_data,ETH_ALEN ); +ether_addr_copy (dev->dev_addr, addr->sa_data);return 0 ; }
Signature · 1 line
1.8.1.2.459.gbcd45b4.dirty