~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/platforms/pseries/hvCall_inst.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Copyright (C) 2006 Mike Kravetz IBM Corporation
  4  *
  5  * Hypervisor Call Instrumentation
  6  */
  7 
  8 #include <linux/kernel.h>
  9 #include <linux/percpu.h>
 10 #include <linux/debugfs.h>
 11 #include <linux/seq_file.h>
 12 #include <linux/cpumask.h>
 13 #include <asm/hvcall.h>
 14 #include <asm/firmware.h>
 15 #include <asm/cputable.h>
 16 #include <asm/trace.h>
 17 #include <asm/machdep.h>
 18 
 19 /* For hcall instrumentation. One structure per-hcall, per-CPU */
 20 struct hcall_stats {
 21         unsigned long   num_calls;      /* number of calls (on this CPU) */
 22         unsigned long   tb_total;       /* total wall time (mftb) of calls. */
 23         unsigned long   purr_total;     /* total cpu time (PURR) of calls. */
 24         unsigned long   tb_start;
 25         unsigned long   purr_start;
 26 };
 27 #define HCALL_STAT_ARRAY_SIZE   ((MAX_HCALL_OPCODE >> 2) + 1)
 28 
 29 static DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
 30 
 31 /*
 32  * Routines for displaying the statistics in debugfs
 33  */
 34 static void *hc_start(struct seq_file *m, loff_t *pos)
 35 {
 36         if ((int)*pos < (HCALL_STAT_ARRAY_SIZE-1))
 37                 return (void *)(unsigned long)(*pos + 1);
 38 
 39         return NULL;
 40 }
 41 
 42 static void *hc_next(struct seq_file *m, void *p, loff_t * pos)
 43 {
 44         ++*pos;
 45 
 46         return hc_start(m, pos);
 47 }
 48 
 49 static void hc_stop(struct seq_file *m, void *p)
 50 {
 51 }
 52 
 53 static int hc_show(struct seq_file *m, void *p)
 54 {
 55         unsigned long h_num = (unsigned long)p;
 56         struct hcall_stats *hs = m->private;
 57 
 58         if (hs[h_num].num_calls) {
 59                 if (cpu_has_feature(CPU_FTR_PURR))
 60                         seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2,
 61                                    hs[h_num].num_calls,
 62                                    hs[h_num].tb_total,
 63                                    hs[h_num].purr_total);
 64                 else
 65                         seq_printf(m, "%lu %lu %lu\n", h_num<<2,
 66                                    hs[h_num].num_calls,
 67                                    hs[h_num].tb_total);
 68         }
 69 
 70         return 0;
 71 }
 72 
 73 static const struct seq_operations hcall_inst_sops = {
 74         .start = hc_start,
 75         .next  = hc_next,
 76         .stop  = hc_stop,
 77         .show  = hc_show
 78 };
 79 
 80 DEFINE_SEQ_ATTRIBUTE(hcall_inst);
 81 
 82 #define HCALL_ROOT_DIR          "hcall_inst"
 83 #define CPU_NAME_BUF_SIZE       32
 84 
 85 
 86 static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long *args)
 87 {
 88         struct hcall_stats *h;
 89 
 90         if (opcode > MAX_HCALL_OPCODE)
 91                 return;
 92 
 93         h = this_cpu_ptr(&hcall_stats[opcode / 4]);
 94         h->tb_start = mftb();
 95         h->purr_start = mfspr(SPRN_PURR);
 96 }
 97 
 98 static void probe_hcall_exit(void *ignored, unsigned long opcode, long retval,
 99                              unsigned long *retbuf)
100 {
101         struct hcall_stats *h;
102 
103         if (opcode > MAX_HCALL_OPCODE)
104                 return;
105 
106         h = this_cpu_ptr(&hcall_stats[opcode / 4]);
107         h->num_calls++;
108         h->tb_total += mftb() - h->tb_start;
109         h->purr_total += mfspr(SPRN_PURR) - h->purr_start;
110 }
111 
112 static int __init hcall_inst_init(void)
113 {
114         struct dentry *hcall_root;
115         char cpu_name_buf[CPU_NAME_BUF_SIZE];
116         int cpu;
117 
118         if (!firmware_has_feature(FW_FEATURE_LPAR))
119                 return 0;
120 
121         if (register_trace_hcall_entry(probe_hcall_entry, NULL))
122                 return -EINVAL;
123 
124         if (register_trace_hcall_exit(probe_hcall_exit, NULL)) {
125                 unregister_trace_hcall_entry(probe_hcall_entry, NULL);
126                 return -EINVAL;
127         }
128 
129         hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL);
130 
131         for_each_possible_cpu(cpu) {
132                 snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu);
133                 debugfs_create_file(cpu_name_buf, 0444, hcall_root,
134                                     per_cpu(hcall_stats, cpu),
135                                     &hcall_inst_fops);
136         }
137 
138         return 0;
139 }
140 machine_device_initcall(pseries, hcall_inst_init);
141 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php