PERF_SAMPLE_ID                          = 1U << 6,
        PERF_SAMPLE_CPU                         = 1U << 7,
        PERF_SAMPLE_PERIOD                      = 1U << 8,
+       PERF_SAMPLE_STREAM_ID                   = 1U << 9,
 
-       PERF_SAMPLE_MAX = 1U << 9,              /* non-ABI */
+       PERF_SAMPLE_MAX = 1U << 10,             /* non-ABI */
 };
 
 /*
         *      struct perf_event_header        header;
         *      u64                             time;
         *      u64                             id;
-        *      u64                             sample_period;
-        * };
-        */
-       PERF_EVENT_PERIOD               = 4,
-
-       /*
-        * struct {
-        *      struct perf_event_header        header;
-        *      u64                             time;
-        *      u64                             id;
+        *      u64                             stream_id;
         * };
         */
        PERF_EVENT_THROTTLE             = 5,
         *      { u64                   time;     } && PERF_SAMPLE_TIME
         *      { u64                   addr;     } && PERF_SAMPLE_ADDR
         *      { u64                   id;       } && PERF_SAMPLE_ID
+        *      { u64                   stream_id;} && PERF_SAMPLE_STREAM_ID
         *      { u32                   cpu, res; } && PERF_SAMPLE_CPU
         *      { u64                   period;   } && PERF_SAMPLE_PERIOD
         *
 
        }
 }
 
+/*
+ * If we inherit counters we want to return the parent counter id
+ * to userspace.
+ */
+static u64 primary_counter_id(struct perf_counter *counter)
+{
+       u64 id = counter->id;
+
+       if (counter->parent)
+               id = counter->parent->id;
+
+       return id;
+}
+
 /*
  * Get the perf_counter_context for a task and lock it.
  * This has to cope with with the fact that until it is locked,
 #define MAX_INTERRUPTS (~0ULL)
 
 static void perf_log_throttle(struct perf_counter *counter, int enable);
-static void perf_log_period(struct perf_counter *counter, u64 period);
 
 static void perf_adjust_period(struct perf_counter *counter, u64 events)
 {
        if (!sample_period)
                sample_period = 1;
 
-       perf_log_period(counter, sample_period);
-
        hwc->sample_period = sample_period;
 }
 
                values[n++] = counter->total_time_running +
                        atomic64_read(&counter->child_total_time_running);
        if (counter->attr.read_format & PERF_FORMAT_ID)
-               values[n++] = counter->id;
+               values[n++] = primary_counter_id(counter);
        mutex_unlock(&counter->child_mutex);
 
        if (count < n * sizeof(u64))
 
                counter->attr.sample_freq = value;
        } else {
-               perf_log_period(counter, value);
-
                counter->attr.sample_period = value;
                counter->hw.sample_period = value;
        }
        if (sample_type & PERF_SAMPLE_ID)
                header.size += sizeof(u64);
 
+       if (sample_type & PERF_SAMPLE_STREAM_ID)
+               header.size += sizeof(u64);
+
        if (sample_type & PERF_SAMPLE_CPU) {
                header.size += sizeof(cpu_entry);
 
        if (sample_type & PERF_SAMPLE_ADDR)
                perf_output_put(&handle, data->addr);
 
-       if (sample_type & PERF_SAMPLE_ID)
+       if (sample_type & PERF_SAMPLE_ID) {
+               u64 id = primary_counter_id(counter);
+
+               perf_output_put(&handle, id);
+       }
+
+       if (sample_type & PERF_SAMPLE_STREAM_ID)
                perf_output_put(&handle, counter->id);
 
        if (sample_type & PERF_SAMPLE_CPU)
                        if (sub != counter)
                                sub->pmu->read(sub);
 
-                       group_entry.id = sub->id;
+                       group_entry.id = primary_counter_id(sub);
                        group_entry.counter = atomic64_read(&sub->count);
 
                        perf_output_put(&handle, group_entry);
        }
 
        if (counter->attr.read_format & PERF_FORMAT_ID) {
-               u64 id;
-
                event.header.size += sizeof(u64);
-               if (counter->parent)
-                       id = counter->parent->id;
-               else
-                       id = counter->id;
-
-               event.format[i++] = id;
+               event.format[i++] = primary_counter_id(counter);
        }
 
        ret = perf_output_begin(&handle, counter, event.header.size, 0, 0);
        perf_counter_mmap_event(&mmap_event);
 }
 
-/*
- * Log sample_period changes so that analyzing tools can re-normalize the
- * event flow.
- */
-
-struct freq_event {
-       struct perf_event_header        header;
-       u64                             time;
-       u64                             id;
-       u64                             period;
-};
-
-static void perf_log_period(struct perf_counter *counter, u64 period)
-{
-       struct perf_output_handle handle;
-       struct freq_event event;
-       int ret;
-
-       if (counter->hw.sample_period == period)
-               return;
-
-       if (counter->attr.sample_type & PERF_SAMPLE_PERIOD)
-               return;
-
-       event = (struct freq_event) {
-               .header = {
-                       .type = PERF_EVENT_PERIOD,
-                       .misc = 0,
-                       .size = sizeof(event),
-               },
-               .time = sched_clock(),
-               .id = counter->id,
-               .period = period,
-       };
-
-       ret = perf_output_begin(&handle, counter, sizeof(event), 1, 0);
-       if (ret)
-               return;
-
-       perf_output_put(&handle, event);
-       perf_output_end(&handle);
-}
-
 /*
  * IRQ throttle logging
  */
                struct perf_event_header        header;
                u64                             time;
                u64                             id;
+               u64                             stream_id;
        } throttle_event = {
                .header = {
                        .type = PERF_EVENT_THROTTLE + 1,
                        .misc = 0,
                        .size = sizeof(throttle_event),
                },
-               .time   = sched_clock(),
-               .id     = counter->id,
+               .time           = sched_clock(),
+               .id             = primary_counter_id(counter),
+               .stream_id      = counter->id,
        };
 
        ret = perf_output_begin(&handle, counter, sizeof(throttle_event), 1, 0);
 
        u32 pid, ppid;
 };
 
-struct period_event {
-       struct perf_event_header header;
-       u64 time;
-       u64 id;
-       u64 sample_period;
-};
-
 typedef union event_union {
        struct perf_event_header        header;
        struct ip_event                 ip;
        struct mmap_event               mmap;
        struct comm_event               comm;
        struct fork_event               fork;
-       struct period_event             period;
 } event_t;
 
 
        return 0;
 }
 
-static int
-process_period_event(event_t *event, unsigned long offset, unsigned long head)
-{
-       dprintf("%p [%p]: PERF_EVENT_PERIOD: time:%Ld, id:%Ld: period:%Ld\n",
-               (void *)(offset + head),
-               (void *)(long)(event->header.size),
-               event->period.time,
-               event->period.id,
-               event->period.sample_period);
-
-       return 0;
-}
-
 static int
 process_event(event_t *event, unsigned long offset, unsigned long head)
 {
 
        case PERF_EVENT_FORK:
                return process_fork_event(event, offset, head);
-
-       case PERF_EVENT_PERIOD:
-               return process_period_event(event, offset, head);
        /*
         * We dont process them right now but they are fine:
         */
 
        u32 pid, ppid;
 };
 
-struct period_event {
-       struct perf_event_header header;
-       u64 time;
-       u64 id;
-       u64 sample_period;
-};
-
 struct lost_event {
        struct perf_event_header header;
        u64 id;
        struct mmap_event               mmap;
        struct comm_event               comm;
        struct fork_event               fork;
-       struct period_event             period;
        struct lost_event               lost;
        struct read_event               read;
 } event_t;
        return 0;
 }
 
-static int
-process_period_event(event_t *event, unsigned long offset, unsigned long head)
-{
-       dprintf("%p [%p]: PERF_EVENT_PERIOD: time:%Ld, id:%Ld: period:%Ld\n",
-               (void *)(offset + head),
-               (void *)(long)(event->header.size),
-               event->period.time,
-               event->period.id,
-               event->period.sample_period);
-
-       return 0;
-}
-
 static int
 process_lost_event(event_t *event, unsigned long offset, unsigned long head)
 {
        case PERF_EVENT_FORK:
                return process_fork_event(event, offset, head);
 
-       case PERF_EVENT_PERIOD:
-               return process_period_event(event, offset, head);
-
        case PERF_EVENT_LOST:
                return process_lost_event(event, offset, head);