]> Pileus Git - ~andy/linux/blobdiff - kernel/events/core.c
Merge tag 'late-dt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[~andy/linux] / kernel / events / core.c
index f5744010a8d2f980f1902279de41a866ceb00a37..56003c6edfd38c03e8dd523f1efb01d99bcf2e84 100644 (file)
@@ -119,7 +119,8 @@ static int cpu_function_call(int cpu, int (*func) (void *info), void *info)
 
 #define PERF_FLAG_ALL (PERF_FLAG_FD_NO_GROUP |\
                       PERF_FLAG_FD_OUTPUT  |\
-                      PERF_FLAG_PID_CGROUP)
+                      PERF_FLAG_PID_CGROUP |\
+                      PERF_FLAG_FD_CLOEXEC)
 
 /*
  * branch priv levels that need permission checks
@@ -3542,7 +3543,7 @@ static void perf_event_for_each(struct perf_event *event,
 static int perf_event_period(struct perf_event *event, u64 __user *arg)
 {
        struct perf_event_context *ctx = event->ctx;
-       int ret = 0;
+       int ret = 0, active;
        u64 value;
 
        if (!is_sampling_event(event))
@@ -3566,6 +3567,20 @@ static int perf_event_period(struct perf_event *event, u64 __user *arg)
                event->attr.sample_period = value;
                event->hw.sample_period = value;
        }
+
+       active = (event->state == PERF_EVENT_STATE_ACTIVE);
+       if (active) {
+               perf_pmu_disable(ctx->pmu);
+               event->pmu->stop(event, PERF_EF_UPDATE);
+       }
+
+       local64_set(&event->hw.period_left, 0);
+
+       if (active) {
+               event->pmu->start(event, PERF_EF_RELOAD);
+               perf_pmu_enable(ctx->pmu);
+       }
+
 unlock:
        raw_spin_unlock_irq(&ctx->lock);
 
@@ -6670,6 +6685,9 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
        INIT_LIST_HEAD(&event->event_entry);
        INIT_LIST_HEAD(&event->sibling_list);
        INIT_LIST_HEAD(&event->rb_entry);
+       INIT_LIST_HEAD(&event->active_entry);
+       INIT_HLIST_NODE(&event->hlist_entry);
+
 
        init_waitqueue_head(&event->waitq);
        init_irq_work(&event->pending, perf_pending_event);
@@ -6980,6 +6998,7 @@ SYSCALL_DEFINE5(perf_event_open,
        int event_fd;
        int move_group = 0;
        int err;
+       int f_flags = O_RDWR;
 
        /* for future expandability... */
        if (flags & ~PERF_FLAG_ALL)
@@ -7008,7 +7027,10 @@ SYSCALL_DEFINE5(perf_event_open,
        if ((flags & PERF_FLAG_PID_CGROUP) && (pid == -1 || cpu == -1))
                return -EINVAL;
 
-       event_fd = get_unused_fd();
+       if (flags & PERF_FLAG_FD_CLOEXEC)
+               f_flags |= O_CLOEXEC;
+
+       event_fd = get_unused_fd_flags(f_flags);
        if (event_fd < 0)
                return event_fd;
 
@@ -7130,7 +7152,8 @@ SYSCALL_DEFINE5(perf_event_open,
                        goto err_context;
        }
 
-       event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR);
+       event_file = anon_inode_getfile("[perf_event]", &perf_fops, event,
+                                       f_flags);
        if (IS_ERR(event_file)) {
                err = PTR_ERR(event_file);
                goto err_context;