From owner-freebsd-hackers@FreeBSD.ORG Wed Aug 22 02:55:55 2012 Return-Path: Delivered-To: freebsd-hackers@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 05D571065674; Wed, 22 Aug 2012 02:55:55 +0000 (UTC) (envelope-from bde@FreeBSD.org) Received: from ref10-i386.freebsd.org (unknown [IPv6:2001:4f8:fff6::5e]) by mx1.freebsd.org (Postfix) with ESMTP id 9879C8FC0C; Wed, 22 Aug 2012 02:55:54 +0000 (UTC) Received: from ref10-i386.freebsd.org (localhost [127.0.0.1]) by ref10-i386.freebsd.org (8.14.5/8.14.5) with ESMTP id q7M2tsAZ020281; Wed, 22 Aug 2012 02:55:54 GMT (envelope-from bde@ref10-i386.freebsd.org) Received: (from bde@localhost) by ref10-i386.freebsd.org (8.14.5/8.14.5/Submit) id q7M2tsxa020280; Wed, 22 Aug 2012 02:55:54 GMT (envelope-from bde) Date: Wed, 22 Aug 2012 02:55:54 GMT From: Bruce Evans Message-Id: <201208220255.q7M2tsxa020280@ref10-i386.freebsd.org> To: freebsd-hackers@FreeBSD.org, jhb@FreeBSD.org In-Reply-To: <201208210943.08341.jhb@freebsd.org> Cc: freebsd-net@FreeBSD.org, mitya@cabletv.dp.ua Subject: Re: Replace bcopy() to update ether_addr X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Aug 2012 02:55:55 -0000 jhb wrote: > On Monday, August 20, 2012 10:46:12 am Mitya wrote: > > ... > > I propose this solution. > > > > In file /usr/src/include/net/ethernet.h add this lines: > > > > static inline void ether_addr_copy(ether_addr* src, ether_addr* dst) { > > #if defined(__i386__) || defined(__amd64__) > > *dst = *src; > > #else > > bcopy(src, dst, ETHER_ADDR_LEN); > > #endif > > } > > Doesn't '*dst = *src' just work on all platforms? It does when you have an actual struct, but often in networking code you only have an array of bytes, and then casting the pointers from uint8_t * to full object pointers fails iff there is an alignment problem. Even on i386, it may be pessimal to use struct copying for 6 bytes, The bytes should be copied as 4+2 or 2+4 depending on alignment of the first bytes. Oops, not even that -- this reminds me of a problem with penalties for mismatched loads and stores which affects at least AthlonXP and Athlon64 significantly (10-20 cycle penalty = enough to copy 80-160 bytes unpenalized). The 6 should probably be copied as 2+2+2 or even as 1+1+1+1+1+1 to match previous stores and later loads, also as 2+2+2, etc. But if the 6 are part of another struct, they might be accessed as 8+0 or 4+4 as part of copying the full struct. gcc is not smart about this. Bruce