Merge branch 'stable/bug-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / x86 / kernel / cpu / perf_event_amd.c
1 #ifdef CONFIG_CPU_SUP_AMD
2
3 static __initconst const u64 amd_hw_cache_event_ids
4                                 [PERF_COUNT_HW_CACHE_MAX]
5                                 [PERF_COUNT_HW_CACHE_OP_MAX]
6                                 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
7 {
8  [ C(L1D) ] = {
9         [ C(OP_READ) ] = {
10                 [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
11                 [ C(RESULT_MISS)   ] = 0x0041, /* Data Cache Misses          */
12         },
13         [ C(OP_WRITE) ] = {
14                 [ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
15                 [ C(RESULT_MISS)   ] = 0,
16         },
17         [ C(OP_PREFETCH) ] = {
18                 [ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts  */
19                 [ C(RESULT_MISS)   ] = 0x0167, /* Data Prefetcher :cancelled */
20         },
21  },
22  [ C(L1I ) ] = {
23         [ C(OP_READ) ] = {
24                 [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches  */
25                 [ C(RESULT_MISS)   ] = 0x0081, /* Instruction cache misses   */
26         },
27         [ C(OP_WRITE) ] = {
28                 [ C(RESULT_ACCESS) ] = -1,
29                 [ C(RESULT_MISS)   ] = -1,
30         },
31         [ C(OP_PREFETCH) ] = {
32                 [ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
33                 [ C(RESULT_MISS)   ] = 0,
34         },
35  },
36  [ C(LL  ) ] = {
37         [ C(OP_READ) ] = {
38                 [ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
39                 [ C(RESULT_MISS)   ] = 0x037E, /* L2 Cache Misses : IC+DC     */
40         },
41         [ C(OP_WRITE) ] = {
42                 [ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback           */
43                 [ C(RESULT_MISS)   ] = 0,
44         },
45         [ C(OP_PREFETCH) ] = {
46                 [ C(RESULT_ACCESS) ] = 0,
47                 [ C(RESULT_MISS)   ] = 0,
48         },
49  },
50  [ C(DTLB) ] = {
51         [ C(OP_READ) ] = {
52                 [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
53                 [ C(RESULT_MISS)   ] = 0x0746, /* L1_DTLB_AND_L2_DLTB_MISS.ALL */
54         },
55         [ C(OP_WRITE) ] = {
56                 [ C(RESULT_ACCESS) ] = 0,
57                 [ C(RESULT_MISS)   ] = 0,
58         },
59         [ C(OP_PREFETCH) ] = {
60                 [ C(RESULT_ACCESS) ] = 0,
61                 [ C(RESULT_MISS)   ] = 0,
62         },
63  },
64  [ C(ITLB) ] = {
65         [ C(OP_READ) ] = {
66                 [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes        */
67                 [ C(RESULT_MISS)   ] = 0x0385, /* L1_ITLB_AND_L2_ITLB_MISS.ALL */
68         },
69         [ C(OP_WRITE) ] = {
70                 [ C(RESULT_ACCESS) ] = -1,
71                 [ C(RESULT_MISS)   ] = -1,
72         },
73         [ C(OP_PREFETCH) ] = {
74                 [ C(RESULT_ACCESS) ] = -1,
75                 [ C(RESULT_MISS)   ] = -1,
76         },
77  },
78  [ C(BPU ) ] = {
79         [ C(OP_READ) ] = {
80                 [ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr.      */
81                 [ C(RESULT_MISS)   ] = 0x00c3, /* Retired Mispredicted BI    */
82         },
83         [ C(OP_WRITE) ] = {
84                 [ C(RESULT_ACCESS) ] = -1,
85                 [ C(RESULT_MISS)   ] = -1,
86         },
87         [ C(OP_PREFETCH) ] = {
88                 [ C(RESULT_ACCESS) ] = -1,
89                 [ C(RESULT_MISS)   ] = -1,
90         },
91  },
92 };
93
94 /*
95  * AMD Performance Monitor K7 and later.
96  */
97 static const u64 amd_perfmon_event_map[] =
98 {
99   [PERF_COUNT_HW_CPU_CYCLES]            = 0x0076,
100   [PERF_COUNT_HW_INSTRUCTIONS]          = 0x00c0,
101   [PERF_COUNT_HW_CACHE_REFERENCES]      = 0x0080,
102   [PERF_COUNT_HW_CACHE_MISSES]          = 0x0081,
103   [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]   = 0x00c2,
104   [PERF_COUNT_HW_BRANCH_MISSES]         = 0x00c3,
105 };
106
107 static u64 amd_pmu_event_map(int hw_event)
108 {
109         return amd_perfmon_event_map[hw_event];
110 }
111
112 static int amd_pmu_hw_config(struct perf_event *event)
113 {
114         int ret = x86_pmu_hw_config(event);
115
116         if (ret)
117                 return ret;
118
119         if (event->attr.type != PERF_TYPE_RAW)
120                 return 0;
121
122         event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK;
123
124         return 0;
125 }
126
127 /*
128  * AMD64 events are detected based on their event codes.
129  */
130 static inline int amd_is_nb_event(struct hw_perf_event *hwc)
131 {
132         return (hwc->config & 0xe0) == 0xe0;
133 }
134
135 static inline int amd_has_nb(struct cpu_hw_events *cpuc)
136 {
137         struct amd_nb *nb = cpuc->amd_nb;
138
139         return nb && nb->nb_id != -1;
140 }
141
142 static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
143                                       struct perf_event *event)
144 {
145         struct hw_perf_event *hwc = &event->hw;
146         struct amd_nb *nb = cpuc->amd_nb;
147         int i;
148
149         /*
150          * only care about NB events
151          */
152         if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc)))
153                 return;
154
155         /*
156          * need to scan whole list because event may not have
157          * been assigned during scheduling
158          *
159          * no race condition possible because event can only
160          * be removed on one CPU at a time AND PMU is disabled
161          * when we come here
162          */
163         for (i = 0; i < x86_pmu.num_counters; i++) {
164                 if (nb->owners[i] == event) {
165                         cmpxchg(nb->owners+i, event, NULL);
166                         break;
167                 }
168         }
169 }
170
171  /*
172   * AMD64 NorthBridge events need special treatment because
173   * counter access needs to be synchronized across all cores
174   * of a package. Refer to BKDG section 3.12
175   *
176   * NB events are events measuring L3 cache, Hypertransport
177   * traffic. They are identified by an event code >= 0xe00.
178   * They measure events on the NorthBride which is shared
179   * by all cores on a package. NB events are counted on a
180   * shared set of counters. When a NB event is programmed
181   * in a counter, the data actually comes from a shared
182   * counter. Thus, access to those counters needs to be
183   * synchronized.
184   *
185   * We implement the synchronization such that no two cores
186   * can be measuring NB events using the same counters. Thus,
187   * we maintain a per-NB allocation table. The available slot
188   * is propagated using the event_constraint structure.
189   *
190   * We provide only one choice for each NB event based on
191   * the fact that only NB events have restrictions. Consequently,
192   * if a counter is available, there is a guarantee the NB event
193   * will be assigned to it. If no slot is available, an empty
194   * constraint is returned and scheduling will eventually fail
195   * for this event.
196   *
197   * Note that all cores attached the same NB compete for the same
198   * counters to host NB events, this is why we use atomic ops. Some
199   * multi-chip CPUs may have more than one NB.
200   *
201   * Given that resources are allocated (cmpxchg), they must be
202   * eventually freed for others to use. This is accomplished by
203   * calling amd_put_event_constraints().
204   *
205   * Non NB events are not impacted by this restriction.
206   */
207 static struct event_constraint *
208 amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
209 {
210         struct hw_perf_event *hwc = &event->hw;
211         struct amd_nb *nb = cpuc->amd_nb;
212         struct perf_event *old = NULL;
213         int max = x86_pmu.num_counters;
214         int i, j, k = -1;
215
216         /*
217          * if not NB event or no NB, then no constraints
218          */
219         if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc)))
220                 return &unconstrained;
221
222         /*
223          * detect if already present, if so reuse
224          *
225          * cannot merge with actual allocation
226          * because of possible holes
227          *
228          * event can already be present yet not assigned (in hwc->idx)
229          * because of successive calls to x86_schedule_events() from
230          * hw_perf_group_sched_in() without hw_perf_enable()
231          */
232         for (i = 0; i < max; i++) {
233                 /*
234                  * keep track of first free slot
235                  */
236                 if (k == -1 && !nb->owners[i])
237                         k = i;
238
239                 /* already present, reuse */
240                 if (nb->owners[i] == event)
241                         goto done;
242         }
243         /*
244          * not present, so grab a new slot
245          * starting either at:
246          */
247         if (hwc->idx != -1) {
248                 /* previous assignment */
249                 i = hwc->idx;
250         } else if (k != -1) {
251                 /* start from free slot found */
252                 i = k;
253         } else {
254                 /*
255                  * event not found, no slot found in
256                  * first pass, try again from the
257                  * beginning
258                  */
259                 i = 0;
260         }
261         j = i;
262         do {
263                 old = cmpxchg(nb->owners+i, NULL, event);
264                 if (!old)
265                         break;
266                 if (++i == max)
267                         i = 0;
268         } while (i != j);
269 done:
270         if (!old)
271                 return &nb->event_constraints[i];
272
273         return &emptyconstraint;
274 }
275
276 static struct amd_nb *amd_alloc_nb(int cpu)
277 {
278         struct amd_nb *nb;
279         int i;
280
281         nb = kmalloc_node(sizeof(struct amd_nb), GFP_KERNEL | __GFP_ZERO,
282                           cpu_to_node(cpu));
283         if (!nb)
284                 return NULL;
285
286         nb->nb_id = -1;
287
288         /*
289          * initialize all possible NB constraints
290          */
291         for (i = 0; i < x86_pmu.num_counters; i++) {
292                 __set_bit(i, nb->event_constraints[i].idxmsk);
293                 nb->event_constraints[i].weight = 1;
294         }
295         return nb;
296 }
297
298 static int amd_pmu_cpu_prepare(int cpu)
299 {
300         struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
301
302         WARN_ON_ONCE(cpuc->amd_nb);
303
304         if (boot_cpu_data.x86_max_cores < 2)
305                 return NOTIFY_OK;
306
307         cpuc->amd_nb = amd_alloc_nb(cpu);
308         if (!cpuc->amd_nb)
309                 return NOTIFY_BAD;
310
311         return NOTIFY_OK;
312 }
313
314 static void amd_pmu_cpu_starting(int cpu)
315 {
316         struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
317         struct amd_nb *nb;
318         int i, nb_id;
319
320         if (boot_cpu_data.x86_max_cores < 2)
321                 return;
322
323         nb_id = amd_get_nb_id(cpu);
324         WARN_ON_ONCE(nb_id == BAD_APICID);
325
326         for_each_online_cpu(i) {
327                 nb = per_cpu(cpu_hw_events, i).amd_nb;
328                 if (WARN_ON_ONCE(!nb))
329                         continue;
330
331                 if (nb->nb_id == nb_id) {
332                         kfree(cpuc->amd_nb);
333                         cpuc->amd_nb = nb;
334                         break;
335                 }
336         }
337
338         cpuc->amd_nb->nb_id = nb_id;
339         cpuc->amd_nb->refcnt++;
340 }
341
342 static void amd_pmu_cpu_dead(int cpu)
343 {
344         struct cpu_hw_events *cpuhw;
345
346         if (boot_cpu_data.x86_max_cores < 2)
347                 return;
348
349         cpuhw = &per_cpu(cpu_hw_events, cpu);
350
351         if (cpuhw->amd_nb) {
352                 struct amd_nb *nb = cpuhw->amd_nb;
353
354                 if (nb->nb_id == -1 || --nb->refcnt == 0)
355                         kfree(nb);
356
357                 cpuhw->amd_nb = NULL;
358         }
359 }
360
361 static __initconst const struct x86_pmu amd_pmu = {
362         .name                   = "AMD",
363         .handle_irq             = x86_pmu_handle_irq,
364         .disable_all            = x86_pmu_disable_all,
365         .enable_all             = x86_pmu_enable_all,
366         .enable                 = x86_pmu_enable_event,
367         .disable                = x86_pmu_disable_event,
368         .hw_config              = amd_pmu_hw_config,
369         .schedule_events        = x86_schedule_events,
370         .eventsel               = MSR_K7_EVNTSEL0,
371         .perfctr                = MSR_K7_PERFCTR0,
372         .event_map              = amd_pmu_event_map,
373         .max_events             = ARRAY_SIZE(amd_perfmon_event_map),
374         .num_counters           = 4,
375         .cntval_bits            = 48,
376         .cntval_mask            = (1ULL << 48) - 1,
377         .apic                   = 1,
378         /* use highest bit to detect overflow */
379         .max_period             = (1ULL << 47) - 1,
380         .get_event_constraints  = amd_get_event_constraints,
381         .put_event_constraints  = amd_put_event_constraints,
382
383         .cpu_prepare            = amd_pmu_cpu_prepare,
384         .cpu_starting           = amd_pmu_cpu_starting,
385         .cpu_dead               = amd_pmu_cpu_dead,
386 };
387
388 static __init int amd_pmu_init(void)
389 {
390         /* Performance-monitoring supported from K7 and later: */
391         if (boot_cpu_data.x86 < 6)
392                 return -ENODEV;
393
394         x86_pmu = amd_pmu;
395
396         /* Events are common for all AMDs */
397         memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
398                sizeof(hw_cache_event_ids));
399
400         return 0;
401 }
402
403 #else /* CONFIG_CPU_SUP_AMD */
404
405 static int amd_pmu_init(void)
406 {
407         return 0;
408 }
409
410 #endif