Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Copyright IBM Corp. 2012,2015
0004  *
0005  *  Author(s):
0006  *    Jan Glauber <jang@linux.vnet.ibm.com>
0007  */
0008 
0009 #define KMSG_COMPONENT "zpci"
0010 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/seq_file.h>
0014 #include <linux/debugfs.h>
0015 #include <linux/export.h>
0016 #include <linux/pci.h>
0017 #include <asm/debug.h>
0018 
0019 #include <asm/pci_dma.h>
0020 
0021 static struct dentry *debugfs_root;
0022 debug_info_t *pci_debug_msg_id;
0023 EXPORT_SYMBOL_GPL(pci_debug_msg_id);
0024 debug_info_t *pci_debug_err_id;
0025 EXPORT_SYMBOL_GPL(pci_debug_err_id);
0026 
0027 static char *pci_common_names[] = {
0028     "Load operations",
0029     "Store operations",
0030     "Store block operations",
0031     "Refresh operations",
0032 };
0033 
0034 static char *pci_fmt0_names[] = {
0035     "DMA read bytes",
0036     "DMA write bytes",
0037 };
0038 
0039 static char *pci_fmt1_names[] = {
0040     "Received bytes",
0041     "Received packets",
0042     "Transmitted bytes",
0043     "Transmitted packets",
0044 };
0045 
0046 static char *pci_fmt2_names[] = {
0047     "Consumed work units",
0048     "Maximum work units",
0049 };
0050 
0051 static char *pci_fmt3_names[] = {
0052     "Transmitted bytes",
0053 };
0054 
0055 static char *pci_sw_names[] = {
0056     "Allocated pages",
0057     "Mapped pages",
0058     "Unmapped pages",
0059 };
0060 
0061 static void pci_fmb_show(struct seq_file *m, char *name[], int length,
0062              u64 *data)
0063 {
0064     int i;
0065 
0066     for (i = 0; i < length; i++, data++)
0067         seq_printf(m, "%26s:\t%llu\n", name[i], *data);
0068 }
0069 
0070 static void pci_sw_counter_show(struct seq_file *m)
0071 {
0072     struct zpci_dev *zdev = m->private;
0073     atomic64_t *counter = &zdev->allocated_pages;
0074     int i;
0075 
0076     for (i = 0; i < ARRAY_SIZE(pci_sw_names); i++, counter++)
0077         seq_printf(m, "%26s:\t%llu\n", pci_sw_names[i],
0078                atomic64_read(counter));
0079 }
0080 
0081 static int pci_perf_show(struct seq_file *m, void *v)
0082 {
0083     struct zpci_dev *zdev = m->private;
0084 
0085     if (!zdev)
0086         return 0;
0087 
0088     mutex_lock(&zdev->lock);
0089     if (!zdev->fmb) {
0090         mutex_unlock(&zdev->lock);
0091         seq_puts(m, "FMB statistics disabled\n");
0092         return 0;
0093     }
0094 
0095     /* header */
0096     seq_printf(m, "Update interval: %u ms\n", zdev->fmb_update);
0097     seq_printf(m, "Samples: %u\n", zdev->fmb->samples);
0098     seq_printf(m, "Last update TOD: %Lx\n", zdev->fmb->last_update);
0099 
0100     pci_fmb_show(m, pci_common_names, ARRAY_SIZE(pci_common_names),
0101              &zdev->fmb->ld_ops);
0102 
0103     switch (zdev->fmb->format) {
0104     case 0:
0105         if (!(zdev->fmb->fmt_ind & ZPCI_FMB_DMA_COUNTER_VALID))
0106             break;
0107         pci_fmb_show(m, pci_fmt0_names, ARRAY_SIZE(pci_fmt0_names),
0108                  &zdev->fmb->fmt0.dma_rbytes);
0109         break;
0110     case 1:
0111         pci_fmb_show(m, pci_fmt1_names, ARRAY_SIZE(pci_fmt1_names),
0112                  &zdev->fmb->fmt1.rx_bytes);
0113         break;
0114     case 2:
0115         pci_fmb_show(m, pci_fmt2_names, ARRAY_SIZE(pci_fmt2_names),
0116                  &zdev->fmb->fmt2.consumed_work_units);
0117         break;
0118     case 3:
0119         pci_fmb_show(m, pci_fmt3_names, ARRAY_SIZE(pci_fmt3_names),
0120                  &zdev->fmb->fmt3.tx_bytes);
0121         break;
0122     default:
0123         seq_puts(m, "Unknown format\n");
0124     }
0125 
0126     pci_sw_counter_show(m);
0127     mutex_unlock(&zdev->lock);
0128     return 0;
0129 }
0130 
0131 static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
0132                   size_t count, loff_t *off)
0133 {
0134     struct zpci_dev *zdev = ((struct seq_file *) file->private_data)->private;
0135     unsigned long val;
0136     int rc;
0137 
0138     if (!zdev)
0139         return 0;
0140 
0141     rc = kstrtoul_from_user(ubuf, count, 10, &val);
0142     if (rc)
0143         return rc;
0144 
0145     mutex_lock(&zdev->lock);
0146     switch (val) {
0147     case 0:
0148         rc = zpci_fmb_disable_device(zdev);
0149         break;
0150     case 1:
0151         rc = zpci_fmb_enable_device(zdev);
0152         break;
0153     }
0154     mutex_unlock(&zdev->lock);
0155     return rc ? rc : count;
0156 }
0157 
0158 static int pci_perf_seq_open(struct inode *inode, struct file *filp)
0159 {
0160     return single_open(filp, pci_perf_show,
0161                file_inode(filp)->i_private);
0162 }
0163 
0164 static const struct file_operations debugfs_pci_perf_fops = {
0165     .open    = pci_perf_seq_open,
0166     .read    = seq_read,
0167     .write   = pci_perf_seq_write,
0168     .llseek  = seq_lseek,
0169     .release = single_release,
0170 };
0171 
0172 void zpci_debug_init_device(struct zpci_dev *zdev, const char *name)
0173 {
0174     zdev->debugfs_dev = debugfs_create_dir(name, debugfs_root);
0175 
0176     debugfs_create_file("statistics", S_IFREG | S_IRUGO | S_IWUSR,
0177                 zdev->debugfs_dev, zdev, &debugfs_pci_perf_fops);
0178 }
0179 
0180 void zpci_debug_exit_device(struct zpci_dev *zdev)
0181 {
0182     debugfs_remove_recursive(zdev->debugfs_dev);
0183 }
0184 
0185 int __init zpci_debug_init(void)
0186 {
0187     /* event trace buffer */
0188     pci_debug_msg_id = debug_register("pci_msg", 8, 1, 8 * sizeof(long));
0189     if (!pci_debug_msg_id)
0190         return -EINVAL;
0191     debug_register_view(pci_debug_msg_id, &debug_sprintf_view);
0192     debug_set_level(pci_debug_msg_id, 3);
0193 
0194     /* error log */
0195     pci_debug_err_id = debug_register("pci_error", 2, 1, 16);
0196     if (!pci_debug_err_id)
0197         return -EINVAL;
0198     debug_register_view(pci_debug_err_id, &debug_hex_ascii_view);
0199     debug_set_level(pci_debug_err_id, 3);
0200 
0201     debugfs_root = debugfs_create_dir("pci", NULL);
0202     return 0;
0203 }
0204 
0205 void zpci_debug_exit(void)
0206 {
0207     debug_unregister(pci_debug_msg_id);
0208     debug_unregister(pci_debug_err_id);
0209     debugfs_remove(debugfs_root);
0210 }