Merge commit '8700c95adb03' into timers/nohz
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / kernel / events / core.c
index dce6e13cf9d752a32a3d4c3eb39556de1a2fad31..6b41c1899a8b00acc0ca48ae30b0e8dfbdd2ad9d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/poll.h>
 #include <linux/slab.h>
 #include <linux/hash.h>
+#include <linux/tick.h>
 #include <linux/sysfs.h>
 #include <linux/dcache.h>
 #include <linux/percpu.h>
@@ -37,6 +38,7 @@
 #include <linux/ftrace_event.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/mm_types.h>
+#include <linux/cgroup.h>
 
 #include "internal.h"
 
@@ -233,6 +235,20 @@ static void perf_ctx_unlock(struct perf_cpu_context *cpuctx,
 
 #ifdef CONFIG_CGROUP_PERF
 
+/*
+ * perf_cgroup_info keeps track of time_enabled for a cgroup.
+ * This is a per-cpu dynamically allocated data structure.
+ */
+struct perf_cgroup_info {
+       u64                             time;
+       u64                             timestamp;
+};
+
+struct perf_cgroup {
+       struct cgroup_subsys_state      css;
+       struct perf_cgroup_info __percpu *info;
+};
+
 /*
  * Must ensure cgroup is pinned (css_get) before calling
  * this function. In other words, we cannot call this function
@@ -670,8 +686,12 @@ static void perf_pmu_rotate_start(struct pmu *pmu)
 
        WARN_ON(!irqs_disabled());
 
-       if (list_empty(&cpuctx->rotation_list))
+       if (list_empty(&cpuctx->rotation_list)) {
+               int was_empty = list_empty(head);
                list_add(&cpuctx->rotation_list, head);
+               if (was_empty)
+                       tick_nohz_full_kick();
+       }
 }
 
 static void get_ctx(struct perf_event_context *ctx)
@@ -976,9 +996,15 @@ static void perf_event__header_size(struct perf_event *event)
        if (sample_type & PERF_SAMPLE_PERIOD)
                size += sizeof(data->period);
 
+       if (sample_type & PERF_SAMPLE_WEIGHT)
+               size += sizeof(data->weight);
+
        if (sample_type & PERF_SAMPLE_READ)
                size += event->read_size;
 
+       if (sample_type & PERF_SAMPLE_DATA_SRC)
+               size += sizeof(data->data_src.val);
+
        event->header_size = size;
 }
 
@@ -2570,6 +2596,16 @@ done:
                list_del_init(&cpuctx->rotation_list);
 }
 
+#ifdef CONFIG_NO_HZ_FULL
+bool perf_event_can_stop_tick(void)
+{
+       if (list_empty(&__get_cpu_var(rotation_list)))
+               return true;
+       else
+               return false;
+}
+#endif
+
 void perf_event_task_tick(void)
 {
        struct list_head *head = &__get_cpu_var(rotation_list);
@@ -4193,6 +4229,12 @@ void perf_output_sample(struct perf_output_handle *handle,
                perf_output_sample_ustack(handle,
                                          data->stack_user_size,
                                          data->regs_user.regs);
+
+       if (sample_type & PERF_SAMPLE_WEIGHT)
+               perf_output_put(handle, data->weight);
+
+       if (sample_type & PERF_SAMPLE_DATA_SRC)
+               perf_output_put(handle, data->data_src.val);
 }
 
 void perf_prepare_sample(struct perf_event_header *header,
@@ -4782,6 +4824,9 @@ got_name:
        mmap_event->file_name = name;
        mmap_event->file_size = size;
 
+       if (!(vma->vm_flags & VM_EXEC))
+               mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA;
+
        mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size;
 
        rcu_read_lock();