From nobody@FreeBSD.org  Fri Oct  8 12:26:38 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 66654106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Fri,  8 Oct 2010 12:26:38 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 3A7578FC16
	for <freebsd-gnats-submit@FreeBSD.org>; Fri,  8 Oct 2010 12:26:38 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o98CQbCn024223
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 8 Oct 2010 12:26:37 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o98CQbBI024222;
	Fri, 8 Oct 2010 12:26:37 GMT
	(envelope-from nobody)
Message-Id: <201010081226.o98CQbBI024222@www.freebsd.org>
Date: Fri, 8 Oct 2010 12:26:37 GMT
From: Svatopluk Kraus <onwahe@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: patch - definitions of variables tested by ASSERT_ATOMIC_LOAD_PTR
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         151304
>Category:       kern
>Synopsis:       [patch] definitions of variables tested by ASSERT_ATOMIC_LOAD_PTR
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Oct 08 12:30:01 UTC 2010
>Closed-Date:    Fri Oct 22 09:52:03 UTC 2010
>Last-Modified:  Fri Oct 22 09:52:03 UTC 2010
>Originator:     Svatopluk Kraus
>Release:        current
>Organization:
>Environment:
coldfire port
>Description:
A macro ASSERT_ATOMIC_LOAD_PTR() hits in colfire port I work on. It is possibly due to use of GNU GCC (4.5.1) compiler -Os option (size optimalization). The macro is applied on four places:

sys/kern/kern_lock.c
sys/kern/kern_mutex.c
sys/kern/kern_rwlock.c
sys/kern/kern_sx.c

and tests entries in four structures:

volatile uintptr_t lk_lock -> struct lock -> sys/sys/_lockmgr.h
volatile uintptr_t mtx_lock -> struct mtx -> sys/sys/_mutex.h
volatile uintptr_t rw_lock -> struct rwlock -> sys/sys/_rwlock.h
volatile uintptr_t sx_lock -> struct sx -> sys/sys/_sx.h
>How-To-Repeat:

>Fix:
I patch the entries definitions in structures by align attribute, I believe it is better than to do nothing. Moreover, it solved my problem.

Patch attached with submission follows:

Index: sys/sys/_rwlock.h
===================================================================
--- sys/sys/_rwlock.h   (revision 213567)
+++ sys/sys/_rwlock.h   (working copy)
@@ -37,7 +37,7 @@
  */
 struct rwlock {
        struct lock_object      lock_object;
-       volatile uintptr_t      rw_lock;
+       volatile uintptr_t      rw_lock __aligned(4);
 };

 #endif /* !_SYS__RWLOCK_H_ */
Index: sys/sys/_sx.h
===================================================================
--- sys/sys/_sx.h       (revision 213567)
+++ sys/sys/_sx.h       (working copy)
@@ -36,7 +36,7 @@
  */
 struct sx {
        struct lock_object      lock_object;
-       volatile uintptr_t      sx_lock;
+       volatile uintptr_t      sx_lock __aligned(4);
 };

 #endif /* !_SYS__SX_H_ */
Index: sys/sys/_lockmgr.h
===================================================================
--- sys/sys/_lockmgr.h  (revision 213567)
+++ sys/sys/_lockmgr.h  (working copy)
@@ -37,7 +37,7 @@

 struct lock {
        struct lock_object      lock_object;
-       volatile uintptr_t      lk_lock;
+       volatile uintptr_t      lk_lock __aligned(4);
        u_int                   lk_exslpfail;
        int                     lk_timo;
        int                     lk_pri;
Index: sys/sys/_mutex.h
===================================================================
--- sys/sys/_mutex.h    (revision 213567)
+++ sys/sys/_mutex.h    (working copy)
@@ -35,8 +35,8 @@
  * Sleep/spin mutex.
  */
 struct mtx {
-       struct lock_object      lock_object;    /* Common lock properties. */
-       volatile uintptr_t      mtx_lock;       /* Owner and flags. */
+       struct lock_object      lock_object;            /* Common lock properties. */
+       volatile uintptr_t      mtx_lock __aligned(4);  /* Owner and flags. */
 };

 #endif /* !_SYS__MUTEX_H_ */



>Release-Note:
>Audit-Trail:

From: Bruce Evans <brde@optusnet.com.au>
To: Svatopluk Kraus <onwahe@gmail.com>
Cc: freebsd-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org
Subject: Re: kern/151304: patch - definitions of variables tested by
 ASSERT_ATOMIC_LOAD_PTR
Date: Sat, 9 Oct 2010 07:16:43 +1100 (EST)

 On Fri, 8 Oct 2010, Svatopluk Kraus wrote:
 
 >> Description:
 > A macro ASSERT_ATOMIC_LOAD_PTR() hits in colfire port I work on. It is possibly due to use of GNU GCC (4.5.1) compiler -Os option (size optimalization). The macro is applied on four places:
 
 Perhaps gcc-4.5.1 -Os is doing invalid packing of structs, or FreeBSD has
 broken packing of structs using the __packed mistake and gcc-4.5.1 -Os
 exposes the brokenness by exploiting __packed more.  Probably the latter.
 
 BTW, gcc-4.2.1 -Os is still completely broken on kernels.  It fails to
 compile some files due to problems with -Wuninitialized, and when this
 is worked around it produces a kernel that is about 50% larger than one
 produced by gcc-4.2.1 -O.  A few years ago I thought the problem was
 excessive inlining, but when I tried to fix it a few weeks ago, reducing
 the inlining caused larger problems and still gave large negative
 optimizations.
 
 >> Fix:
 > I patch the entries definitions in structures by align attribute, I believe it is better than to do nothing. Moreover, it solved my problem.
 >
 > Patch attached with submission follows:
 >
 > Index: sys/sys/_rwlock.h
 > ===================================================================
 > --- sys/sys/_rwlock.h   (revision 213567)
 > +++ sys/sys/_rwlock.h   (working copy)
 > @@ -37,7 +37,7 @@
 >  */
 > struct rwlock {
 >        struct lock_object      lock_object;
 > -       volatile uintptr_t      rw_lock;
 > +       volatile uintptr_t      rw_lock __aligned(4);
 > };
 >
 > #endif /* !_SYS__RWLOCK_H_ */
 > ...
 
 This does nothing good on arches with 64-bit pointers.  With gcc-4.2.1 on
 amd64, it seems to do nothing -- the natural alignment of a uintptr_t on
 amd64 is 8, and asking for a smaller alignment using __aligned(4) apparently
 makes no difference.  It takes __aligned(more_than_8) or __packed to make a
 difference.
 
 Here is an example of creating an alignment bug due using __packed and just
 gcc-4.2.1 on amd64:
 
 % #include <sys/cdefs.h>
 % #include <stddef.h>
 % 
 % struct foo {
 % 	int	x;
 % 	long	y __aligned(4);
 % };
 % 
 % struct bar {
 % 	char	c;
 % 	struct foo d;
 % } __packed;
 % 
 % int z = offsetof(struct foo, y);
 % int t = sizeof (struct bar);
 
 'y' has the correct offset of 8, but `struct bar' has size 17, so the `y'
 nested in it cannot possibly be aligned properly, at least if there is an
 array of `struct bar' with at least 2 elements.  I think this is a compiler
 bug -- the explicit __aligned(4) in the nested struct should force alignment
 of container structs (but only to 4 here, not the 8 that is required).
 
 Bruce

From: Svatopluk Kraus <onwahe@gmail.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/151304: [patch] definitions of variables tested by ASSERT_ATOMIC_LOAD_PTR
Date: Wed, 20 Oct 2010 13:41:43 +0200

 In the light of my new insight into a kernel matter, I think that the
 problem could be closed. Default data alignment for coldfire is 2
 bytes (gcc). What an unexpected surprise for 32-bit processor. It can
 be changed by -malign-int machine specific option. Thanks Bruce for
 your hint.
 
    Svata
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Fri Oct 22 09:51:40 UTC 2010 
State-Changed-Why:  
Closed at submitter's request. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=151304 
>Unformatted:
