Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-20 Thread Pavel Machek
Hi!

> > > hm.  So if I have
> > > 
> > >   struct bar {
> > >   unsigned long b;
> > >   } __attribute__((packed));
> > > 
> > >   struct foo {
> > >   unsigned long u;
> > >   struct bar b;
> > >   };
> > > 
> > > then the compiler can see that foo.b.b is well-aligned, regardless of the
> > > packedness.
> > > 
> > > Plus some crazy people compile the kernel with icc (or at least they used
> > > to).  What happens there?
> > 
> > A quick grep for __attribute__((packed)) and __packed find around 900 hits,
> > I'd probably find more if I'd look for syntactical variations.  Some hits
> > are in arch/{i386,x86_64,ia64}.  At a glance it seems hard to configure a
> > useful x86 kernel that doesn't involve any packed attribute.  I take that
> > as statistical proof that icc either has doesn't really work for building
> > the kernel or groks packing.  Any compiler not implementing gcc extensions
> > is lost at building the kernel but that's old news.
> > 
> 
> No, icc surely supports attribute(packed).  My point is that we shouldn't
> rely upon the gcc info file for this, because other compilers can (or
> could) be used to build the kernel.

Well, icc should be gcc compatible. If it is not, it is icc bug.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-20 Thread Pavel Machek
Hi!

   hm.  So if I have
   
 struct bar {
 unsigned long b;
 } __attribute__((packed));
   
 struct foo {
 unsigned long u;
 struct bar b;
 };
   
   then the compiler can see that foo.b.b is well-aligned, regardless of the
   packedness.
   
   Plus some crazy people compile the kernel with icc (or at least they used
   to).  What happens there?
  
  A quick grep for __attribute__((packed)) and __packed find around 900 hits,
  I'd probably find more if I'd look for syntactical variations.  Some hits
  are in arch/{i386,x86_64,ia64}.  At a glance it seems hard to configure a
  useful x86 kernel that doesn't involve any packed attribute.  I take that
  as statistical proof that icc either has doesn't really work for building
  the kernel or groks packing.  Any compiler not implementing gcc extensions
  is lost at building the kernel but that's old news.
  
 
 No, icc surely supports attribute(packed).  My point is that we shouldn't
 rely upon the gcc info file for this, because other compilers can (or
 could) be used to build the kernel.

Well, icc should be gcc compatible. If it is not, it is icc bug.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Ralf Baechle
On Thu, Feb 15, 2007 at 05:27:20PM -0800, Andrew Morton wrote:

> No, icc surely supports attribute(packed).  My point is that we shouldn't
> rely upon the gcc info file for this, because other compilers can (or
> could) be used to build the kernel.
> 
> So it would be safer if the C spec said (or could be interpreted to say)
> "members of packed structures are always copied bytewise".  So then we
> can be reasonably confident that this change won't break the use of
> those compilers.
> 
> But then, I don't even know if any C standard says anything about packing.

Memory layout and alignment of structures and members are implementation
defined according to the C standard; the standard provides no means to
influence these.  So it takes a compiler extension such as gcc's
__attribute__().

> Ho hum.  Why are we talking about this, anyway?  Does the patch make the
> code faster?  Or just nicer?

Smaller binary and from looking at the disassembly a tad faster also.

  Ralf
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Andrew Morton
On Fri, 16 Feb 2007 00:43:17 +
Ralf Baechle <[EMAIL PROTECTED]> wrote:

> On Thu, Feb 15, 2007 at 03:38:23PM -0800, Andrew Morton wrote:
> 
> > hm.  So if I have
> > 
> > struct bar {
> > unsigned long b;
> > } __attribute__((packed));
> > 
> > struct foo {
> > unsigned long u;
> > struct bar b;
> > };
> > 
> > then the compiler can see that foo.b.b is well-aligned, regardless of the
> > packedness.
> > 
> > Plus some crazy people compile the kernel with icc (or at least they used
> > to).  What happens there?
> 
> A quick grep for __attribute__((packed)) and __packed find around 900 hits,
> I'd probably find more if I'd look for syntactical variations.  Some hits
> are in arch/{i386,x86_64,ia64}.  At a glance it seems hard to configure a
> useful x86 kernel that doesn't involve any packed attribute.  I take that
> as statistical proof that icc either has doesn't really work for building
> the kernel or groks packing.  Any compiler not implementing gcc extensions
> is lost at building the kernel but that's old news.
> 

No, icc surely supports attribute(packed).  My point is that we shouldn't
rely upon the gcc info file for this, because other compilers can (or
could) be used to build the kernel.

So it would be safer if the C spec said (or could be interpreted to say)
"members of packed structures are always copied bytewise".  So then we
can be reasonably confident that this change won't break the use of
those compilers.

But then, I don't even know if any C standard says anything about packing.

Ho hum.  Why are we talking about this, anyway?  Does the patch make the
code faster?  Or just nicer?
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Ralf Baechle
On Thu, Feb 15, 2007 at 03:38:23PM -0800, Andrew Morton wrote:

> hm.  So if I have
> 
>   struct bar {
>   unsigned long b;
>   } __attribute__((packed));
> 
>   struct foo {
>   unsigned long u;
>   struct bar b;
>   };
> 
> then the compiler can see that foo.b.b is well-aligned, regardless of the
> packedness.
> 
> Plus some crazy people compile the kernel with icc (or at least they used
> to).  What happens there?

A quick grep for __attribute__((packed)) and __packed find around 900 hits,
I'd probably find more if I'd look for syntactical variations.  Some hits
are in arch/{i386,x86_64,ia64}.  At a glance it seems hard to configure a
useful x86 kernel that doesn't involve any packed attribute.  I take that
as statistical proof that icc either has doesn't really work for building
the kernel or groks packing.  Any compiler not implementing gcc extensions
is lost at building the kernel but that's old news.

  Ralf
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Jeremy Fitzhardinge
Andrew Morton wrote:
> hm.  So if I have
>
>   struct bar {
>   unsigned long b;
>   } __attribute__((packed));
>
>   struct foo {
>   unsigned long u;
>   struct bar b;
>   };
>
> then the compiler can see that foo.b.b is well-aligned, regardless of the
> packedness.

In Ralf's code, the structure is anonymous, and is used to declare a
pointer type, which is initialized from a void *.  So I think the
compiler isn't allowed to assume anything about its alignment.

J
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Andrew Morton
On Thu, 15 Feb 2007 22:18:39 +
Ralf Baechle <[EMAIL PROTECTED]> wrote:

> On Thu, Feb 15, 2007 at 01:53:58PM -0800, Andrew Morton wrote:
> 
> > > The whole union thing was only needed to get rid of a warning but Marcel's
> > > solution does the same thing by attaching the packed keyword to the entire
> > > structure instead, so this patch is now using his macros but using 
> > > __packed
> > > instead.
> > 
> > How do we know this trick will work as-designed across all versions of gcc
> > and icc (at least) and for all architectures and for all sets of compiler
> > options?
> > 
> > Basically, it has to be guaranteed by a C standard.  Is it?
> 
> Gcc info page says:
> 
> [...]
> `packed'
>  The `packed' attribute specifies that a variable or structure field
>  should have the smallest possible alignment--one byte for a
>  variable, and one bit for a field, unless you specify a larger
>  value with the `aligned' attribute.
> [...]
> 

hm.  So if I have

struct bar {
unsigned long b;
} __attribute__((packed));

struct foo {
unsigned long u;
struct bar b;
};

then the compiler can see that foo.b.b is well-aligned, regardless of the
packedness.

Plus some crazy people compile the kernel with icc (or at least they used
to).  What happens there?

> Qed?

worried.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Jeremy Fitzhardinge
Ralf Baechle wrote:
> Gcc info page says:
>
> [...]
> `packed'
>  The `packed' attribute specifies that a variable or structure field
>  should have the smallest possible alignment--one byte for a
>  variable, and one bit for a field, unless you specify a larger
>  value with the `aligned' attribute.
> [...]
>
> Qed?

So that the compiler has to assume that if its accessing this __packed
structure, it may be embedded unaligned within something else? And
because the pointer is cast through (void *) it isn't allowed to use
alias analysis to notice that the pointer wasn't originally (apparently)
unaligned.

Seems sound to me.

J
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Ralf Baechle
On Thu, Feb 15, 2007 at 01:53:58PM -0800, Andrew Morton wrote:

> > The whole union thing was only needed to get rid of a warning but Marcel's
> > solution does the same thing by attaching the packed keyword to the entire
> > structure instead, so this patch is now using his macros but using __packed
> > instead.
> 
> How do we know this trick will work as-designed across all versions of gcc
> and icc (at least) and for all architectures and for all sets of compiler
> options?
> 
> Basically, it has to be guaranteed by a C standard.  Is it?

Gcc info page says:

[...]
`packed'
 The `packed' attribute specifies that a variable or structure field
 should have the smallest possible alignment--one byte for a
 variable, and one bit for a field, unless you specify a larger
 value with the `aligned' attribute.
[...]

Qed?

  Ralf
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Andrew Morton
On Thu, 15 Feb 2007 14:34:41 +
Ralf Baechle <[EMAIL PROTECTED]> wrote:

> On Wed, Feb 14, 2007 at 08:39:03PM -0800, Andrew Morton wrote:
> 
> > Can someone please tell us how this magic works?  (And it does appear to
> > work).
> > 
> > It seems to assuming that the compiler will assume that members of packed
> > structures can have arbitrary alignment, even if that alignment is obvious.
> > 
> > Which makes sense, but I'd like to see chapter-and-verse from the spec or
> > from the gcc docs so we can rely upon it working on all architectures and
> > compilers from now until ever more.
> > 
> > IOW: your changlogging sucks ;)
> 
> It was my entry for the next edition of the C Puzzle Book ;-)
> 
> The whole union thing was only needed to get rid of a warning but Marcel's
> solution does the same thing by attaching the packed keyword to the entire
> structure instead, so this patch is now using his macros but using __packed
> instead.

How do we know this trick will work as-designed across all versions of gcc
and icc (at least) and for all architectures and for all sets of compiler
options?

Basically, it has to be guaranteed by a C standard.  Is it?
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Ralf Baechle
On Wed, Feb 14, 2007 at 08:39:03PM -0800, Andrew Morton wrote:

> Can someone please tell us how this magic works?  (And it does appear to
> work).
> 
> It seems to assuming that the compiler will assume that members of packed
> structures can have arbitrary alignment, even if that alignment is obvious.
> 
> Which makes sense, but I'd like to see chapter-and-verse from the spec or
> from the gcc docs so we can rely upon it working on all architectures and
> compilers from now until ever more.
> 
> IOW: your changlogging sucks ;)

It was my entry for the next edition of the C Puzzle Book ;-)

The whole union thing was only needed to get rid of a warning but Marcel's
solution does the same thing by attaching the packed keyword to the entire
structure instead, so this patch is now using his macros but using __packed
instead.

  Ralf

Signed-off-by: Ralf Baechle <[EMAIL PROTECTED]>

diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h
index 09ec447..60d94fc 100644
--- a/include/asm-generic/unaligned.h
+++ b/include/asm-generic/unaligned.h
@@ -1,122 +1,27 @@
-#ifndef _ASM_GENERIC_UNALIGNED_H_
-#define _ASM_GENERIC_UNALIGNED_H_
-
-/*
- * For the benefit of those who are trying to port Linux to another
- * architecture, here are some C-language equivalents. 
- *
- * This is based almost entirely upon Richard Henderson's
- * asm-alpha/unaligned.h implementation.  Some comments were
- * taken from David Mosberger's asm-ia64/unaligned.h header.
- */
-
-#include 
-
-/* 
- * The main single-value unaligned transfer routines.
- */
-#define get_unaligned(ptr) \
-   __get_unaligned((ptr), sizeof(*(ptr)))
-#define put_unaligned(x,ptr) \
-   __put_unaligned((__u64)(x), (ptr), sizeof(*(ptr)))
-
 /*
- * This function doesn't actually exist.  The idea is that when
- * someone uses the macros below with an unsupported size (datatype),
- * the linker will alert us to the problem via an unresolved reference
- * error.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  */
-extern void bad_unaligned_access_length(void) __attribute__((noreturn));
-
-struct __una_u64 { __u64 x __attribute__((packed)); };
-struct __una_u32 { __u32 x __attribute__((packed)); };
-struct __una_u16 { __u16 x __attribute__((packed)); };
-
-/*
- * Elemental unaligned loads 
- */
-
-static inline __u64 __uldq(const __u64 *addr)
-{
-   const struct __una_u64 *ptr = (const struct __una_u64 *) addr;
-   return ptr->x;
-}
-
-static inline __u32 __uldl(const __u32 *addr)
-{
-   const struct __una_u32 *ptr = (const struct __una_u32 *) addr;
-   return ptr->x;
-}
-
-static inline __u16 __uldw(const __u16 *addr)
-{
-   const struct __una_u16 *ptr = (const struct __una_u16 *) addr;
-   return ptr->x;
-}
-
-/*
- * Elemental unaligned stores 
- */
-
-static inline void __ustq(__u64 val, __u64 *addr)
-{
-   struct __una_u64 *ptr = (struct __una_u64 *) addr;
-   ptr->x = val;
-}
-
-static inline void __ustl(__u32 val, __u32 *addr)
-{
-   struct __una_u32 *ptr = (struct __una_u32 *) addr;
-   ptr->x = val;
-}
+#ifndef __ASM_GENERIC_UNALIGNED_H
+#define __ASM_GENERIC_UNALIGNED_H
 
-static inline void __ustw(__u16 val, __u16 *addr)
-{
-   struct __una_u16 *ptr = (struct __una_u16 *) addr;
-   ptr->x = val;
-}
+#include 
 
-#define __get_unaligned(ptr, size) ({  \
-   const void *__gu_p = ptr;   \
-   __u64 val;  \
-   switch (size) { \
-   case 1: \
-   val = *(const __u8 *)__gu_p;\
-   break;  \
-   case 2: \
-   val = __uldw(__gu_p);   \
-   break;  \
-   case 4: \
-   val = __uldl(__gu_p);   \
-   break;  \
-   case 8: \
-   val = __uldq(__gu_p);   \
-   break;  \
-   default:\
-   bad_unaligned_access_length();  \
-   };  \
-   (__typeof__(*(ptr)))val;\
+#define get_unaligned(ptr) \
+({ \
+   struct __packed {   \
+   typeof(*(ptr)) __v; \
+   } *__p = (void *) (ptr);\
+   __p->__v;   \
 })
 
-#define __put_unaligned(val, ptr, size)\
-do {   \
-   void *__gu_p = ptr; \
-   switch 

Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Marcel Holtmann
Hi Andrew,

> > +#define get_unaligned(ptr) \
> > +({ \
> > +   const struct {  \
> > +   union { \
> > +   const int __un_foo[0];  \
> > +   const __typeof__(*(ptr)) __un;  \
> > +   } __un __attribute__ ((packed));\
> > +   } * const __gu_p = (void *) (ptr);  \
> > +   \
> > +   __gu_p->__un.__un;  \
> >  })
> 
> Can someone please tell us how this magic works?  (And it does appear to
> work).
> 
> It seems to assuming that the compiler will assume that members of packed
> structures can have arbitrary alignment, even if that alignment is obvious.
> 
> Which makes sense, but I'd like to see chapter-and-verse from the spec or
> from the gcc docs so we can rely upon it working on all architectures and
> compilers from now until ever more.

I am far away from having any knowledge about the GCC internals and the
reason why this code works, but I've been told the generic way of
handling unaligned access is this:

#define get_unaligned(ptr)  \
({  \
struct __attribute__((packed)) {\
typeof(*(ptr)) __v; \
} *__p = (void *) (ptr);\
__p->__v;   \
})

#define put_unaligned(val, ptr) \
do {\
struct __attribute__((packed)) {\
typeof(*(ptr)) __v; \
} *__p = (void *) (ptr);\
__p->__v = (val);   \
} while(0)

Actually I am using this code in the Bluetooth userspace library for
over two years now without any complaints.

Regards

Marcel


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Marcel Holtmann
Hi Andrew,

  +#define get_unaligned(ptr) \
  +({ \
  +   const struct {  \
  +   union { \
  +   const int __un_foo[0];  \
  +   const __typeof__(*(ptr)) __un;  \
  +   } __un __attribute__ ((packed));\
  +   } * const __gu_p = (void *) (ptr);  \
  +   \
  +   __gu_p-__un.__un;  \
   })
 
 Can someone please tell us how this magic works?  (And it does appear to
 work).
 
 It seems to assuming that the compiler will assume that members of packed
 structures can have arbitrary alignment, even if that alignment is obvious.
 
 Which makes sense, but I'd like to see chapter-and-verse from the spec or
 from the gcc docs so we can rely upon it working on all architectures and
 compilers from now until ever more.

I am far away from having any knowledge about the GCC internals and the
reason why this code works, but I've been told the generic way of
handling unaligned access is this:

#define get_unaligned(ptr)  \
({  \
struct __attribute__((packed)) {\
typeof(*(ptr)) __v; \
} *__p = (void *) (ptr);\
__p-__v;   \
})

#define put_unaligned(val, ptr) \
do {\
struct __attribute__((packed)) {\
typeof(*(ptr)) __v; \
} *__p = (void *) (ptr);\
__p-__v = (val);   \
} while(0)

Actually I am using this code in the Bluetooth userspace library for
over two years now without any complaints.

Regards

Marcel


-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Ralf Baechle
On Wed, Feb 14, 2007 at 08:39:03PM -0800, Andrew Morton wrote:

 Can someone please tell us how this magic works?  (And it does appear to
 work).
 
 It seems to assuming that the compiler will assume that members of packed
 structures can have arbitrary alignment, even if that alignment is obvious.
 
 Which makes sense, but I'd like to see chapter-and-verse from the spec or
 from the gcc docs so we can rely upon it working on all architectures and
 compilers from now until ever more.
 
 IOW: your changlogging sucks ;)

It was my entry for the next edition of the C Puzzle Book ;-)

The whole union thing was only needed to get rid of a warning but Marcel's
solution does the same thing by attaching the packed keyword to the entire
structure instead, so this patch is now using his macros but using __packed
instead.

  Ralf

Signed-off-by: Ralf Baechle [EMAIL PROTECTED]

diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h
index 09ec447..60d94fc 100644
--- a/include/asm-generic/unaligned.h
+++ b/include/asm-generic/unaligned.h
@@ -1,122 +1,27 @@
-#ifndef _ASM_GENERIC_UNALIGNED_H_
-#define _ASM_GENERIC_UNALIGNED_H_
-
-/*
- * For the benefit of those who are trying to port Linux to another
- * architecture, here are some C-language equivalents. 
- *
- * This is based almost entirely upon Richard Henderson's
- * asm-alpha/unaligned.h implementation.  Some comments were
- * taken from David Mosberger's asm-ia64/unaligned.h header.
- */
-
-#include linux/types.h
-
-/* 
- * The main single-value unaligned transfer routines.
- */
-#define get_unaligned(ptr) \
-   __get_unaligned((ptr), sizeof(*(ptr)))
-#define put_unaligned(x,ptr) \
-   __put_unaligned((__u64)(x), (ptr), sizeof(*(ptr)))
-
 /*
- * This function doesn't actually exist.  The idea is that when
- * someone uses the macros below with an unsupported size (datatype),
- * the linker will alert us to the problem via an unresolved reference
- * error.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
  */
-extern void bad_unaligned_access_length(void) __attribute__((noreturn));
-
-struct __una_u64 { __u64 x __attribute__((packed)); };
-struct __una_u32 { __u32 x __attribute__((packed)); };
-struct __una_u16 { __u16 x __attribute__((packed)); };
-
-/*
- * Elemental unaligned loads 
- */
-
-static inline __u64 __uldq(const __u64 *addr)
-{
-   const struct __una_u64 *ptr = (const struct __una_u64 *) addr;
-   return ptr-x;
-}
-
-static inline __u32 __uldl(const __u32 *addr)
-{
-   const struct __una_u32 *ptr = (const struct __una_u32 *) addr;
-   return ptr-x;
-}
-
-static inline __u16 __uldw(const __u16 *addr)
-{
-   const struct __una_u16 *ptr = (const struct __una_u16 *) addr;
-   return ptr-x;
-}
-
-/*
- * Elemental unaligned stores 
- */
-
-static inline void __ustq(__u64 val, __u64 *addr)
-{
-   struct __una_u64 *ptr = (struct __una_u64 *) addr;
-   ptr-x = val;
-}
-
-static inline void __ustl(__u32 val, __u32 *addr)
-{
-   struct __una_u32 *ptr = (struct __una_u32 *) addr;
-   ptr-x = val;
-}
+#ifndef __ASM_GENERIC_UNALIGNED_H
+#define __ASM_GENERIC_UNALIGNED_H
 
-static inline void __ustw(__u16 val, __u16 *addr)
-{
-   struct __una_u16 *ptr = (struct __una_u16 *) addr;
-   ptr-x = val;
-}
+#include linux/compiler.h
 
-#define __get_unaligned(ptr, size) ({  \
-   const void *__gu_p = ptr;   \
-   __u64 val;  \
-   switch (size) { \
-   case 1: \
-   val = *(const __u8 *)__gu_p;\
-   break;  \
-   case 2: \
-   val = __uldw(__gu_p);   \
-   break;  \
-   case 4: \
-   val = __uldl(__gu_p);   \
-   break;  \
-   case 8: \
-   val = __uldq(__gu_p);   \
-   break;  \
-   default:\
-   bad_unaligned_access_length();  \
-   };  \
-   (__typeof__(*(ptr)))val;\
+#define get_unaligned(ptr) \
+({ \
+   struct __packed {   \
+   typeof(*(ptr)) __v; \
+   } *__p = (void *) (ptr);\
+   __p-__v;   \
 })
 
-#define __put_unaligned(val, ptr, size)\
-do {   \
-   void *__gu_p = ptr; \
-   

Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Andrew Morton
On Thu, 15 Feb 2007 14:34:41 +
Ralf Baechle [EMAIL PROTECTED] wrote:

 On Wed, Feb 14, 2007 at 08:39:03PM -0800, Andrew Morton wrote:
 
  Can someone please tell us how this magic works?  (And it does appear to
  work).
  
  It seems to assuming that the compiler will assume that members of packed
  structures can have arbitrary alignment, even if that alignment is obvious.
  
  Which makes sense, but I'd like to see chapter-and-verse from the spec or
  from the gcc docs so we can rely upon it working on all architectures and
  compilers from now until ever more.
  
  IOW: your changlogging sucks ;)
 
 It was my entry for the next edition of the C Puzzle Book ;-)
 
 The whole union thing was only needed to get rid of a warning but Marcel's
 solution does the same thing by attaching the packed keyword to the entire
 structure instead, so this patch is now using his macros but using __packed
 instead.

How do we know this trick will work as-designed across all versions of gcc
and icc (at least) and for all architectures and for all sets of compiler
options?

Basically, it has to be guaranteed by a C standard.  Is it?
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Ralf Baechle
On Thu, Feb 15, 2007 at 01:53:58PM -0800, Andrew Morton wrote:

  The whole union thing was only needed to get rid of a warning but Marcel's
  solution does the same thing by attaching the packed keyword to the entire
  structure instead, so this patch is now using his macros but using __packed
  instead.
 
 How do we know this trick will work as-designed across all versions of gcc
 and icc (at least) and for all architectures and for all sets of compiler
 options?
 
 Basically, it has to be guaranteed by a C standard.  Is it?

Gcc info page says:

[...]
`packed'
 The `packed' attribute specifies that a variable or structure field
 should have the smallest possible alignment--one byte for a
 variable, and one bit for a field, unless you specify a larger
 value with the `aligned' attribute.
[...]

Qed?

  Ralf
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Jeremy Fitzhardinge
Ralf Baechle wrote:
 Gcc info page says:

 [...]
 `packed'
  The `packed' attribute specifies that a variable or structure field
  should have the smallest possible alignment--one byte for a
  variable, and one bit for a field, unless you specify a larger
  value with the `aligned' attribute.
 [...]

 Qed?

So that the compiler has to assume that if its accessing this __packed
structure, it may be embedded unaligned within something else? And
because the pointer is cast through (void *) it isn't allowed to use
alias analysis to notice that the pointer wasn't originally (apparently)
unaligned.

Seems sound to me.

J
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Andrew Morton
On Thu, 15 Feb 2007 22:18:39 +
Ralf Baechle [EMAIL PROTECTED] wrote:

 On Thu, Feb 15, 2007 at 01:53:58PM -0800, Andrew Morton wrote:
 
   The whole union thing was only needed to get rid of a warning but Marcel's
   solution does the same thing by attaching the packed keyword to the entire
   structure instead, so this patch is now using his macros but using 
   __packed
   instead.
  
  How do we know this trick will work as-designed across all versions of gcc
  and icc (at least) and for all architectures and for all sets of compiler
  options?
  
  Basically, it has to be guaranteed by a C standard.  Is it?
 
 Gcc info page says:
 
 [...]
 `packed'
  The `packed' attribute specifies that a variable or structure field
  should have the smallest possible alignment--one byte for a
  variable, and one bit for a field, unless you specify a larger
  value with the `aligned' attribute.
 [...]
 

hm.  So if I have

struct bar {
unsigned long b;
} __attribute__((packed));

struct foo {
unsigned long u;
struct bar b;
};

then the compiler can see that foo.b.b is well-aligned, regardless of the
packedness.

Plus some crazy people compile the kernel with icc (or at least they used
to).  What happens there?

 Qed?

worried.
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Jeremy Fitzhardinge
Andrew Morton wrote:
 hm.  So if I have

   struct bar {
   unsigned long b;
   } __attribute__((packed));

   struct foo {
   unsigned long u;
   struct bar b;
   };

 then the compiler can see that foo.b.b is well-aligned, regardless of the
 packedness.

In Ralf's code, the structure is anonymous, and is used to declare a
pointer type, which is initialized from a void *.  So I think the
compiler isn't allowed to assume anything about its alignment.

J
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Ralf Baechle
On Thu, Feb 15, 2007 at 03:38:23PM -0800, Andrew Morton wrote:

 hm.  So if I have
 
   struct bar {
   unsigned long b;
   } __attribute__((packed));
 
   struct foo {
   unsigned long u;
   struct bar b;
   };
 
 then the compiler can see that foo.b.b is well-aligned, regardless of the
 packedness.
 
 Plus some crazy people compile the kernel with icc (or at least they used
 to).  What happens there?

A quick grep for __attribute__((packed)) and __packed find around 900 hits,
I'd probably find more if I'd look for syntactical variations.  Some hits
are in arch/{i386,x86_64,ia64}.  At a glance it seems hard to configure a
useful x86 kernel that doesn't involve any packed attribute.  I take that
as statistical proof that icc either has doesn't really work for building
the kernel or groks packing.  Any compiler not implementing gcc extensions
is lost at building the kernel but that's old news.

  Ralf
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Andrew Morton
On Fri, 16 Feb 2007 00:43:17 +
Ralf Baechle [EMAIL PROTECTED] wrote:

 On Thu, Feb 15, 2007 at 03:38:23PM -0800, Andrew Morton wrote:
 
  hm.  So if I have
  
  struct bar {
  unsigned long b;
  } __attribute__((packed));
  
  struct foo {
  unsigned long u;
  struct bar b;
  };
  
  then the compiler can see that foo.b.b is well-aligned, regardless of the
  packedness.
  
  Plus some crazy people compile the kernel with icc (or at least they used
  to).  What happens there?
 
 A quick grep for __attribute__((packed)) and __packed find around 900 hits,
 I'd probably find more if I'd look for syntactical variations.  Some hits
 are in arch/{i386,x86_64,ia64}.  At a glance it seems hard to configure a
 useful x86 kernel that doesn't involve any packed attribute.  I take that
 as statistical proof that icc either has doesn't really work for building
 the kernel or groks packing.  Any compiler not implementing gcc extensions
 is lost at building the kernel but that's old news.
 

No, icc surely supports attribute(packed).  My point is that we shouldn't
rely upon the gcc info file for this, because other compilers can (or
could) be used to build the kernel.

So it would be safer if the C spec said (or could be interpreted to say)
members of packed structures are always copied bytewise.  So then we
can be reasonably confident that this change won't break the use of
those compilers.

But then, I don't even know if any C standard says anything about packing.

Ho hum.  Why are we talking about this, anyway?  Does the patch make the
code faster?  Or just nicer?
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-15 Thread Ralf Baechle
On Thu, Feb 15, 2007 at 05:27:20PM -0800, Andrew Morton wrote:

 No, icc surely supports attribute(packed).  My point is that we shouldn't
 rely upon the gcc info file for this, because other compilers can (or
 could) be used to build the kernel.
 
 So it would be safer if the C spec said (or could be interpreted to say)
 members of packed structures are always copied bytewise.  So then we
 can be reasonably confident that this change won't break the use of
 those compilers.
 
 But then, I don't even know if any C standard says anything about packing.

Memory layout and alignment of structures and members are implementation
defined according to the C standard; the standard provides no means to
influence these.  So it takes a compiler extension such as gcc's
__attribute__().

 Ho hum.  Why are we talking about this, anyway?  Does the patch make the
 code faster?  Or just nicer?

Smaller binary and from looking at the disassembly a tad faster also.

  Ralf
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-14 Thread Andrew Morton
On Wed, 14 Feb 2007 21:42:26 + Ralf Baechle <[EMAIL PROTECTED]> wrote:

> Time for a little bit of dead horse flogging.
> 
> On Mon, Mar 06, 2006 at 05:05:52PM -0800, Andrew Morton wrote:
> 
> > > --- a/include/asm-generic/unaligned.h
> > > +++ b/include/asm-generic/unaligned.h
> > > @@ -78,7 +78,7 @@ static inline void __ustw(__u16 val, __u
> > >  
> > >  #define __get_unaligned(ptr, size) ({\
> > >   const void *__gu_p = ptr;   \
> > > - __typeof__(*(ptr)) val; \
> > > + __u64 val;  \
> > >   switch (size) { \
> > >   case 1: \
> > >   val = *(const __u8 *)__gu_p;\
> > > @@ -95,7 +95,7 @@ static inline void __ustw(__u16 val, __u
> > >   default:\
> > >   bad_unaligned_access_length();  \
> > >   };  \
> > > - val;\
> > > + (__typeof__(*(ptr)))val;\
> > >  })
> > >  
> > >  #define __put_unaligned(val, ptr, size)  \
> > 
> > I worry about what impact that change might have on code generation. 
> > Hopefully none, if gcc is good enough.
> > 
> > But I cannot think of a better fix.
> 
> It does inflate the code but back then we agreed to go for Atsushi's patch
> because it was fairly obviously correct.  This patch obviously is less
> obvious but generates fairly decent, works for arbitrary data types and
> cuts down the size of unaligned.h from 122 lines to 44 so it must be good.
> 
> ...
>
> +#define get_unaligned(ptr)   \
> +({   \
> + const struct {  \
> + union { \
> + const int __un_foo[0];  \
> + const __typeof__(*(ptr)) __un;  \
> + } __un __attribute__ ((packed));\
> + } * const __gu_p = (void *) (ptr);  \
> + \
> + __gu_p->__un.__un;  \
>  })

Can someone please tell us how this magic works?  (And it does appear to
work).

It seems to assuming that the compiler will assume that members of packed
structures can have arbitrary alignment, even if that alignment is obvious.

Which makes sense, but I'd like to see chapter-and-verse from the spec or
from the gcc docs so we can rely upon it working on all architectures and
compilers from now until ever more.

IOW: your changlogging sucks ;)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.

2007-02-14 Thread Andrew Morton
On Wed, 14 Feb 2007 21:42:26 + Ralf Baechle [EMAIL PROTECTED] wrote:

 Time for a little bit of dead horse flogging.
 
 On Mon, Mar 06, 2006 at 05:05:52PM -0800, Andrew Morton wrote:
 
   --- a/include/asm-generic/unaligned.h
   +++ b/include/asm-generic/unaligned.h
   @@ -78,7 +78,7 @@ static inline void __ustw(__u16 val, __u

#define __get_unaligned(ptr, size) ({\
 const void *__gu_p = ptr;   \
   - __typeof__(*(ptr)) val; \
   + __u64 val;  \
 switch (size) { \
 case 1: \
 val = *(const __u8 *)__gu_p;\
   @@ -95,7 +95,7 @@ static inline void __ustw(__u16 val, __u
 default:\
 bad_unaligned_access_length();  \
 };  \
   - val;\
   + (__typeof__(*(ptr)))val;\
})

#define __put_unaligned(val, ptr, size)  \
  
  I worry about what impact that change might have on code generation. 
  Hopefully none, if gcc is good enough.
  
  But I cannot think of a better fix.
 
 It does inflate the code but back then we agreed to go for Atsushi's patch
 because it was fairly obviously correct.  This patch obviously is less
 obvious but generates fairly decent, works for arbitrary data types and
 cuts down the size of unaligned.h from 122 lines to 44 so it must be good.
 
 ...

 +#define get_unaligned(ptr)   \
 +({   \
 + const struct {  \
 + union { \
 + const int __un_foo[0];  \
 + const __typeof__(*(ptr)) __un;  \
 + } __un __attribute__ ((packed));\
 + } * const __gu_p = (void *) (ptr);  \
 + \
 + __gu_p-__un.__un;  \
  })

Can someone please tell us how this magic works?  (And it does appear to
work).

It seems to assuming that the compiler will assume that members of packed
structures can have arbitrary alignment, even if that alignment is obvious.

Which makes sense, but I'd like to see chapter-and-verse from the spec or
from the gcc docs so we can rely upon it working on all architectures and
compilers from now until ever more.

IOW: your changlogging sucks ;)
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/