Merge branch 'linus' into perf/core, to refresh the branch
authorIngo Molnar <mingo@kernel.org>
Wed, 8 Jun 2016 07:26:46 +0000 (09:26 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 8 Jun 2016 07:26:46 +0000 (09:26 +0200)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
include/linux/perf_event.h
kernel/bpf/stackmap.c
kernel/events/core.c
tools/perf/util/evsel.c
tools/perf/util/parse-events.c
tools/perf/util/session.c

@@@ -517,11 -517,6 +517,11 @@@ struct swevent_hlist 
  struct perf_cgroup;
  struct ring_buffer;
  
 +struct pmu_event_list {
 +      raw_spinlock_t          lock;
 +      struct list_head        list;
 +};
 +
  /**
   * struct perf_event - performance event kernel representation:
   */
@@@ -680,7 -675,6 +680,7 @@@ struct perf_event 
        int                             cgrp_defer_enabled;
  #endif
  
 +      struct list_head                sb_list;
  #endif /* CONFIG_PERF_EVENTS */
  };
  
@@@ -990,8 -984,6 +990,6 @@@ static inline void perf_arch_fetch_call
   */
  static inline void perf_fetch_caller_regs(struct pt_regs *regs)
  {
-       memset(regs, 0, sizeof(*regs));
        perf_arch_fetch_caller_regs(regs, CALLER_ADDR0);
  }
  
@@@ -1082,7 -1074,7 +1080,7 @@@ extern void perf_callchain_kernel(struc
  extern struct perf_callchain_entry *
  get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
                   u32 max_stack, bool crosstask, bool add_mark);
 -extern int get_callchain_buffers(void);
 +extern int get_callchain_buffers(int max_stack);
  extern void put_callchain_buffers(void);
  
  extern int sysctl_perf_event_max_stack;
@@@ -1146,7 -1138,7 +1144,7 @@@ static inline bool perf_paranoid_kernel
  }
  
  extern void perf_event_init(void);
- extern void perf_tp_event(u64 addr, u64 count, void *record,
+ extern void perf_tp_event(u16 event_type, u64 count, void *record,
                          int entry_size, struct pt_regs *regs,
                          struct hlist_head *head, int rctx,
                          struct task_struct *task);
@@@ -1334,13 -1326,6 +1332,13 @@@ struct perf_pmu_events_attr 
        const char *event_str;
  };
  
 +struct perf_pmu_events_ht_attr {
 +      struct device_attribute                 attr;
 +      u64                                     id;
 +      const char                              *event_str_ht;
 +      const char                              *event_str_noht;
 +};
 +
  ssize_t perf_event_sysfs_show(struct device *dev, struct device_attribute *attr,
                              char *page);
  
diff --combined kernel/bpf/stackmap.c
@@@ -99,7 -99,7 +99,7 @@@ static struct bpf_map *stack_map_alloc(
        if (err)
                goto free_smap;
  
 -      err = get_callchain_buffers();
 +      err = get_callchain_buffers(sysctl_perf_event_max_stack);
        if (err)
                goto free_smap;
  
@@@ -116,7 -116,7 +116,7 @@@ free_smap
        return ERR_PTR(err);
  }
  
static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5)
+ u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5)
  {
        struct pt_regs *regs = (struct pt_regs *) (long) r1;
        struct bpf_map *map = (struct bpf_map *) (long) r2;
diff --combined kernel/events/core.c
@@@ -335,7 -335,6 +335,7 @@@ static atomic_t perf_sched_count
  
  static DEFINE_PER_CPU(atomic_t, perf_cgroup_events);
  static DEFINE_PER_CPU(int, perf_sched_cb_usages);
 +static DEFINE_PER_CPU(struct pmu_event_list, pmu_sb_events);
  
  static atomic_t nr_mmap_events __read_mostly;
  static atomic_t nr_comm_events __read_mostly;
@@@ -397,13 -396,6 +397,13 @@@ int perf_proc_update_handler(struct ctl
        if (ret || !write)
                return ret;
  
 +      /*
 +       * If throttling is disabled don't allow the write:
 +       */
 +      if (sysctl_perf_cpu_time_max_percent == 100 ||
 +          sysctl_perf_cpu_time_max_percent == 0)
 +              return -EINVAL;
 +
        max_samples_per_tick = DIV_ROUND_UP(sysctl_perf_event_sample_rate, HZ);
        perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate;
        update_perf_cpu_limits();
@@@ -3673,39 -3665,6 +3673,39 @@@ static void free_event_rcu(struct rcu_h
  static void ring_buffer_attach(struct perf_event *event,
                               struct ring_buffer *rb);
  
 +static void detach_sb_event(struct perf_event *event)
 +{
 +      struct pmu_event_list *pel = per_cpu_ptr(&pmu_sb_events, event->cpu);
 +
 +      raw_spin_lock(&pel->lock);
 +      list_del_rcu(&event->sb_list);
 +      raw_spin_unlock(&pel->lock);
 +}
 +
 +static bool is_sb_event(struct perf_event *event)
 +{
 +      struct perf_event_attr *attr = &event->attr;
 +
 +      if (event->parent)
 +              return false;
 +
 +      if (event->attach_state & PERF_ATTACH_TASK)
 +              return false;
 +
 +      if (attr->mmap || attr->mmap_data || attr->mmap2 ||
 +          attr->comm || attr->comm_exec ||
 +          attr->task ||
 +          attr->context_switch)
 +              return true;
 +      return false;
 +}
 +
 +static void unaccount_pmu_sb_event(struct perf_event *event)
 +{
 +      if (is_sb_event(event))
 +              detach_sb_event(event);
 +}
 +
  static void unaccount_event_cpu(struct perf_event *event, int cpu)
  {
        if (event->parent)
@@@ -3769,8 -3728,6 +3769,8 @@@ static void unaccount_event(struct perf
        }
  
        unaccount_event_cpu(event, event->cpu);
 +
 +      unaccount_pmu_sb_event(event);
  }
  
  static void perf_sched_delayed(struct work_struct *work)
@@@ -5899,11 -5856,11 +5899,11 @@@ perf_event_read_event(struct perf_even
        perf_output_end(&handle);
  }
  
 -typedef void (perf_event_aux_output_cb)(struct perf_event *event, void *data);
 +typedef void (perf_iterate_f)(struct perf_event *event, void *data);
  
  static void
 -perf_event_aux_ctx(struct perf_event_context *ctx,
 -                 perf_event_aux_output_cb output,
 +perf_iterate_ctx(struct perf_event_context *ctx,
 +                 perf_iterate_f output,
                   void *data, bool all)
  {
        struct perf_event *event;
        }
  }
  
 -static void
 -perf_event_aux_task_ctx(perf_event_aux_output_cb output, void *data,
 -                      struct perf_event_context *task_ctx)
 +static void perf_iterate_sb_cpu(perf_iterate_f output, void *data)
  {
 -      rcu_read_lock();
 -      preempt_disable();
 -      perf_event_aux_ctx(task_ctx, output, data, false);
 -      preempt_enable();
 -      rcu_read_unlock();
 +      struct pmu_event_list *pel = this_cpu_ptr(&pmu_sb_events);
 +      struct perf_event *event;
 +
 +      list_for_each_entry_rcu(event, &pel->list, sb_list) {
 +              if (event->state < PERF_EVENT_STATE_INACTIVE)
 +                      continue;
 +              if (!event_filter_match(event))
 +                      continue;
 +              output(event, data);
 +      }
  }
  
 +/*
 + * Iterate all events that need to receive side-band events.
 + *
 + * For new callers; ensure that account_pmu_sb_event() includes
 + * your event, otherwise it might not get delivered.
 + */
  static void
 -perf_event_aux(perf_event_aux_output_cb output, void *data,
 +perf_iterate_sb(perf_iterate_f output, void *data,
               struct perf_event_context *task_ctx)
  {
 -      struct perf_cpu_context *cpuctx;
        struct perf_event_context *ctx;
 -      struct pmu *pmu;
        int ctxn;
  
 +      rcu_read_lock();
 +      preempt_disable();
 +
        /*
 -       * If we have task_ctx != NULL we only notify
 -       * the task context itself. The task_ctx is set
 -       * only for EXIT events before releasing task
 +       * If we have task_ctx != NULL we only notify the task context itself.
 +       * The task_ctx is set only for EXIT events before releasing task
         * context.
         */
        if (task_ctx) {
 -              perf_event_aux_task_ctx(output, data, task_ctx);
 -              return;
 +              perf_iterate_ctx(task_ctx, output, data, false);
 +              goto done;
        }
  
 -      rcu_read_lock();
 -      list_for_each_entry_rcu(pmu, &pmus, entry) {
 -              cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
 -              if (cpuctx->unique_pmu != pmu)
 -                      goto next;
 -              perf_event_aux_ctx(&cpuctx->ctx, output, data, false);
 -              ctxn = pmu->task_ctx_nr;
 -              if (ctxn < 0)
 -                      goto next;
 +      perf_iterate_sb_cpu(output, data);
 +
 +      for_each_task_context_nr(ctxn) {
                ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
                if (ctx)
 -                      perf_event_aux_ctx(ctx, output, data, false);
 -next:
 -              put_cpu_ptr(pmu->pmu_cpu_context);
 +                      perf_iterate_ctx(ctx, output, data, false);
        }
 +done:
 +      preempt_enable();
        rcu_read_unlock();
  }
  
@@@ -6017,7 -5971,7 +6017,7 @@@ void perf_event_exec(void
  
                perf_event_enable_on_exec(ctxn);
  
 -              perf_event_aux_ctx(ctx, perf_event_addr_filters_exec, NULL,
 +              perf_iterate_ctx(ctx, perf_event_addr_filters_exec, NULL,
                                   true);
        }
        rcu_read_unlock();
@@@ -6061,9 -6015,9 +6061,9 @@@ static int __perf_pmu_output_stop(void 
        };
  
        rcu_read_lock();
 -      perf_event_aux_ctx(&cpuctx->ctx, __perf_event_output_stop, &ro, false);
 +      perf_iterate_ctx(&cpuctx->ctx, __perf_event_output_stop, &ro, false);
        if (cpuctx->task_ctx)
 -              perf_event_aux_ctx(cpuctx->task_ctx, __perf_event_output_stop,
 +              perf_iterate_ctx(cpuctx->task_ctx, __perf_event_output_stop,
                                   &ro, false);
        rcu_read_unlock();
  
@@@ -6192,7 -6146,7 +6192,7 @@@ static void perf_event_task(struct task
                },
        };
  
 -      perf_event_aux(perf_event_task_output,
 +      perf_iterate_sb(perf_event_task_output,
                       &task_event,
                       task_ctx);
  }
@@@ -6271,7 -6225,7 +6271,7 @@@ static void perf_event_comm_event(struc
  
        comm_event->event_id.header.size = sizeof(comm_event->event_id) + size;
  
 -      perf_event_aux(perf_event_comm_output,
 +      perf_iterate_sb(perf_event_comm_output,
                       comm_event,
                       NULL);
  }
@@@ -6502,7 -6456,7 +6502,7 @@@ got_name
  
        mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size;
  
 -      perf_event_aux(perf_event_mmap_output,
 +      perf_iterate_sb(perf_event_mmap_output,
                       mmap_event,
                       NULL);
  
@@@ -6585,7 -6539,7 +6585,7 @@@ static void perf_addr_filters_adjust(st
                if (!ctx)
                        continue;
  
 -              perf_event_aux_ctx(ctx, __perf_addr_filters_adjust, vma, true);
 +              perf_iterate_ctx(ctx, __perf_addr_filters_adjust, vma, true);
        }
        rcu_read_unlock();
  }
@@@ -6772,7 -6726,7 +6772,7 @@@ static void perf_event_switch(struct ta
                },
        };
  
 -      perf_event_aux(perf_event_switch_output,
 +      perf_iterate_sb(perf_event_switch_output,
                       &switch_event,
                       NULL);
  }
@@@ -7146,7 -7100,7 +7146,7 @@@ int perf_swevent_get_recursion_context(
  }
  EXPORT_SYMBOL_GPL(perf_swevent_get_recursion_context);
  
inline void perf_swevent_put_recursion_context(int rctx)
+ void perf_swevent_put_recursion_context(int rctx)
  {
        struct swevent_htable *swhash = this_cpu_ptr(&swevent_htable);
  
@@@ -7408,7 -7362,26 +7408,26 @@@ static int perf_tp_event_match(struct p
        return 1;
  }
  
- void perf_tp_event(u64 addr, u64 count, void *record, int entry_size,
+ void perf_trace_run_bpf_submit(void *raw_data, int size, int rctx,
+                              struct trace_event_call *call, u64 count,
+                              struct pt_regs *regs, struct hlist_head *head,
+                              struct task_struct *task)
+ {
+       struct bpf_prog *prog = call->prog;
+       if (prog) {
+               *(struct pt_regs **)raw_data = regs;
+               if (!trace_call_bpf(prog, raw_data) || hlist_empty(head)) {
+                       perf_swevent_put_recursion_context(rctx);
+                       return;
+               }
+       }
+       perf_tp_event(call->event.type, count, raw_data, size, regs, head,
+                     rctx, task);
+ }
+ EXPORT_SYMBOL_GPL(perf_trace_run_bpf_submit);
+ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size,
                   struct pt_regs *regs, struct hlist_head *head, int rctx,
                   struct task_struct *task)
  {
                .data = record,
        };
  
-       perf_sample_data_init(&data, addr, 0);
+       perf_sample_data_init(&data, 0, 0);
        data.raw = &raw;
  
+       perf_trace_buf_update(record, event_type);
        hlist_for_each_entry_rcu(event, head, hlist_entry) {
                if (perf_tp_event_match(event, &data, regs))
                        perf_swevent_event(event, count, &data, regs);
@@@ -7507,6 -7482,7 +7528,7 @@@ static void perf_event_free_filter(stru
  
  static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)
  {
+       bool is_kprobe, is_tracepoint;
        struct bpf_prog *prog;
  
        if (event->attr.type != PERF_TYPE_TRACEPOINT)
        if (event->tp_event->prog)
                return -EEXIST;
  
-       if (!(event->tp_event->flags & TRACE_EVENT_FL_UKPROBE))
-               /* bpf programs can only be attached to u/kprobes */
+       is_kprobe = event->tp_event->flags & TRACE_EVENT_FL_UKPROBE;
+       is_tracepoint = event->tp_event->flags & TRACE_EVENT_FL_TRACEPOINT;
+       if (!is_kprobe && !is_tracepoint)
+               /* bpf programs can only be attached to u/kprobe or tracepoint */
                return -EINVAL;
  
        prog = bpf_prog_get(prog_fd);
        if (IS_ERR(prog))
                return PTR_ERR(prog);
  
-       if (prog->type != BPF_PROG_TYPE_KPROBE) {
+       if ((is_kprobe && prog->type != BPF_PROG_TYPE_KPROBE) ||
+           (is_tracepoint && prog->type != BPF_PROG_TYPE_TRACEPOINT)) {
                /* valid fd, but invalid bpf program type */
                bpf_prog_put(prog);
                return -EINVAL;
        }
  
+       if (is_tracepoint) {
+               int off = trace_event_get_offsets(event->tp_event);
+               if (prog->aux->max_ctx_offset > off) {
+                       bpf_prog_put(prog);
+                       return -EACCES;
+               }
+       }
        event->tp_event->prog = prog;
  
        return 0;
@@@ -8661,28 -8648,6 +8694,28 @@@ unlock
        return pmu;
  }
  
 +static void attach_sb_event(struct perf_event *event)
 +{
 +      struct pmu_event_list *pel = per_cpu_ptr(&pmu_sb_events, event->cpu);
 +
 +      raw_spin_lock(&pel->lock);
 +      list_add_rcu(&event->sb_list, &pel->list);
 +      raw_spin_unlock(&pel->lock);
 +}
 +
 +/*
 + * We keep a list of all !task (and therefore per-cpu) events
 + * that need to receive side-band records.
 + *
 + * This avoids having to scan all the various PMU per-cpu contexts
 + * looking for them.
 + */
 +static void account_pmu_sb_event(struct perf_event *event)
 +{
 +      if (is_sb_event(event))
 +              attach_sb_event(event);
 +}
 +
  static void account_event_cpu(struct perf_event *event, int cpu)
  {
        if (event->parent)
@@@ -8763,8 -8728,6 +8796,8 @@@ static void account_event(struct perf_e
  enabled:
  
        account_event_cpu(event, event->cpu);
 +
 +      account_pmu_sb_event(event);
  }
  
  /*
@@@ -8913,7 -8876,7 +8946,7 @@@ perf_event_alloc(struct perf_event_att
  
        if (!event->parent) {
                if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
 -                      err = get_callchain_buffers();
 +                      err = get_callchain_buffers(attr->sample_max_stack);
                        if (err)
                                goto err_addr_filters;
                }
@@@ -9235,9 -9198,6 +9268,9 @@@ SYSCALL_DEFINE5(perf_event_open
                        return -EINVAL;
        }
  
 +      if (!attr.sample_max_stack)
 +              attr.sample_max_stack = sysctl_perf_event_max_stack;
 +
        /*
         * In cgroup mode, the pid argument is used to pass the fd
         * opened to the cgroup directory in cgroupfs. The cpu argument
  
        if (is_sampling_event(event)) {
                if (event->pmu->capabilities & PERF_PMU_CAP_NO_INTERRUPT) {
 -                      err = -ENOTSUPP;
 +                      err = -EOPNOTSUPP;
                        goto err_alloc;
                }
        }
@@@ -10273,9 -10233,6 +10306,9 @@@ static void __init perf_event_init_all_
                swhash = &per_cpu(swevent_htable, cpu);
                mutex_init(&swhash->hlist_mutex);
                INIT_LIST_HEAD(&per_cpu(active_ctx_list, cpu));
 +
 +              INIT_LIST_HEAD(&per_cpu(pmu_sb_events.list, cpu));
 +              raw_spin_lock_init(&per_cpu(pmu_sb_events.lock, cpu));
        }
  }
  
diff --combined tools/perf/util/evsel.c
@@@ -572,8 -572,6 +572,8 @@@ void perf_evsel__config_callchain(struc
  
        perf_evsel__set_sample_bit(evsel, CALLCHAIN);
  
 +      attr->sample_max_stack = param->max_stack;
 +
        if (param->record_mode == CALLCHAIN_LBR) {
                if (!opts->branch_stack) {
                        if (attr->exclude_user) {
@@@ -637,8 -635,7 +637,8 @@@ static void apply_config_terms(struct p
        struct perf_event_attr *attr = &evsel->attr;
        struct callchain_param param;
        u32 dump_size = 0;
 -      char *callgraph_buf = NULL;
 +      int max_stack = 0;
 +      const char *callgraph_buf = NULL;
  
        /* callgraph default */
        param.record_mode = callchain_param.record_mode;
                case PERF_EVSEL__CONFIG_TERM_STACK_USER:
                        dump_size = term->val.stack_user;
                        break;
 +              case PERF_EVSEL__CONFIG_TERM_MAX_STACK:
 +                      max_stack = term->val.max_stack;
 +                      break;
                case PERF_EVSEL__CONFIG_TERM_INHERIT:
                        /*
                         * attr->inherit should has already been set by
        }
  
        /* User explicitly set per-event callgraph, clear the old setting and reset. */
 -      if ((callgraph_buf != NULL) || (dump_size > 0)) {
 +      if ((callgraph_buf != NULL) || (dump_size > 0) || max_stack) {
 +              if (max_stack) {
 +                      param.max_stack = max_stack;
 +                      if (callgraph_buf == NULL)
 +                              callgraph_buf = "fp";
 +              }
  
                /* parse callgraph parameters */
                if (callgraph_buf != NULL) {
@@@ -839,7 -828,7 +839,7 @@@ void perf_evsel__config(struct perf_evs
                perf_evsel__set_sample_bit(evsel, PERIOD);
  
        /*
-        * When the user explicitely disabled time don't force it here.
+        * When the user explicitly disabled time don't force it here.
         */
        if (opts->sample_time &&
            (!perf_missing_features.sample_id_all &&
@@@ -1340,7 -1329,6 +1340,7 @@@ int perf_event_attr__fprintf(FILE *fp, 
        PRINT_ATTRf(clockid, p_signed);
        PRINT_ATTRf(sample_regs_intr, p_hex);
        PRINT_ATTRf(aux_watermark, p_unsigned);
 +      PRINT_ATTRf(sample_max_stack, p_unsigned);
  
        return ret;
  }
@@@ -2384,9 -2372,6 +2384,9 @@@ int perf_evsel__open_strerror(struct pe
         "No such device - did you specify an out-of-range profile CPU?");
                break;
        case EOPNOTSUPP:
 +              if (evsel->attr.sample_period != 0)
 +                      return scnprintf(msg, size, "%s",
 +      "PMU Hardware doesn't support sampling/overflow-interrupts.");
                if (evsel->attr.precise_ip)
                        return scnprintf(msg, size, "%s",
        "\'precise\' request may not be supported. Try removing 'p' modifier.");
@@@ -900,7 -900,6 +900,7 @@@ static const char *config_term_names[__
        [PARSE_EVENTS__TERM_TYPE_STACKSIZE]             = "stack-size",
        [PARSE_EVENTS__TERM_TYPE_NOINHERIT]             = "no-inherit",
        [PARSE_EVENTS__TERM_TYPE_INHERIT]               = "inherit",
 +      [PARSE_EVENTS__TERM_TYPE_MAX_STACK]             = "max-stack",
  };
  
  static bool config_term_shrinked;
@@@ -996,9 -995,6 +996,9 @@@ do {                                                                          
        case PARSE_EVENTS__TERM_TYPE_NAME:
                CHECK_TYPE_VAL(STR);
                break;
 +      case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
 +              CHECK_TYPE_VAL(NUM);
 +              break;
        default:
                err->str = strdup("unknown term");
                err->idx = term->err_term;
@@@ -1044,7 -1040,6 +1044,7 @@@ static int config_term_tracepoint(struc
        case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
        case PARSE_EVENTS__TERM_TYPE_INHERIT:
        case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
 +      case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
                return config_term_common(attr, term, err);
        default:
                if (err) {
@@@ -1114,9 -1109,6 +1114,9 @@@ do {                                                            
                case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
                        ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 0 : 1);
                        break;
 +              case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
 +                      ADD_CONFIG_TERM(MAX_STACK, max_stack, term->val.num);
 +                      break;
                default:
                        break;
                }
@@@ -1657,7 -1649,7 +1657,7 @@@ static void parse_events_print_error(st
  
                buf = _buf;
  
-               /* We're cutting from the beggining. */
+               /* We're cutting from the beginning. */
                if (err->idx > max_err_idx)
                        cut = err->idx - max_err_idx;
  
@@@ -557,7 -557,7 +557,7 @@@ static u8 revbyte(u8 b
  
  /*
   * XXX this is hack in attempt to carry flags bitfield
-  * throught endian village. ABI says:
+  * through endian village. ABI says:
   *
   * Bit-fields are allocated from right to left (least to most significant)
   * on little-endian implementations and from left to right (most to least
@@@ -593,7 -593,6 +593,7 @@@ do {                                               
        if (bswap_safe(f, 0))                   \
                attr->f = bswap_##sz(attr->f);  \
  } while(0)
 +#define bswap_field_16(f) bswap_field(f, 16)
  #define bswap_field_32(f) bswap_field(f, 32)
  #define bswap_field_64(f) bswap_field(f, 64)
  
        bswap_field_64(sample_regs_user);
        bswap_field_32(sample_stack_user);
        bswap_field_32(aux_watermark);
 +      bswap_field_16(sample_max_stack);
  
        /*
         * After read_format are bitfields. Check read_format because