blob: 59c9278befc9a88965caf7ebf6e52fec53d749be [file] [log] [blame]
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001/**
2 * arch/s390/oprofile/hwsampler.c
3 *
4 * Copyright IBM Corp. 2010
5 * Author: Heinz Graalfs <graalfs@de.ibm.com>
6 */
7
Heiko Carstensfcdd65b2011-05-23 10:24:48 +02008#include <linux/kernel_stat.h>
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00009#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/smp.h>
12#include <linux/errno.h>
13#include <linux/workqueue.h>
14#include <linux/interrupt.h>
15#include <linux/notifier.h>
16#include <linux/cpu.h>
17#include <linux/semaphore.h>
18#include <linux/oom.h>
19#include <linux/oprofile.h>
20
David Howellsa0616cd2012-03-28 18:30:02 +010021#include <asm/facility.h>
Heinz Graalfsec6a3df2011-01-21 10:06:52 +000022#include <asm/lowcore.h>
Heiko Carstensd7b250e2011-05-26 09:48:24 +020023#include <asm/irq.h>
Heinz Graalfsec6a3df2011-01-21 10:06:52 +000024
25#include "hwsampler.h"
Andreas Krebbeldd3c4672011-11-25 20:03:05 +010026#include "op_counter.h"
Heinz Graalfsec6a3df2011-01-21 10:06:52 +000027
28#define MAX_NUM_SDB 511
29#define MIN_NUM_SDB 1
30
31#define ALERT_REQ_MASK 0x4000000000000000ul
32#define BUFFER_FULL_MASK 0x8000000000000000ul
33
34#define EI_IEA (1 << 31) /* invalid entry address */
35#define EI_ISE (1 << 30) /* incorrect SDBT entry */
36#define EI_PRA (1 << 29) /* program request alert */
37#define EI_SACA (1 << 23) /* sampler authorization change alert */
38#define EI_LSDA (1 << 22) /* loss of sample data alert */
39
40DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer);
41
42struct hws_execute_parms {
43 void *buffer;
44 signed int rc;
45};
46
47DEFINE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer);
48EXPORT_PER_CPU_SYMBOL(sampler_cpu_buffer);
49
50static DEFINE_MUTEX(hws_sem);
51static DEFINE_MUTEX(hws_sem_oom);
52
53static unsigned char hws_flush_all;
54static unsigned int hws_oom;
55static struct workqueue_struct *hws_wq;
56
57static unsigned int hws_state;
58enum {
59 HWS_INIT = 1,
60 HWS_DEALLOCATED,
61 HWS_STOPPED,
62 HWS_STARTED,
63 HWS_STOPPING };
64
65/* set to 1 if called by kernel during memory allocation */
66static unsigned char oom_killer_was_active;
67/* size of SDBT and SDB as of allocate API */
68static unsigned long num_sdbt = 100;
69static unsigned long num_sdb = 511;
70/* sampling interval (machine cycles) */
71static unsigned long interval;
72
73static unsigned long min_sampler_rate;
74static unsigned long max_sampler_rate;
75
76static int ssctl(void *buffer)
77{
78 int cc;
79
80 /* set in order to detect a program check */
81 cc = 1;
82
83 asm volatile(
84 "0: .insn s,0xB2870000,0(%1)\n"
85 "1: ipm %0\n"
86 " srl %0,28\n"
87 "2:\n"
88 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b)
89 : "+d" (cc), "+a" (buffer)
90 : "m" (*((struct hws_ssctl_request_block *)buffer))
91 : "cc", "memory");
92
93 return cc ? -EINVAL : 0 ;
94}
95
96static int qsi(void *buffer)
97{
98 int cc;
99 cc = 1;
100
101 asm volatile(
102 "0: .insn s,0xB2860000,0(%1)\n"
103 "1: lhi %0,0\n"
104 "2:\n"
105 EX_TABLE(0b, 2b) EX_TABLE(1b, 2b)
106 : "=d" (cc), "+a" (buffer)
107 : "m" (*((struct hws_qsi_info_block *)buffer))
108 : "cc", "memory");
109
110 return cc ? -EINVAL : 0;
111}
112
113static void execute_qsi(void *parms)
114{
115 struct hws_execute_parms *ep = parms;
116
117 ep->rc = qsi(ep->buffer);
118}
119
120static void execute_ssctl(void *parms)
121{
122 struct hws_execute_parms *ep = parms;
123
124 ep->rc = ssctl(ep->buffer);
125}
126
127static int smp_ctl_ssctl_stop(int cpu)
128{
129 int rc;
130 struct hws_execute_parms ep;
131 struct hws_cpu_buffer *cb;
132
133 cb = &per_cpu(sampler_cpu_buffer, cpu);
134
135 cb->ssctl.es = 0;
136 cb->ssctl.cs = 0;
137
138 ep.buffer = &cb->ssctl;
139 smp_call_function_single(cpu, execute_ssctl, &ep, 1);
140 rc = ep.rc;
141 if (rc) {
142 printk(KERN_ERR "hwsampler: CPU %d CPUMF SSCTL failed.\n", cpu);
143 dump_stack();
144 }
145
146 ep.buffer = &cb->qsi;
147 smp_call_function_single(cpu, execute_qsi, &ep, 1);
148
149 if (cb->qsi.es || cb->qsi.cs) {
150 printk(KERN_EMERG "CPUMF sampling did not stop properly.\n");
151 dump_stack();
152 }
153
154 return rc;
155}
156
157static int smp_ctl_ssctl_deactivate(int cpu)
158{
159 int rc;
160 struct hws_execute_parms ep;
161 struct hws_cpu_buffer *cb;
162
163 cb = &per_cpu(sampler_cpu_buffer, cpu);
164
165 cb->ssctl.es = 1;
166 cb->ssctl.cs = 0;
167
168 ep.buffer = &cb->ssctl;
169 smp_call_function_single(cpu, execute_ssctl, &ep, 1);
170 rc = ep.rc;
171 if (rc)
172 printk(KERN_ERR "hwsampler: CPU %d CPUMF SSCTL failed.\n", cpu);
173
174 ep.buffer = &cb->qsi;
175 smp_call_function_single(cpu, execute_qsi, &ep, 1);
176
177 if (cb->qsi.cs)
178 printk(KERN_EMERG "CPUMF sampling was not set inactive.\n");
179
180 return rc;
181}
182
183static int smp_ctl_ssctl_enable_activate(int cpu, unsigned long interval)
184{
185 int rc;
186 struct hws_execute_parms ep;
187 struct hws_cpu_buffer *cb;
188
189 cb = &per_cpu(sampler_cpu_buffer, cpu);
190
191 cb->ssctl.h = 1;
192 cb->ssctl.tear = cb->first_sdbt;
193 cb->ssctl.dear = *(unsigned long *) cb->first_sdbt;
194 cb->ssctl.interval = interval;
195 cb->ssctl.es = 1;
196 cb->ssctl.cs = 1;
197
198 ep.buffer = &cb->ssctl;
199 smp_call_function_single(cpu, execute_ssctl, &ep, 1);
200 rc = ep.rc;
201 if (rc)
202 printk(KERN_ERR "hwsampler: CPU %d CPUMF SSCTL failed.\n", cpu);
203
204 ep.buffer = &cb->qsi;
205 smp_call_function_single(cpu, execute_qsi, &ep, 1);
206 if (ep.rc)
207 printk(KERN_ERR "hwsampler: CPU %d CPUMF QSI failed.\n", cpu);
208
209 return rc;
210}
211
212static int smp_ctl_qsi(int cpu)
213{
214 struct hws_execute_parms ep;
215 struct hws_cpu_buffer *cb;
216
217 cb = &per_cpu(sampler_cpu_buffer, cpu);
218
219 ep.buffer = &cb->qsi;
220 smp_call_function_single(cpu, execute_qsi, &ep, 1);
221
222 return ep.rc;
223}
224
225static inline unsigned long *trailer_entry_ptr(unsigned long v)
226{
227 void *ret;
228
229 ret = (void *)v;
230 ret += PAGE_SIZE;
231 ret -= sizeof(struct hws_trailer_entry);
232
233 return (unsigned long *) ret;
234}
235
236/* prototypes for external interrupt handler and worker */
Heiko Carstensfde15c32012-03-11 11:59:31 -0400237static void hws_ext_handler(struct ext_code ext_code,
238 unsigned int param32, unsigned long param64);
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000239
240static void worker(struct work_struct *work);
241
242static void add_samples_to_oprofile(unsigned cpu, unsigned long *,
243 unsigned long *dear);
244
245static void init_all_cpu_buffers(void)
246{
247 int cpu;
248 struct hws_cpu_buffer *cb;
249
250 for_each_online_cpu(cpu) {
251 cb = &per_cpu(sampler_cpu_buffer, cpu);
252 memset(cb, 0, sizeof(struct hws_cpu_buffer));
253 }
254}
255
256static int is_link_entry(unsigned long *s)
257{
258 return *s & 0x1ul ? 1 : 0;
259}
260
261static unsigned long *get_next_sdbt(unsigned long *s)
262{
263 return (unsigned long *) (*s & ~0x1ul);
264}
265
266static int prepare_cpu_buffers(void)
267{
268 int cpu;
269 int rc;
270 struct hws_cpu_buffer *cb;
271
272 rc = 0;
273 for_each_online_cpu(cpu) {
274 cb = &per_cpu(sampler_cpu_buffer, cpu);
275 atomic_set(&cb->ext_params, 0);
276 cb->worker_entry = 0;
277 cb->sample_overflow = 0;
278 cb->req_alert = 0;
279 cb->incorrect_sdbt_entry = 0;
280 cb->invalid_entry_address = 0;
281 cb->loss_of_sample_data = 0;
282 cb->sample_auth_change_alert = 0;
283 cb->finish = 0;
284 cb->oom = 0;
285 cb->stop_mode = 0;
286 }
287
288 return rc;
289}
290
291/*
292 * allocate_sdbt() - allocate sampler memory
293 * @cpu: the cpu for which sampler memory is allocated
294 *
295 * A 4K page is allocated for each requested SDBT.
296 * A maximum of 511 4K pages are allocated for the SDBs in each of the SDBTs.
297 * Set ALERT_REQ mask in each SDBs trailer.
298 * Returns zero if successful, <0 otherwise.
299 */
300static int allocate_sdbt(int cpu)
301{
302 int j, k, rc;
303 unsigned long *sdbt;
304 unsigned long sdb;
305 unsigned long *tail;
306 unsigned long *trailer;
307 struct hws_cpu_buffer *cb;
308
309 cb = &per_cpu(sampler_cpu_buffer, cpu);
310
311 if (cb->first_sdbt)
312 return -EINVAL;
313
314 sdbt = NULL;
315 tail = sdbt;
316
317 for (j = 0; j < num_sdbt; j++) {
318 sdbt = (unsigned long *)get_zeroed_page(GFP_KERNEL);
319
320 mutex_lock(&hws_sem_oom);
321 /* OOM killer might have been activated */
322 barrier();
323 if (oom_killer_was_active || !sdbt) {
324 if (sdbt)
325 free_page((unsigned long)sdbt);
326
327 goto allocate_sdbt_error;
328 }
329 if (cb->first_sdbt == 0)
330 cb->first_sdbt = (unsigned long)sdbt;
331
332 /* link current page to tail of chain */
333 if (tail)
334 *tail = (unsigned long)(void *)sdbt + 1;
335
336 mutex_unlock(&hws_sem_oom);
337
338 for (k = 0; k < num_sdb; k++) {
339 /* get and set SDB page */
340 sdb = get_zeroed_page(GFP_KERNEL);
341
342 mutex_lock(&hws_sem_oom);
343 /* OOM killer might have been activated */
344 barrier();
345 if (oom_killer_was_active || !sdb) {
346 if (sdb)
347 free_page(sdb);
348
349 goto allocate_sdbt_error;
350 }
351 *sdbt = sdb;
352 trailer = trailer_entry_ptr(*sdbt);
353 *trailer = ALERT_REQ_MASK;
354 sdbt++;
355 mutex_unlock(&hws_sem_oom);
356 }
357 tail = sdbt;
358 }
359 mutex_lock(&hws_sem_oom);
360 if (oom_killer_was_active)
361 goto allocate_sdbt_error;
362
363 rc = 0;
364 if (tail)
365 *tail = (unsigned long)
366 ((void *)cb->first_sdbt) + 1;
367
368allocate_sdbt_exit:
369 mutex_unlock(&hws_sem_oom);
370 return rc;
371
372allocate_sdbt_error:
373 rc = -ENOMEM;
374 goto allocate_sdbt_exit;
375}
376
377/*
378 * deallocate_sdbt() - deallocate all sampler memory
379 *
380 * For each online CPU all SDBT trees are deallocated.
381 * Returns the number of freed pages.
382 */
383static int deallocate_sdbt(void)
384{
385 int cpu;
386 int counter;
387
388 counter = 0;
389
390 for_each_online_cpu(cpu) {
391 unsigned long start;
392 unsigned long sdbt;
393 unsigned long *curr;
394 struct hws_cpu_buffer *cb;
395
396 cb = &per_cpu(sampler_cpu_buffer, cpu);
397
398 if (!cb->first_sdbt)
399 continue;
400
401 sdbt = cb->first_sdbt;
402 curr = (unsigned long *) sdbt;
403 start = sdbt;
404
405 /* we'll free the SDBT after all SDBs are processed... */
406 while (1) {
407 if (!*curr || !sdbt)
408 break;
409
410 /* watch for link entry reset if found */
411 if (is_link_entry(curr)) {
412 curr = get_next_sdbt(curr);
413 if (sdbt)
414 free_page(sdbt);
415
416 /* we are done if we reach the start */
417 if ((unsigned long) curr == start)
418 break;
419 else
420 sdbt = (unsigned long) curr;
421 } else {
422 /* process SDB pointer */
423 if (*curr) {
424 free_page(*curr);
425 curr++;
426 }
427 }
428 counter++;
429 }
430 cb->first_sdbt = 0;
431 }
432 return counter;
433}
434
435static int start_sampling(int cpu)
436{
437 int rc;
438 struct hws_cpu_buffer *cb;
439
440 cb = &per_cpu(sampler_cpu_buffer, cpu);
441 rc = smp_ctl_ssctl_enable_activate(cpu, interval);
442 if (rc) {
443 printk(KERN_INFO "hwsampler: CPU %d ssctl failed.\n", cpu);
444 goto start_exit;
445 }
446
447 rc = -EINVAL;
448 if (!cb->qsi.es) {
449 printk(KERN_INFO "hwsampler: CPU %d ssctl not enabled.\n", cpu);
450 goto start_exit;
451 }
452
453 if (!cb->qsi.cs) {
454 printk(KERN_INFO "hwsampler: CPU %d ssctl not active.\n", cpu);
455 goto start_exit;
456 }
457
458 printk(KERN_INFO
459 "hwsampler: CPU %d, CPUMF Sampling started, interval %lu.\n",
460 cpu, interval);
461
462 rc = 0;
463
464start_exit:
465 return rc;
466}
467
468static int stop_sampling(int cpu)
469{
470 unsigned long v;
471 int rc;
472 struct hws_cpu_buffer *cb;
473
474 rc = smp_ctl_qsi(cpu);
475 WARN_ON(rc);
476
477 cb = &per_cpu(sampler_cpu_buffer, cpu);
478 if (!rc && !cb->qsi.es)
479 printk(KERN_INFO "hwsampler: CPU %d, already stopped.\n", cpu);
480
481 rc = smp_ctl_ssctl_stop(cpu);
482 if (rc) {
483 printk(KERN_INFO "hwsampler: CPU %d, ssctl stop error %d.\n",
484 cpu, rc);
485 goto stop_exit;
486 }
487
488 printk(KERN_INFO "hwsampler: CPU %d, CPUMF Sampling stopped.\n", cpu);
489
490stop_exit:
491 v = cb->req_alert;
492 if (v)
493 printk(KERN_ERR "hwsampler: CPU %d CPUMF Request alert,"
494 " count=%lu.\n", cpu, v);
495
496 v = cb->loss_of_sample_data;
497 if (v)
498 printk(KERN_ERR "hwsampler: CPU %d CPUMF Loss of sample data,"
499 " count=%lu.\n", cpu, v);
500
501 v = cb->invalid_entry_address;
502 if (v)
503 printk(KERN_ERR "hwsampler: CPU %d CPUMF Invalid entry address,"
504 " count=%lu.\n", cpu, v);
505
506 v = cb->incorrect_sdbt_entry;
507 if (v)
508 printk(KERN_ERR
509 "hwsampler: CPU %d CPUMF Incorrect SDBT address,"
510 " count=%lu.\n", cpu, v);
511
512 v = cb->sample_auth_change_alert;
513 if (v)
514 printk(KERN_ERR
515 "hwsampler: CPU %d CPUMF Sample authorization change,"
516 " count=%lu.\n", cpu, v);
517
518 return rc;
519}
520
521static int check_hardware_prerequisites(void)
522{
Jan Glauber65a94b12011-04-04 09:43:29 +0200523 if (!test_facility(68))
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000524 return -EOPNOTSUPP;
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000525 return 0;
526}
527/*
528 * hws_oom_callback() - the OOM callback function
529 *
530 * In case the callback is invoked during memory allocation for the
531 * hw sampler, all obtained memory is deallocated and a flag is set
532 * so main sampler memory allocation can exit with a failure code.
533 * In case the callback is invoked during sampling the hw sampler
534 * is deactivated for all CPUs.
535 */
536static int hws_oom_callback(struct notifier_block *nfb,
537 unsigned long dummy, void *parm)
538{
539 unsigned long *freed;
540 int cpu;
541 struct hws_cpu_buffer *cb;
542
543 freed = parm;
544
545 mutex_lock(&hws_sem_oom);
546
547 if (hws_state == HWS_DEALLOCATED) {
548 /* during memory allocation */
549 if (oom_killer_was_active == 0) {
550 oom_killer_was_active = 1;
551 *freed += deallocate_sdbt();
552 }
553 } else {
554 int i;
555 cpu = get_cpu();
556 cb = &per_cpu(sampler_cpu_buffer, cpu);
557
558 if (!cb->oom) {
559 for_each_online_cpu(i) {
560 smp_ctl_ssctl_deactivate(i);
561 cb->oom = 1;
562 }
563 cb->finish = 1;
564
565 printk(KERN_INFO
566 "hwsampler: CPU %d, OOM notify during CPUMF Sampling.\n",
567 cpu);
568 }
569 }
570
571 mutex_unlock(&hws_sem_oom);
572
573 return NOTIFY_OK;
574}
575
576static struct notifier_block hws_oom_notifier = {
577 .notifier_call = hws_oom_callback
578};
579
Robert Richter7bb2e262011-02-14 19:08:33 +0100580static int hws_cpu_callback(struct notifier_block *nfb,
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000581 unsigned long action, void *hcpu)
582{
583 /* We do not have sampler space available for all possible CPUs.
584 All CPUs should be online when hw sampling is activated. */
Martin Schwidefskyb07c9012011-05-26 09:48:26 +0200585 return (hws_state <= HWS_DEALLOCATED) ? NOTIFY_OK : NOTIFY_BAD;
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000586}
587
588static struct notifier_block hws_cpu_notifier = {
589 .notifier_call = hws_cpu_callback
590};
591
592/**
593 * hwsampler_deactivate() - set hardware sampling temporarily inactive
594 * @cpu: specifies the CPU to be set inactive.
595 *
596 * Returns 0 on success, !0 on failure.
597 */
598int hwsampler_deactivate(unsigned int cpu)
599{
600 /*
601 * Deactivate hw sampling temporarily and flush the buffer
602 * by pushing all the pending samples to oprofile buffer.
603 *
604 * This function can be called under one of the following conditions:
605 * Memory unmap, task is exiting.
606 */
607 int rc;
608 struct hws_cpu_buffer *cb;
609
610 rc = 0;
611 mutex_lock(&hws_sem);
612
613 cb = &per_cpu(sampler_cpu_buffer, cpu);
614 if (hws_state == HWS_STARTED) {
615 rc = smp_ctl_qsi(cpu);
616 WARN_ON(rc);
617 if (cb->qsi.cs) {
618 rc = smp_ctl_ssctl_deactivate(cpu);
619 if (rc) {
620 printk(KERN_INFO
621 "hwsampler: CPU %d, CPUMF Deactivation failed.\n", cpu);
622 cb->finish = 1;
623 hws_state = HWS_STOPPING;
624 } else {
625 hws_flush_all = 1;
626 /* Add work to queue to read pending samples.*/
627 queue_work_on(cpu, hws_wq, &cb->worker);
628 }
629 }
630 }
631 mutex_unlock(&hws_sem);
632
633 if (hws_wq)
634 flush_workqueue(hws_wq);
635
636 return rc;
637}
638
639/**
640 * hwsampler_activate() - activate/resume hardware sampling which was deactivated
641 * @cpu: specifies the CPU to be set active.
642 *
643 * Returns 0 on success, !0 on failure.
644 */
645int hwsampler_activate(unsigned int cpu)
646{
647 /*
648 * Re-activate hw sampling. This should be called in pair with
649 * hwsampler_deactivate().
650 */
651 int rc;
652 struct hws_cpu_buffer *cb;
653
654 rc = 0;
655 mutex_lock(&hws_sem);
656
657 cb = &per_cpu(sampler_cpu_buffer, cpu);
658 if (hws_state == HWS_STARTED) {
659 rc = smp_ctl_qsi(cpu);
660 WARN_ON(rc);
661 if (!cb->qsi.cs) {
662 hws_flush_all = 0;
663 rc = smp_ctl_ssctl_enable_activate(cpu, interval);
664 if (rc) {
665 printk(KERN_ERR
666 "CPU %d, CPUMF activate sampling failed.\n",
667 cpu);
668 }
669 }
670 }
671
672 mutex_unlock(&hws_sem);
673
674 return rc;
675}
676
Heiko Carstensfde15c32012-03-11 11:59:31 -0400677static void hws_ext_handler(struct ext_code ext_code,
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000678 unsigned int param32, unsigned long param64)
679{
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000680 struct hws_cpu_buffer *cb;
681
Heiko Carstensfcdd65b2011-05-23 10:24:48 +0200682 kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++;
Heiko Carstens5f420c52011-05-23 10:24:49 +0200683 cb = &__get_cpu_var(sampler_cpu_buffer);
684 atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32);
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000685 if (hws_wq)
686 queue_work(hws_wq, &cb->worker);
687}
688
689static int check_qsi_on_setup(void)
690{
691 int rc;
692 unsigned int cpu;
693 struct hws_cpu_buffer *cb;
694
695 for_each_online_cpu(cpu) {
696 cb = &per_cpu(sampler_cpu_buffer, cpu);
697 rc = smp_ctl_qsi(cpu);
698 WARN_ON(rc);
699 if (rc)
700 return -EOPNOTSUPP;
701
702 if (!cb->qsi.as) {
703 printk(KERN_INFO "hwsampler: CPUMF sampling is not authorized.\n");
704 return -EINVAL;
705 }
706
707 if (cb->qsi.es) {
708 printk(KERN_WARNING "hwsampler: CPUMF is still enabled.\n");
709 rc = smp_ctl_ssctl_stop(cpu);
710 if (rc)
711 return -EINVAL;
712
713 printk(KERN_INFO
714 "CPU %d, CPUMF Sampling stopped now.\n", cpu);
715 }
716 }
717 return 0;
718}
719
720static int check_qsi_on_start(void)
721{
722 unsigned int cpu;
723 int rc;
724 struct hws_cpu_buffer *cb;
725
726 for_each_online_cpu(cpu) {
727 cb = &per_cpu(sampler_cpu_buffer, cpu);
728 rc = smp_ctl_qsi(cpu);
729 WARN_ON(rc);
730
731 if (!cb->qsi.as)
732 return -EINVAL;
733
734 if (cb->qsi.es)
735 return -EINVAL;
736
737 if (cb->qsi.cs)
738 return -EINVAL;
739 }
740 return 0;
741}
742
743static void worker_on_start(unsigned int cpu)
744{
745 struct hws_cpu_buffer *cb;
746
747 cb = &per_cpu(sampler_cpu_buffer, cpu);
748 cb->worker_entry = cb->first_sdbt;
749}
750
751static int worker_check_error(unsigned int cpu, int ext_params)
752{
753 int rc;
754 unsigned long *sdbt;
755 struct hws_cpu_buffer *cb;
756
757 rc = 0;
758 cb = &per_cpu(sampler_cpu_buffer, cpu);
759 sdbt = (unsigned long *) cb->worker_entry;
760
761 if (!sdbt || !*sdbt)
762 return -EINVAL;
763
Jan Glauber9529cdc2011-05-23 10:24:45 +0200764 if (ext_params & EI_PRA)
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000765 cb->req_alert++;
766
767 if (ext_params & EI_LSDA)
768 cb->loss_of_sample_data++;
769
770 if (ext_params & EI_IEA) {
771 cb->invalid_entry_address++;
772 rc = -EINVAL;
773 }
774
775 if (ext_params & EI_ISE) {
776 cb->incorrect_sdbt_entry++;
777 rc = -EINVAL;
778 }
779
780 if (ext_params & EI_SACA) {
781 cb->sample_auth_change_alert++;
782 rc = -EINVAL;
783 }
784
785 return rc;
786}
787
788static void worker_on_finish(unsigned int cpu)
789{
790 int rc, i;
791 struct hws_cpu_buffer *cb;
792
793 cb = &per_cpu(sampler_cpu_buffer, cpu);
794
795 if (cb->finish) {
796 rc = smp_ctl_qsi(cpu);
797 WARN_ON(rc);
798 if (cb->qsi.es) {
799 printk(KERN_INFO
800 "hwsampler: CPU %d, CPUMF Stop/Deactivate sampling.\n",
801 cpu);
802 rc = smp_ctl_ssctl_stop(cpu);
803 if (rc)
804 printk(KERN_INFO
805 "hwsampler: CPU %d, CPUMF Deactivation failed.\n",
806 cpu);
807
808 for_each_online_cpu(i) {
809 if (i == cpu)
810 continue;
811 if (!cb->finish) {
812 cb->finish = 1;
813 queue_work_on(i, hws_wq,
814 &cb->worker);
815 }
816 }
817 }
818 }
819}
820
821static void worker_on_interrupt(unsigned int cpu)
822{
823 unsigned long *sdbt;
824 unsigned char done;
825 struct hws_cpu_buffer *cb;
826
827 cb = &per_cpu(sampler_cpu_buffer, cpu);
828
829 sdbt = (unsigned long *) cb->worker_entry;
830
831 done = 0;
832 /* do not proceed if stop was entered,
833 * forget the buffers not yet processed */
834 while (!done && !cb->stop_mode) {
835 unsigned long *trailer;
836 struct hws_trailer_entry *te;
837 unsigned long *dear = 0;
838
839 trailer = trailer_entry_ptr(*sdbt);
840 /* leave loop if no more work to do */
841 if (!(*trailer & BUFFER_FULL_MASK)) {
842 done = 1;
843 if (!hws_flush_all)
844 continue;
845 }
846
847 te = (struct hws_trailer_entry *)trailer;
848 cb->sample_overflow += te->overflow;
849
850 add_samples_to_oprofile(cpu, sdbt, dear);
851
852 /* reset trailer */
853 xchg((unsigned char *) te, 0x40);
854
855 /* advance to next sdb slot in current sdbt */
856 sdbt++;
857 /* in case link bit is set use address w/o link bit */
858 if (is_link_entry(sdbt))
859 sdbt = get_next_sdbt(sdbt);
860
861 cb->worker_entry = (unsigned long)sdbt;
862 }
863}
864
865static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt,
866 unsigned long *dear)
867{
868 struct hws_data_entry *sample_data_ptr;
869 unsigned long *trailer;
870
871 trailer = trailer_entry_ptr(*sdbt);
872 if (dear) {
873 if (dear > trailer)
874 return;
875 trailer = dear;
876 }
877
878 sample_data_ptr = (struct hws_data_entry *)(*sdbt);
879
880 while ((unsigned long *)sample_data_ptr < trailer) {
881 struct pt_regs *regs = NULL;
882 struct task_struct *tsk = NULL;
883
884 /*
885 * Check sampling mode, 1 indicates basic (=customer) sampling
886 * mode.
887 */
888 if (sample_data_ptr->def != 1) {
889 /* sample slot is not yet written */
890 break;
891 } else {
892 /* make sure we don't use it twice,
893 * the next time the sampler will set it again */
894 sample_data_ptr->def = 0;
895 }
896
897 /* Get pt_regs. */
898 if (sample_data_ptr->P == 1) {
899 /* userspace sample */
900 unsigned int pid = sample_data_ptr->prim_asn;
Andreas Krebbeldd3c4672011-11-25 20:03:05 +0100901 if (!counter_config.user)
902 goto skip_sample;
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000903 rcu_read_lock();
904 tsk = pid_task(find_vpid(pid), PIDTYPE_PID);
905 if (tsk)
906 regs = task_pt_regs(tsk);
907 rcu_read_unlock();
908 } else {
909 /* kernelspace sample */
Andreas Krebbeldd3c4672011-11-25 20:03:05 +0100910 if (!counter_config.kernel)
911 goto skip_sample;
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000912 regs = task_pt_regs(current);
913 }
914
915 mutex_lock(&hws_sem);
916 oprofile_add_ext_hw_sample(sample_data_ptr->ia, regs, 0,
917 !sample_data_ptr->P, tsk);
918 mutex_unlock(&hws_sem);
Andreas Krebbeldd3c4672011-11-25 20:03:05 +0100919 skip_sample:
Heinz Graalfsec6a3df2011-01-21 10:06:52 +0000920 sample_data_ptr++;
921 }
922}
923
924static void worker(struct work_struct *work)
925{
926 unsigned int cpu;
927 int ext_params;
928 struct hws_cpu_buffer *cb;
929
930 cb = container_of(work, struct hws_cpu_buffer, worker);
931 cpu = smp_processor_id();
932 ext_params = atomic_xchg(&cb->ext_params, 0);
933
934 if (!cb->worker_entry)
935 worker_on_start(cpu);
936
937 if (worker_check_error(cpu, ext_params))
938 return;
939
940 if (!cb->finish)
941 worker_on_interrupt(cpu);
942
943 if (cb->finish)
944 worker_on_finish(cpu);
945}
946
947/**
948 * hwsampler_allocate() - allocate memory for the hardware sampler
949 * @sdbt: number of SDBTs per online CPU (must be > 0)
950 * @sdb: number of SDBs per SDBT (minimum 1, maximum 511)
951 *
952 * Returns 0 on success, !0 on failure.
953 */
954int hwsampler_allocate(unsigned long sdbt, unsigned long sdb)
955{
956 int cpu, rc;
957 mutex_lock(&hws_sem);
958
959 rc = -EINVAL;
960 if (hws_state != HWS_DEALLOCATED)
961 goto allocate_exit;
962
963 if (sdbt < 1)
964 goto allocate_exit;
965
966 if (sdb > MAX_NUM_SDB || sdb < MIN_NUM_SDB)
967 goto allocate_exit;
968
969 num_sdbt = sdbt;
970 num_sdb = sdb;
971
972 oom_killer_was_active = 0;
973 register_oom_notifier(&hws_oom_notifier);
974
975 for_each_online_cpu(cpu) {
976 if (allocate_sdbt(cpu)) {
977 unregister_oom_notifier(&hws_oom_notifier);
978 goto allocate_error;
979 }
980 }
981 unregister_oom_notifier(&hws_oom_notifier);
982 if (oom_killer_was_active)
983 goto allocate_error;
984
985 hws_state = HWS_STOPPED;
986 rc = 0;
987
988allocate_exit:
989 mutex_unlock(&hws_sem);
990 return rc;
991
992allocate_error:
993 rc = -ENOMEM;
994 printk(KERN_ERR "hwsampler: CPUMF Memory allocation failed.\n");
995 goto allocate_exit;
996}
997
998/**
999 * hwsampler_deallocate() - deallocate hardware sampler memory
1000 *
1001 * Returns 0 on success, !0 on failure.
1002 */
Martin Schwidefskye54aafa2011-10-30 15:17:12 +01001003int hwsampler_deallocate(void)
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001004{
1005 int rc;
1006
1007 mutex_lock(&hws_sem);
1008
1009 rc = -EINVAL;
1010 if (hws_state != HWS_STOPPED)
1011 goto deallocate_exit;
1012
Jan Glauber43a679d2011-05-23 10:24:46 +02001013 ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001014 deallocate_sdbt();
1015
1016 hws_state = HWS_DEALLOCATED;
1017 rc = 0;
1018
1019deallocate_exit:
1020 mutex_unlock(&hws_sem);
1021
1022 return rc;
1023}
1024
Martin Schwidefsky3d8dcb32011-05-10 17:13:42 +02001025unsigned long hwsampler_query_min_interval(void)
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001026{
Martin Schwidefsky3d8dcb32011-05-10 17:13:42 +02001027 return min_sampler_rate;
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001028}
1029
Martin Schwidefsky3d8dcb32011-05-10 17:13:42 +02001030unsigned long hwsampler_query_max_interval(void)
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001031{
Martin Schwidefsky3d8dcb32011-05-10 17:13:42 +02001032 return max_sampler_rate;
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001033}
1034
1035unsigned long hwsampler_get_sample_overflow_count(unsigned int cpu)
1036{
1037 struct hws_cpu_buffer *cb;
1038
1039 cb = &per_cpu(sampler_cpu_buffer, cpu);
1040
1041 return cb->sample_overflow;
1042}
1043
Martin Schwidefskye54aafa2011-10-30 15:17:12 +01001044int hwsampler_setup(void)
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001045{
1046 int rc;
1047 int cpu;
1048 struct hws_cpu_buffer *cb;
1049
1050 mutex_lock(&hws_sem);
1051
1052 rc = -EINVAL;
1053 if (hws_state)
1054 goto setup_exit;
1055
1056 hws_state = HWS_INIT;
1057
1058 init_all_cpu_buffers();
1059
1060 rc = check_hardware_prerequisites();
1061 if (rc)
1062 goto setup_exit;
1063
1064 rc = check_qsi_on_setup();
1065 if (rc)
1066 goto setup_exit;
1067
1068 rc = -EINVAL;
1069 hws_wq = create_workqueue("hwsampler");
1070 if (!hws_wq)
1071 goto setup_exit;
1072
1073 register_cpu_notifier(&hws_cpu_notifier);
1074
1075 for_each_online_cpu(cpu) {
1076 cb = &per_cpu(sampler_cpu_buffer, cpu);
1077 INIT_WORK(&cb->worker, worker);
1078 rc = smp_ctl_qsi(cpu);
1079 WARN_ON(rc);
1080 if (min_sampler_rate != cb->qsi.min_sampl_rate) {
1081 if (min_sampler_rate) {
1082 printk(KERN_WARNING
1083 "hwsampler: different min sampler rate values.\n");
1084 if (min_sampler_rate < cb->qsi.min_sampl_rate)
1085 min_sampler_rate =
1086 cb->qsi.min_sampl_rate;
1087 } else
1088 min_sampler_rate = cb->qsi.min_sampl_rate;
1089 }
1090 if (max_sampler_rate != cb->qsi.max_sampl_rate) {
1091 if (max_sampler_rate) {
1092 printk(KERN_WARNING
1093 "hwsampler: different max sampler rate values.\n");
1094 if (max_sampler_rate > cb->qsi.max_sampl_rate)
1095 max_sampler_rate =
1096 cb->qsi.max_sampl_rate;
1097 } else
1098 max_sampler_rate = cb->qsi.max_sampl_rate;
1099 }
1100 }
1101 register_external_interrupt(0x1407, hws_ext_handler);
1102
1103 hws_state = HWS_DEALLOCATED;
1104 rc = 0;
1105
1106setup_exit:
1107 mutex_unlock(&hws_sem);
1108 return rc;
1109}
1110
Martin Schwidefskye54aafa2011-10-30 15:17:12 +01001111int hwsampler_shutdown(void)
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001112{
1113 int rc;
1114
1115 mutex_lock(&hws_sem);
1116
1117 rc = -EINVAL;
1118 if (hws_state == HWS_DEALLOCATED || hws_state == HWS_STOPPED) {
1119 mutex_unlock(&hws_sem);
1120
1121 if (hws_wq)
1122 flush_workqueue(hws_wq);
1123
1124 mutex_lock(&hws_sem);
1125
1126 if (hws_state == HWS_STOPPED) {
Jan Glauber43a679d2011-05-23 10:24:46 +02001127 ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001128 deallocate_sdbt();
1129 }
1130 if (hws_wq) {
1131 destroy_workqueue(hws_wq);
1132 hws_wq = NULL;
1133 }
1134
1135 unregister_external_interrupt(0x1407, hws_ext_handler);
1136 hws_state = HWS_INIT;
1137 rc = 0;
1138 }
1139 mutex_unlock(&hws_sem);
1140
1141 unregister_cpu_notifier(&hws_cpu_notifier);
1142
1143 return rc;
1144}
1145
1146/**
1147 * hwsampler_start_all() - start hardware sampling on all online CPUs
1148 * @rate: specifies the used interval when samples are taken
1149 *
1150 * Returns 0 on success, !0 on failure.
1151 */
1152int hwsampler_start_all(unsigned long rate)
1153{
1154 int rc, cpu;
1155
1156 mutex_lock(&hws_sem);
1157
1158 hws_oom = 0;
1159
1160 rc = -EINVAL;
1161 if (hws_state != HWS_STOPPED)
1162 goto start_all_exit;
1163
1164 interval = rate;
1165
1166 /* fail if rate is not valid */
1167 if (interval < min_sampler_rate || interval > max_sampler_rate)
1168 goto start_all_exit;
1169
1170 rc = check_qsi_on_start();
1171 if (rc)
1172 goto start_all_exit;
1173
1174 rc = prepare_cpu_buffers();
1175 if (rc)
1176 goto start_all_exit;
1177
1178 for_each_online_cpu(cpu) {
1179 rc = start_sampling(cpu);
1180 if (rc)
1181 break;
1182 }
1183 if (rc) {
1184 for_each_online_cpu(cpu) {
1185 stop_sampling(cpu);
1186 }
1187 goto start_all_exit;
1188 }
1189 hws_state = HWS_STARTED;
1190 rc = 0;
1191
1192start_all_exit:
1193 mutex_unlock(&hws_sem);
1194
1195 if (rc)
1196 return rc;
1197
1198 register_oom_notifier(&hws_oom_notifier);
1199 hws_oom = 1;
1200 hws_flush_all = 0;
1201 /* now let them in, 1407 CPUMF external interrupts */
Jan Glauber43a679d2011-05-23 10:24:46 +02001202 ctl_set_bit(0, 5); /* set CR0 bit 58 */
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001203
1204 return 0;
1205}
1206
1207/**
1208 * hwsampler_stop_all() - stop hardware sampling on all online CPUs
1209 *
1210 * Returns 0 on success, !0 on failure.
1211 */
Martin Schwidefskye54aafa2011-10-30 15:17:12 +01001212int hwsampler_stop_all(void)
Heinz Graalfsec6a3df2011-01-21 10:06:52 +00001213{
1214 int tmp_rc, rc, cpu;
1215 struct hws_cpu_buffer *cb;
1216
1217 mutex_lock(&hws_sem);
1218
1219 rc = 0;
1220 if (hws_state == HWS_INIT) {
1221 mutex_unlock(&hws_sem);
1222 return rc;
1223 }
1224 hws_state = HWS_STOPPING;
1225 mutex_unlock(&hws_sem);
1226
1227 for_each_online_cpu(cpu) {
1228 cb = &per_cpu(sampler_cpu_buffer, cpu);
1229 cb->stop_mode = 1;
1230 tmp_rc = stop_sampling(cpu);
1231 if (tmp_rc)
1232 rc = tmp_rc;
1233 }
1234
1235 if (hws_wq)
1236 flush_workqueue(hws_wq);
1237
1238 mutex_lock(&hws_sem);
1239 if (hws_oom) {
1240 unregister_oom_notifier(&hws_oom_notifier);
1241 hws_oom = 0;
1242 }
1243 hws_state = HWS_STOPPED;
1244 mutex_unlock(&hws_sem);
1245
1246 return rc;
1247}