lkml.org 
[lkml]   [2009]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH] perfcounters: fix type/event_id layout on big-endian systems
From
Date
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;
> };
>



\
 
 \ /
  Last update: 2009-03-21 11:27    [W:0.068 / U:5.460 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site