Messages in this thread | | | Subject | Re: New information on the CIPE problem (compiler conflicts) | Date | Fri, 17 Mar 2000 01:14:33 +0100 | From | Olaf Titz <> |
| |
[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/
| |