Merge branch 'perf/x86' into perf/core, because it's ready
[cascardo/linux.git] / kernel / events / core.c
index 525062b..b01dfb6 100644 (file)
@@ -3587,7 +3587,7 @@ static void put_event(struct perf_event *event)
        ctx = perf_event_ctx_lock_nested(event, SINGLE_DEPTH_NESTING);
        WARN_ON_ONCE(ctx->parent_ctx);
        perf_remove_from_context(event, true);
-       mutex_unlock(&ctx->mutex);
+       perf_event_ctx_unlock(event, ctx);
 
        _free_event(event);
 }
@@ -4423,7 +4423,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
         * If we have rb pages ensure they're a power-of-two number, so we
         * can do bitmasks instead of modulo.
         */
-       if (!is_power_of_2(nr_pages))
+       if (nr_pages != 0 && !is_power_of_2(nr_pages))
                return -EINVAL;
 
        if (vma_size != PAGE_SIZE * (1 + nr_pages))
@@ -4570,6 +4570,13 @@ static void perf_pending_event(struct irq_work *entry)
 {
        struct perf_event *event = container_of(entry,
                        struct perf_event, pending);
+       int rctx;
+
+       rctx = perf_swevent_get_recursion_context();
+       /*
+        * If we 'fail' here, that's OK, it means recursion is already disabled
+        * and we won't recurse 'further'.
+        */
 
        if (event->pending_disable) {
                event->pending_disable = 0;
@@ -4580,6 +4587,9 @@ static void perf_pending_event(struct irq_work *entry)
                event->pending_wakeup = 0;
                perf_event_wakeup(event);
        }
+
+       if (rctx >= 0)
+               perf_swevent_put_recursion_context(rctx);
 }
 
 /*
@@ -8516,6 +8526,18 @@ void __init perf_event_init(void)
                     != 1024);
 }
 
+ssize_t perf_event_sysfs_show(struct device *dev, struct device_attribute *attr,
+                             char *page)
+{
+       struct perf_pmu_events_attr *pmu_attr =
+               container_of(attr, struct perf_pmu_events_attr, attr);
+
+       if (pmu_attr->event_str)
+               return sprintf(page, "%s\n", pmu_attr->event_str);
+
+       return 0;
+}
+
 static int __init perf_event_sysfs_init(void)
 {
        struct pmu *pmu;