From 5208d9cda6b7e01f5057aad59d2dfe3a3a9dcba8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 4 Nov 2011 08:16:58 -0200 Subject: [PATCH] --- yaml --- r: 276390 b: refs/heads/master c: 0e2a5f10fb550835e199a3b56a80ed88232188e9 h: refs/heads/master v: v3 --- [refs] | 2 +- .../arch/x86/kernel/cpu/perf_event_amd_ibs.c | 29 +++---- trunk/arch/x86/kernel/cpu/perf_event_intel.c | 8 -- trunk/include/linux/perf_event.h | 1 - trunk/kernel/events/core.c | 86 +------------------ trunk/kernel/events/internal.h | 3 - trunk/kernel/events/ring_buffer.c | 3 - trunk/tools/perf/util/evsel.c | 10 +++ trunk/tools/perf/util/hist.c | 10 --- trunk/tools/perf/util/hist.h | 2 - 10 files changed, 24 insertions(+), 130 deletions(-) diff --git a/[refs] b/[refs] index 4edd129f7db2..d0cf9001e15d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 10c6db110d0eb4466b59812c49088ab56218fc2e +refs/heads/master: 0e2a5f10fb550835e199a3b56a80ed88232188e9 diff --git a/trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c index 3b8a2d30d14e..ab6343d21825 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c @@ -199,7 +199,8 @@ static int force_ibs_eilvt_setup(void) goto out; } - pr_info("IBS: LVT offset %d assigned\n", offset); + pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset); + pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); return 0; out: @@ -264,23 +265,19 @@ perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *h static __init int amd_ibs_init(void) { u32 caps; - int ret = -EINVAL; + int ret; caps = __get_ibs_caps(); if (!caps) return -ENODEV; /* ibs not supported by the cpu */ - /* - * Force LVT offset assignment for family 10h: The offsets are - * not assigned by the BIOS for this family, so the OS is - * responsible for doing it. If the OS assignment fails, fall - * back to BIOS settings and try to setup this. - */ - if (boot_cpu_data.x86 == 0x10) - force_ibs_eilvt_setup(); - - if (!ibs_eilvt_valid()) - goto out; + if (!ibs_eilvt_valid()) { + ret = force_ibs_eilvt_setup(); + if (ret) { + pr_err("Failed to setup IBS, %d\n", ret); + return ret; + } + } get_online_cpus(); ibs_caps = caps; @@ -290,11 +287,7 @@ static __init int amd_ibs_init(void) smp_call_function(setup_APIC_ibs, NULL, 1); put_online_cpus(); - ret = perf_event_ibs_init(); -out: - if (ret) - pr_err("Failed to setup IBS, %d\n", ret); - return ret; + return perf_event_ibs_init(); } /* Since we need the pci subsystem to init ibs we can't do this earlier: */ diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c index 8d601b18bf9f..2be5ebe99872 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c @@ -1545,13 +1545,6 @@ static void intel_clovertown_quirks(void) x86_pmu.pebs_constraints = NULL; } -static void intel_sandybridge_quirks(void) -{ - printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); - x86_pmu.pebs = 0; - x86_pmu.pebs_constraints = NULL; -} - __init int intel_pmu_init(void) { union cpuid10_edx edx; @@ -1701,7 +1694,6 @@ __init int intel_pmu_init(void) break; case 42: /* SandyBridge */ - x86_pmu.quirks = intel_sandybridge_quirks; case 45: /* SandyBridge, "Romely-EP" */ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); diff --git a/trunk/include/linux/perf_event.h b/trunk/include/linux/perf_event.h index b1f89122bf6a..1e9ebe5e0091 100644 --- a/trunk/include/linux/perf_event.h +++ b/trunk/include/linux/perf_event.h @@ -822,7 +822,6 @@ struct perf_event { int mmap_locked; struct user_struct *mmap_user; struct ring_buffer *rb; - struct list_head rb_entry; /* poll related */ wait_queue_head_t waitq; diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index 600c1629b64d..b0c1186fd97b 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -185,9 +185,6 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, static void update_context_time(struct perf_event_context *ctx); static u64 perf_event_time(struct perf_event *event); -static void ring_buffer_attach(struct perf_event *event, - struct ring_buffer *rb); - void __weak perf_event_print_debug(void) { } extern __weak const char *perf_pmu_name(void) @@ -3194,33 +3191,12 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) struct ring_buffer *rb; unsigned int events = POLL_HUP; - /* - * Race between perf_event_set_output() and perf_poll(): perf_poll() - * grabs the rb reference but perf_event_set_output() overrides it. - * Here is the timeline for two threads T1, T2: - * t0: T1, rb = rcu_dereference(event->rb) - * t1: T2, old_rb = event->rb - * t2: T2, event->rb = new rb - * t3: T2, ring_buffer_detach(old_rb) - * t4: T1, ring_buffer_attach(rb1) - * t5: T1, poll_wait(event->waitq) - * - * To avoid this problem, we grab mmap_mutex in perf_poll() - * thereby ensuring that the assignment of the new ring buffer - * and the detachment of the old buffer appear atomic to perf_poll() - */ - mutex_lock(&event->mmap_mutex); - rcu_read_lock(); rb = rcu_dereference(event->rb); - if (rb) { - ring_buffer_attach(event, rb); + if (rb) events = atomic_xchg(&rb->poll, 0); - } rcu_read_unlock(); - mutex_unlock(&event->mmap_mutex); - poll_wait(file, &event->waitq, wait); return events; @@ -3521,49 +3497,6 @@ static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) return ret; } -static void ring_buffer_attach(struct perf_event *event, - struct ring_buffer *rb) -{ - unsigned long flags; - - if (!list_empty(&event->rb_entry)) - return; - - spin_lock_irqsave(&rb->event_lock, flags); - if (!list_empty(&event->rb_entry)) - goto unlock; - - list_add(&event->rb_entry, &rb->event_list); -unlock: - spin_unlock_irqrestore(&rb->event_lock, flags); -} - -static void ring_buffer_detach(struct perf_event *event, - struct ring_buffer *rb) -{ - unsigned long flags; - - if (list_empty(&event->rb_entry)) - return; - - spin_lock_irqsave(&rb->event_lock, flags); - list_del_init(&event->rb_entry); - wake_up_all(&event->waitq); - spin_unlock_irqrestore(&rb->event_lock, flags); -} - -static void ring_buffer_wakeup(struct perf_event *event) -{ - struct ring_buffer *rb; - - rcu_read_lock(); - rb = rcu_dereference(event->rb); - list_for_each_entry_rcu(event, &rb->event_list, rb_entry) { - wake_up_all(&event->waitq); - } - rcu_read_unlock(); -} - static void rb_free_rcu(struct rcu_head *rcu_head) { struct ring_buffer *rb; @@ -3589,19 +3522,9 @@ static struct ring_buffer *ring_buffer_get(struct perf_event *event) static void ring_buffer_put(struct ring_buffer *rb) { - struct perf_event *event, *n; - unsigned long flags; - if (!atomic_dec_and_test(&rb->refcount)) return; - spin_lock_irqsave(&rb->event_lock, flags); - list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) { - list_del_init(&event->rb_entry); - wake_up_all(&event->waitq); - } - spin_unlock_irqrestore(&rb->event_lock, flags); - call_rcu(&rb->rcu_head, rb_free_rcu); } @@ -3624,7 +3547,6 @@ static void perf_mmap_close(struct vm_area_struct *vma) atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm); vma->vm_mm->pinned_vm -= event->mmap_locked; rcu_assign_pointer(event->rb, NULL); - ring_buffer_detach(event, rb); mutex_unlock(&event->mmap_mutex); ring_buffer_put(rb); @@ -3779,7 +3701,7 @@ static const struct file_operations perf_fops = { void perf_event_wakeup(struct perf_event *event) { - ring_buffer_wakeup(event); + wake_up_all(&event->waitq); if (event->pending_kill) { kill_fasync(&event->fasync, SIGIO, event->pending_kill); @@ -5901,8 +5823,6 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, INIT_LIST_HEAD(&event->group_entry); INIT_LIST_HEAD(&event->event_entry); INIT_LIST_HEAD(&event->sibling_list); - INIT_LIST_HEAD(&event->rb_entry); - init_waitqueue_head(&event->waitq); init_irq_work(&event->pending, perf_pending_event); @@ -6109,8 +6029,6 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event) old_rb = event->rb; rcu_assign_pointer(event->rb, rb); - if (old_rb) - ring_buffer_detach(event, old_rb); ret = 0; unlock: mutex_unlock(&event->mmap_mutex); diff --git a/trunk/kernel/events/internal.h b/trunk/kernel/events/internal.h index 64568a699375..09097dd8116c 100644 --- a/trunk/kernel/events/internal.h +++ b/trunk/kernel/events/internal.h @@ -22,9 +22,6 @@ struct ring_buffer { local_t lost; /* nr records lost */ long watermark; /* wakeup watermark */ - /* poll crap */ - spinlock_t event_lock; - struct list_head event_list; struct perf_event_mmap_page *user_page; void *data_pages[0]; diff --git a/trunk/kernel/events/ring_buffer.c b/trunk/kernel/events/ring_buffer.c index 7f3011c6b57f..a2a29205cc0f 100644 --- a/trunk/kernel/events/ring_buffer.c +++ b/trunk/kernel/events/ring_buffer.c @@ -209,9 +209,6 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags) rb->writable = 1; atomic_set(&rb->refcount, 1); - - INIT_LIST_HEAD(&rb->event_list); - spin_lock_init(&rb->event_lock); } #ifndef CONFIG_PERF_USE_VMALLOC diff --git a/trunk/tools/perf/util/evsel.c b/trunk/tools/perf/util/evsel.c index e42626422587..d7915d4e77cb 100644 --- a/trunk/tools/perf/util/evsel.c +++ b/trunk/tools/perf/util/evsel.c @@ -34,6 +34,16 @@ int __perf_evsel__sample_size(u64 sample_type) return size; } +static void hists__init(struct hists *hists) +{ + memset(hists, 0, sizeof(*hists)); + hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; + hists->entries_in = &hists->entries_in_array[0]; + hists->entries_collapsed = RB_ROOT; + hists->entries = RB_ROOT; + pthread_mutex_init(&hists->lock, NULL); +} + void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr, int idx) { diff --git a/trunk/tools/perf/util/hist.c b/trunk/tools/perf/util/hist.c index a36a3fa81ffb..abef2703cd24 100644 --- a/trunk/tools/perf/util/hist.c +++ b/trunk/tools/perf/util/hist.c @@ -1211,13 +1211,3 @@ size_t hists__fprintf_nr_events(struct hists *hists, FILE *fp) return ret; } - -void hists__init(struct hists *hists) -{ - memset(hists, 0, sizeof(*hists)); - hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; - hists->entries_in = &hists->entries_in_array[0]; - hists->entries_collapsed = RB_ROOT; - hists->entries = RB_ROOT; - pthread_mutex_init(&hists->lock, NULL); -} diff --git a/trunk/tools/perf/util/hist.h b/trunk/tools/perf/util/hist.h index c86c1d27bd1e..89289c8e935e 100644 --- a/trunk/tools/perf/util/hist.h +++ b/trunk/tools/perf/util/hist.h @@ -63,8 +63,6 @@ struct hists { struct callchain_cursor callchain_cursor; }; -void hists__init(struct hists *hists); - struct hist_entry *__hists__add_entry(struct hists *self, struct addr_location *al, struct symbol *parent, u64 period);