Re: New information on the CIPE problem (compiler conflicts)

From: Olaf Titz (olaf@bigred.inka.de)
Date: Thu Mar 16 2000 - 19:14:33 EST


[CCd to linux-kernel]

Martijn van Oosterhout <kleptog@cupid.suninternet.com> wrote:
> It seems indeed that the module and the kernel were
> compiled with different versions. The kernel with 2.95.2
> (Debian Potato) on a dual-PII and the module on the
> actually machine with 2.7.2.3 (Debian Slink).

Exactly my config too.

> I checked a few header files to see if there was anything
> obvious. All I could come up with was in the
> <linux/netdevice.h> header, in the declaration for
> struct hh_cache. The member named hh_type it in a
> position to make the alignment ambiguous. This would
> explain the 2 byte shift.

Good spot. I've always suspected that the hh_cache was involved in
some way. This struct is (in 2.2.15pre7 <linux/netdevice.h>) as
follows, and it's even worse than seen from your first look:

struct hh_cache
{
        struct hh_cache *hh_next; /* Next entry */
        atomic_t hh_refcnt; /* number of users */
        unsigned short hh_type; /* protocol identifier, f.e ETH_P_IP */
     /*** Possible alignment problem here ***/
        int (*hh_output)(struct sk_buff *skb);
        rwlock_t hh_lock;
     /*** And another possible alignment problem here ***/
        /* cached hardware header; allow for machine alignment needs. */
        unsigned long hh_data[16/sizeof(unsigned long)];
};

As I've already mentioned I've got a _four_ byte shift. The reason is
probably the rwlock_t definition in <asm-i386/spinlock.h> for the UP case:

#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
  typedef struct { } rwlock_t;
  #define RW_LOCK_UNLOCKED (rwlock_t) { }
#else
  typedef struct { int gcc_is_buggy; } rwlock_t;
  #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
#endif

This is not only an alignment problem but an explicit compiler
dependency as well :-(

Alan (or whoever is responsible :-), is there any chance to get this
fixed in some way?

> Suggestion: use attribute((packed)), make it an int
> and move that member elsewhere.

Packing doesn't look right to me, as misaligning the array and the
lock (for SMP) is performance-unfriendly. Reordering could help, like
this:

struct hh_cache
{
        struct hh_cache *hh_next; /* Next entry */
        atomic_t hh_refcnt; /* number of users */
        int (*hh_output)(struct sk_buff *skb);
        /* cached hardware header; allow for machine alignment needs. */
        unsigned long hh_data[16/sizeof(unsigned long)];
        rwlock_t hh_lock;
        unsigned short hh_type; /* protocol identifier, f.e ETH_P_IP */
};

Olaf

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Mar 23 2000 - 21:00:20 EST