Re: [PATCH] perfcounters: fix type/event_id layout on big-endiansystems
From: Peter Zijlstra
Date: Sat Mar 21 2009 - 06:24:55 EST
On Sat, 2009-03-21 at 15:53 +1100, Paul Mackerras wrote:
> Impact: build fix for powerpc
>
> Commit db3a944aca35ae61 ("perf_counter: revamp syscall input ABI")
> expanded the hw_event.type field into a union of structs containing
> bitfields. In particular it introduced a type field and a raw_type
> field, with the intention that the 1-bit raw_type field should
> overlay the most-significant bit of the 8-bit type field, and in fact
> perf_counter_alloc() now assumes that (or at least, assumes that
> raw_type doesn't overlay any of the bits that are 1 in the values of
> PERF_TYPE_{HARDWARE,SOFTWARE,TRACEPOINT}).
>
> Unfortunately this is not true on big-endian systems such as PowerPC,
> where bitfields are laid out from left to right, i.e. from most
> significant bit to least significant. This means that setting
> hw_event.type = PERF_TYPE_SOFTWARE will set hw_event.raw_type to 1.
>
> This fixes it by making the layout depend on whether or not
> __BIG_ENDIAN_BITFIELD is defined. It's a bit ugly, but that's what
> we get for using bitfields in a user/kernel ABI.
Hmm, does userspace know about __BIG_ENDIAN_BITFIELD too? If not, we've
got ourselves a problem here.
Sorry about missing those powerpc bits, I guess I should dust-off the
cross-compiler.
> diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
> index a4b76c0..98f5990 100644
> --- a/include/linux/perf_counter.h
> +++ b/include/linux/perf_counter.h
> @@ -15,6 +15,7 @@
>
> #include <linux/types.h>
> #include <linux/ioctl.h>
> +#include <asm/byteorder.h>
>
> /*
> * User-space ABI bits:
> @@ -86,6 +87,7 @@ enum perf_counter_record_type {
> */
> struct perf_counter_hw_event {
> union {
> +#ifndef __BIG_ENDIAN_BITFIELD
> struct {
> __u64 event_id : 56,
> type : 8;
> @@ -94,6 +96,16 @@ struct perf_counter_hw_event {
> __u64 raw_event_id : 63,
> raw_type : 1;
> };
> +#else
> + struct {
> + __u64 type : 8,
> + event_id : 56;
> + };
> + struct {
> + __u64 raw_type : 1,
> + raw_event_id : 63;
> + };
> +#endif /* __BIT_ENDIAN_BITFIELD */
> __u64 event_config;
> };
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/