aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2012-12-11 08:53:35 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-12-14 04:01:17 -0500
commitd0b0885316ab7a97cc8a19027905de3ff7bd1e79 (patch)
tree43a490c63baf2da1d4768f7d083e2e9d6cf8467b /arch/s390
parent7313264b899bbf3988841296265a6e0e8a7b6521 (diff)
s390/pci: performance statistics and debug infrastructure
Add support for reading the PCI function measurement block counters provided by the hypervisor. Add two s390 debug features, one for critical errors and one for tracing and provide wrappers to log data. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/pci.h39
-rw-r--r--arch/s390/include/asm/pci_debug.h36
-rw-r--r--arch/s390/pci/Makefile2
-rw-r--r--arch/s390/pci/pci.c73
-rw-r--r--arch/s390/pci/pci_clp.c1
-rw-r--r--arch/s390/pci/pci_debug.c193
-rw-r--r--arch/s390/pci/pci_dma.c8
-rw-r--r--arch/s390/pci/pci_event.c2
8 files changed, 349 insertions, 5 deletions
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index a6175ad0c42f..b1fa93c606ad 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -9,6 +9,7 @@
9#include <asm-generic/pci.h> 9#include <asm-generic/pci.h>
10#include <asm-generic/pci-dma-compat.h> 10#include <asm-generic/pci-dma-compat.h>
11#include <asm/pci_clp.h> 11#include <asm/pci_clp.h>
12#include <asm/pci_debug.h>
12 13
13#define PCIBIOS_MIN_IO 0x1000 14#define PCIBIOS_MIN_IO 0x1000
14#define PCIBIOS_MIN_MEM 0x10000000 15#define PCIBIOS_MIN_MEM 0x10000000
@@ -33,6 +34,25 @@ int pci_proc_domain(struct pci_bus *);
33#define ZPCI_FC_BLOCKED 0x20 34#define ZPCI_FC_BLOCKED 0x20
34#define ZPCI_FC_DMA_ENABLED 0x10 35#define ZPCI_FC_DMA_ENABLED 0x10
35 36
37struct zpci_fmb {
38 u32 format : 8;
39 u32 dma_valid : 1;
40 u32 : 23;
41 u32 samples;
42 u64 last_update;
43 /* hardware counters */
44 u64 ld_ops;
45 u64 st_ops;
46 u64 stb_ops;
47 u64 rpcit_ops;
48 u64 dma_rbytes;
49 u64 dma_wbytes;
50 /* software counters */
51 atomic64_t allocated_pages;
52 atomic64_t mapped_pages;
53 atomic64_t unmapped_pages;
54} __packed __aligned(16);
55
36struct msi_map { 56struct msi_map {
37 unsigned long irq; 57 unsigned long irq;
38 struct msi_desc *msi; 58 struct msi_desc *msi;
@@ -92,7 +112,15 @@ struct zpci_dev {
92 u64 end_dma; /* End of available DMA addresses */ 112 u64 end_dma; /* End of available DMA addresses */
93 u64 dma_mask; /* DMA address space mask */ 113 u64 dma_mask; /* DMA address space mask */
94 114
115 /* Function measurement block */
116 struct zpci_fmb *fmb;
117 u16 fmb_update; /* update interval */
118
95 enum pci_bus_speed max_bus_speed; 119 enum pci_bus_speed max_bus_speed;
120
121 struct dentry *debugfs_dev;
122 struct dentry *debugfs_perf;
123 struct dentry *debugfs_debug;
96}; 124};
97 125
98struct pci_hp_callback_ops { 126struct pci_hp_callback_ops {
@@ -155,4 +183,15 @@ extern struct list_head zpci_list;
155extern struct pci_hp_callback_ops hotplug_ops; 183extern struct pci_hp_callback_ops hotplug_ops;
156extern unsigned int pci_probe; 184extern unsigned int pci_probe;
157 185
186/* FMB */
187int zpci_fmb_enable_device(struct zpci_dev *);
188int zpci_fmb_disable_device(struct zpci_dev *);
189
190/* Debug */
191int zpci_debug_init(void);
192void zpci_debug_exit(void);
193void zpci_debug_init_device(struct zpci_dev *);
194void zpci_debug_exit_device(struct zpci_dev *);
195void zpci_debug_info(struct zpci_dev *, struct seq_file *);
196
158#endif 197#endif
diff --git a/arch/s390/include/asm/pci_debug.h b/arch/s390/include/asm/pci_debug.h
new file mode 100644
index 000000000000..6bbec4265b6e
--- /dev/null
+++ b/arch/s390/include/asm/pci_debug.h
@@ -0,0 +1,36 @@
1#ifndef _S390_ASM_PCI_DEBUG_H
2#define _S390_ASM_PCI_DEBUG_H
3
4#include <asm/debug.h>
5
6extern debug_info_t *pci_debug_msg_id;
7extern debug_info_t *pci_debug_err_id;
8
9#ifdef CONFIG_PCI_DEBUG
10#define zpci_dbg(fmt, args...) \
11 do { \
12 if (pci_debug_msg_id->level >= 2) \
13 debug_sprintf_event(pci_debug_msg_id, 2, fmt , ## args);\
14 } while (0)
15
16#else /* !CONFIG_PCI_DEBUG */
17#define zpci_dbg(fmt, args...) do { } while (0)
18#endif
19
20#define zpci_err(text...) \
21 do { \
22 char debug_buffer[16]; \
23 snprintf(debug_buffer, 16, text); \
24 debug_text_event(pci_debug_err_id, 0, debug_buffer); \
25 } while (0)
26
27static inline void zpci_err_hex(void *addr, int len)
28{
29 while (len > 0) {
30 debug_event(pci_debug_err_id, 0, (void *) addr, len);
31 len -= pci_debug_err_id->buf_size;
32 addr += pci_debug_err_id->buf_size;
33 }
34}
35
36#endif
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile
index ab0827b6bc4b..f0f426a113ce 100644
--- a/arch/s390/pci/Makefile
+++ b/arch/s390/pci/Makefile
@@ -3,4 +3,4 @@
3# 3#
4 4
5obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \ 5obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \
6 pci_sysfs.o pci_event.o 6 pci_sysfs.o pci_event.o pci_debug.o
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 7ed38e5e3028..8fa416b8775f 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -98,6 +98,10 @@ EXPORT_SYMBOL_GPL(zpci_iomap_start);
98static int __read_mostly aisb_max; 98static int __read_mostly aisb_max;
99 99
100static struct kmem_cache *zdev_irq_cache; 100static struct kmem_cache *zdev_irq_cache;
101static struct kmem_cache *zdev_fmb_cache;
102
103debug_info_t *pci_debug_msg_id;
104debug_info_t *pci_debug_err_id;
101 105
102static inline int irq_to_msi_nr(unsigned int irq) 106static inline int irq_to_msi_nr(unsigned int irq)
103{ 107{
@@ -216,6 +220,7 @@ struct mod_pci_args {
216 u64 base; 220 u64 base;
217 u64 limit; 221 u64 limit;
218 u64 iota; 222 u64 iota;
223 u64 fmb_addr;
219}; 224};
220 225
221static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args) 226static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args)
@@ -232,6 +237,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args
232 fib->pba = args->base; 237 fib->pba = args->base;
233 fib->pal = args->limit; 238 fib->pal = args->limit;
234 fib->iota = args->iota; 239 fib->iota = args->iota;
240 fib->fmb_addr = args->fmb_addr;
235 241
236 rc = mpcifc_instr(req, fib); 242 rc = mpcifc_instr(req, fib);
237 free_page((unsigned long) fib); 243 free_page((unsigned long) fib);
@@ -242,7 +248,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args
242int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas, 248int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
243 u64 base, u64 limit, u64 iota) 249 u64 base, u64 limit, u64 iota)
244{ 250{
245 struct mod_pci_args args = { base, limit, iota }; 251 struct mod_pci_args args = { base, limit, iota, 0 };
246 252
247 WARN_ON_ONCE(iota & 0x3fff); 253 WARN_ON_ONCE(iota & 0x3fff);
248 args.iota |= ZPCI_IOTA_RTTO_FLAG; 254 args.iota |= ZPCI_IOTA_RTTO_FLAG;
@@ -252,7 +258,7 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
252/* Modify PCI: Unregister I/O address translation parameters */ 258/* Modify PCI: Unregister I/O address translation parameters */
253int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas) 259int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
254{ 260{
255 struct mod_pci_args args = { 0, 0, 0 }; 261 struct mod_pci_args args = { 0, 0, 0, 0 };
256 262
257 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args); 263 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args);
258} 264}
@@ -260,11 +266,46 @@ int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
260/* Modify PCI: Unregister adapter interruptions */ 266/* Modify PCI: Unregister adapter interruptions */
261static int zpci_unregister_airq(struct zpci_dev *zdev) 267static int zpci_unregister_airq(struct zpci_dev *zdev)
262{ 268{
263 struct mod_pci_args args = { 0, 0, 0 }; 269 struct mod_pci_args args = { 0, 0, 0, 0 };
264 270
265 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args); 271 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args);
266} 272}
267 273
274/* Modify PCI: Set PCI function measurement parameters */
275int zpci_fmb_enable_device(struct zpci_dev *zdev)
276{
277 struct mod_pci_args args = { 0, 0, 0, 0 };
278
279 if (zdev->fmb)
280 return -EINVAL;
281
282 zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL);
283 if (!zdev->fmb)
284 return -ENOMEM;
285 memset(zdev->fmb, 0, sizeof(*zdev->fmb));
286 WARN_ON((u64) zdev->fmb & 0xf);
287
288 args.fmb_addr = virt_to_phys(zdev->fmb);
289 return mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
290}
291
292/* Modify PCI: Disable PCI function measurement */
293int zpci_fmb_disable_device(struct zpci_dev *zdev)
294{
295 struct mod_pci_args args = { 0, 0, 0, 0 };
296 int rc;
297
298 if (!zdev->fmb)
299 return -EINVAL;
300
301 /* Function measurement is disabled if fmb address is zero */
302 rc = mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
303
304 kmem_cache_free(zdev_fmb_cache, zdev->fmb);
305 zdev->fmb = NULL;
306 return rc;
307}
308
268#define ZPCI_PCIAS_CFGSPC 15 309#define ZPCI_PCIAS_CFGSPC 15
269 310
270static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) 311static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)
@@ -633,6 +674,7 @@ static void zpci_remove_device(struct pci_dev *pdev)
633 dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); 674 dev_info(&pdev->dev, "Removing device %u\n", zdev->domain);
634 zdev->state = ZPCI_FN_STATE_CONFIGURED; 675 zdev->state = ZPCI_FN_STATE_CONFIGURED;
635 zpci_dma_exit_device(zdev); 676 zpci_dma_exit_device(zdev);
677 zpci_fmb_disable_device(zdev);
636 zpci_sysfs_remove_device(&pdev->dev); 678 zpci_sysfs_remove_device(&pdev->dev);
637 zpci_unmap_resources(pdev); 679 zpci_unmap_resources(pdev);
638 list_del(&zdev->entry); /* can be called from init */ 680 list_del(&zdev->entry); /* can be called from init */
@@ -799,6 +841,16 @@ static void zpci_irq_exit(void)
799 kfree(bucket); 841 kfree(bucket);
800} 842}
801 843
844void zpci_debug_info(struct zpci_dev *zdev, struct seq_file *m)
845{
846 if (!zdev)
847 return;
848
849 seq_printf(m, "global irq retries: %u\n", atomic_read(&irq_retries));
850 seq_printf(m, "aibv[0]:%016lx aibv[1]:%016lx aisb:%016lx\n",
851 get_imap(0)->aibv, get_imap(1)->aibv, *bucket->aisb);
852}
853
802static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, 854static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
803 unsigned long flags, int domain) 855 unsigned long flags, int domain)
804{ 856{
@@ -994,6 +1046,8 @@ int zpci_scan_device(struct zpci_dev *zdev)
994 goto out; 1046 goto out;
995 } 1047 }
996 1048
1049 zpci_debug_init_device(zdev);
1050 zpci_fmb_enable_device(zdev);
997 zpci_map_resources(zdev); 1051 zpci_map_resources(zdev);
998 pci_bus_add_devices(zdev->bus); 1052 pci_bus_add_devices(zdev->bus);
999 1053
@@ -1020,6 +1074,11 @@ static int zpci_mem_init(void)
1020 if (!zdev_irq_cache) 1074 if (!zdev_irq_cache)
1021 goto error_zdev; 1075 goto error_zdev;
1022 1076
1077 zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
1078 16, 0, NULL);
1079 if (!zdev_fmb_cache)
1080 goto error_fmb;
1081
1023 /* TODO: use realloc */ 1082 /* TODO: use realloc */
1024 zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), 1083 zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
1025 GFP_KERNEL); 1084 GFP_KERNEL);
@@ -1028,6 +1087,8 @@ static int zpci_mem_init(void)
1028 return 0; 1087 return 0;
1029 1088
1030error_iomap: 1089error_iomap:
1090 kmem_cache_destroy(zdev_fmb_cache);
1091error_fmb:
1031 kmem_cache_destroy(zdev_irq_cache); 1092 kmem_cache_destroy(zdev_irq_cache);
1032error_zdev: 1093error_zdev:
1033 return -ENOMEM; 1094 return -ENOMEM;
@@ -1037,6 +1098,7 @@ static void zpci_mem_exit(void)
1037{ 1098{
1038 kfree(zpci_iomap_start); 1099 kfree(zpci_iomap_start);
1039 kmem_cache_destroy(zdev_irq_cache); 1100 kmem_cache_destroy(zdev_irq_cache);
1101 kmem_cache_destroy(zdev_fmb_cache);
1040} 1102}
1041 1103
1042unsigned int pci_probe = 1; 1104unsigned int pci_probe = 1;
@@ -1066,6 +1128,10 @@ static int __init pci_base_init(void)
1066 test_facility(69), test_facility(70), 1128 test_facility(69), test_facility(70),
1067 test_facility(71)); 1129 test_facility(71));
1068 1130
1131 rc = zpci_debug_init();
1132 if (rc)
1133 return rc;
1134
1069 rc = zpci_mem_init(); 1135 rc = zpci_mem_init();
1070 if (rc) 1136 if (rc)
1071 goto out_mem; 1137 goto out_mem;
@@ -1098,6 +1164,7 @@ out_irq:
1098out_hash: 1164out_hash:
1099 zpci_mem_exit(); 1165 zpci_mem_exit();
1100out_mem: 1166out_mem:
1167 zpci_debug_exit();
1101 return rc; 1168 return rc;
1102} 1169}
1103subsys_initcall(pci_base_init); 1170subsys_initcall(pci_base_init);
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
index 7f4ce8d874a4..2c847143cbd1 100644
--- a/arch/s390/pci/pci_clp.c
+++ b/arch/s390/pci/pci_clp.c
@@ -51,6 +51,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
51 zdev->tlb_refresh = response->refresh; 51 zdev->tlb_refresh = response->refresh;
52 zdev->dma_mask = response->dasm; 52 zdev->dma_mask = response->dasm;
53 zdev->msi_addr = response->msia; 53 zdev->msi_addr = response->msia;
54 zdev->fmb_update = response->mui;
54 55
55 pr_debug("Supported number of MSI vectors: %u\n", response->noi); 56 pr_debug("Supported number of MSI vectors: %u\n", response->noi);
56 switch (response->version) { 57 switch (response->version) {
diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c
new file mode 100644
index 000000000000..a303c95346cb
--- /dev/null
+++ b/arch/s390/pci/pci_debug.c
@@ -0,0 +1,193 @@
1/*
2 * Copyright IBM Corp. 2012
3 *
4 * Author(s):
5 * Jan Glauber <jang@linux.vnet.ibm.com>
6 */
7
8#define COMPONENT "zPCI"
9#define pr_fmt(fmt) COMPONENT ": " fmt
10
11#include <linux/kernel.h>
12#include <linux/seq_file.h>
13#include <linux/debugfs.h>
14#include <linux/pci.h>
15#include <asm/debug.h>
16
17#include <asm/pci_dma.h>
18
19static struct dentry *debugfs_root;
20
21static char *pci_perf_names[] = {
22 /* hardware counters */
23 "Load operations",
24 "Store operations",
25 "Store block operations",
26 "Refresh operations",
27 "DMA read bytes",
28 "DMA write bytes",
29 /* software counters */
30 "Allocated pages",
31 "Mapped pages",
32 "Unmapped pages",
33};
34
35static int pci_perf_show(struct seq_file *m, void *v)
36{
37 struct zpci_dev *zdev = m->private;
38 u64 *stat;
39 int i;
40
41 if (!zdev)
42 return 0;
43 if (!zdev->fmb)
44 return seq_printf(m, "FMB statistics disabled\n");
45
46 /* header */
47 seq_printf(m, "FMB @ %p\n", zdev->fmb);
48 seq_printf(m, "Update interval: %u ms\n", zdev->fmb_update);
49 seq_printf(m, "Samples: %u\n", zdev->fmb->samples);
50 seq_printf(m, "Last update TOD: %Lx\n", zdev->fmb->last_update);
51
52 /* hardware counters */
53 stat = (u64 *) &zdev->fmb->ld_ops;
54 for (i = 0; i < 4; i++)
55 seq_printf(m, "%26s:\t%llu\n",
56 pci_perf_names[i], *(stat + i));
57 if (zdev->fmb->dma_valid)
58 for (i = 4; i < 6; i++)
59 seq_printf(m, "%26s:\t%llu\n",
60 pci_perf_names[i], *(stat + i));
61 /* software counters */
62 for (i = 6; i < ARRAY_SIZE(pci_perf_names); i++)
63 seq_printf(m, "%26s:\t%llu\n",
64 pci_perf_names[i],
65 atomic64_read((atomic64_t *) (stat + i)));
66
67 return 0;
68}
69
70static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
71 size_t count, loff_t *off)
72{
73 struct zpci_dev *zdev = ((struct seq_file *) file->private_data)->private;
74 unsigned long val;
75 int rc;
76
77 if (!zdev)
78 return 0;
79
80 rc = kstrtoul_from_user(ubuf, count, 10, &val);
81 if (rc)
82 return rc;
83
84 switch (val) {
85 case 0:
86 rc = zpci_fmb_disable_device(zdev);
87 if (rc)
88 return rc;
89 break;
90 case 1:
91 rc = zpci_fmb_enable_device(zdev);
92 if (rc)
93 return rc;
94 break;
95 }
96 return count;
97}
98
99static int pci_perf_seq_open(struct inode *inode, struct file *filp)
100{
101 return single_open(filp, pci_perf_show,
102 filp->f_path.dentry->d_inode->i_private);
103}
104
105static const struct file_operations debugfs_pci_perf_fops = {
106 .open = pci_perf_seq_open,
107 .read = seq_read,
108 .write = pci_perf_seq_write,
109 .llseek = seq_lseek,
110 .release = single_release,
111};
112
113static int pci_debug_show(struct seq_file *m, void *v)
114{
115 struct zpci_dev *zdev = m->private;
116
117 zpci_debug_info(zdev, m);
118 return 0;
119}
120
121static int pci_debug_seq_open(struct inode *inode, struct file *filp)
122{
123 return single_open(filp, pci_debug_show,
124 filp->f_path.dentry->d_inode->i_private);
125}
126
127static const struct file_operations debugfs_pci_debug_fops = {
128 .open = pci_debug_seq_open,
129 .read = seq_read,
130 .llseek = seq_lseek,
131 .release = single_release,
132};
133
134void zpci_debug_init_device(struct zpci_dev *zdev)
135{
136 zdev->debugfs_dev = debugfs_create_dir(dev_name(&zdev->pdev->dev),
137 debugfs_root);
138 if (IS_ERR(zdev->debugfs_dev))
139 zdev->debugfs_dev = NULL;
140
141 zdev->debugfs_perf = debugfs_create_file("statistics",
142 S_IFREG | S_IRUGO | S_IWUSR,
143 zdev->debugfs_dev, zdev,
144 &debugfs_pci_perf_fops);
145 if (IS_ERR(zdev->debugfs_perf))
146 zdev->debugfs_perf = NULL;
147
148 zdev->debugfs_debug = debugfs_create_file("debug",
149 S_IFREG | S_IRUGO | S_IWUSR,
150 zdev->debugfs_dev, zdev,
151 &debugfs_pci_debug_fops);
152 if (IS_ERR(zdev->debugfs_debug))
153 zdev->debugfs_debug = NULL;
154}
155
156void zpci_debug_exit_device(struct zpci_dev *zdev)
157{
158 debugfs_remove(zdev->debugfs_perf);
159 debugfs_remove(zdev->debugfs_debug);
160 debugfs_remove(zdev->debugfs_dev);
161}
162
163int __init zpci_debug_init(void)
164{
165 /* event trace buffer */
166 pci_debug_msg_id = debug_register("pci_msg", 16, 1, 16 * sizeof(long));
167 if (!pci_debug_msg_id)
168 return -EINVAL;
169 debug_register_view(pci_debug_msg_id, &debug_sprintf_view);
170 debug_set_level(pci_debug_msg_id, 3);
171 zpci_dbg("Debug view initialized\n");
172
173 /* error log */
174 pci_debug_err_id = debug_register("pci_error", 2, 1, 16);
175 if (!pci_debug_err_id)
176 return -EINVAL;
177 debug_register_view(pci_debug_err_id, &debug_hex_ascii_view);
178 debug_set_level(pci_debug_err_id, 6);
179 zpci_err("Debug view initialized\n");
180
181 debugfs_root = debugfs_create_dir("pci", NULL);
182 return 0;
183}
184
185void zpci_debug_exit(void)
186{
187 if (pci_debug_msg_id)
188 debug_unregister(pci_debug_msg_id);
189 if (pci_debug_err_id)
190 debug_unregister(pci_debug_err_id);
191
192 debugfs_remove(debugfs_root);
193}
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index c64b4b294b0a..6138468b420f 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -291,8 +291,10 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
291 if (direction == DMA_NONE || direction == DMA_TO_DEVICE) 291 if (direction == DMA_NONE || direction == DMA_TO_DEVICE)
292 flags |= ZPCI_TABLE_PROTECTED; 292 flags |= ZPCI_TABLE_PROTECTED;
293 293
294 if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) 294 if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) {
295 atomic64_add(nr_pages, (atomic64_t *) &zdev->fmb->mapped_pages);
295 return dma_addr + offset; 296 return dma_addr + offset;
297 }
296 298
297out_free: 299out_free:
298 dma_free_iommu(zdev, iommu_page_index, nr_pages); 300 dma_free_iommu(zdev, iommu_page_index, nr_pages);
@@ -315,6 +317,7 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
315 ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) 317 ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID))
316 dev_err(dev, "Failed to unmap addr: %Lx\n", dma_addr); 318 dev_err(dev, "Failed to unmap addr: %Lx\n", dma_addr);
317 319
320 atomic64_add(npages, (atomic64_t *) &zdev->fmb->unmapped_pages);
318 iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT; 321 iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT;
319 dma_free_iommu(zdev, iommu_page_index, npages); 322 dma_free_iommu(zdev, iommu_page_index, npages);
320} 323}
@@ -323,6 +326,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
323 dma_addr_t *dma_handle, gfp_t flag, 326 dma_addr_t *dma_handle, gfp_t flag,
324 struct dma_attrs *attrs) 327 struct dma_attrs *attrs)
325{ 328{
329 struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
326 struct page *page; 330 struct page *page;
327 unsigned long pa; 331 unsigned long pa;
328 dma_addr_t map; 332 dma_addr_t map;
@@ -331,6 +335,8 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
331 page = alloc_pages(flag, get_order(size)); 335 page = alloc_pages(flag, get_order(size));
332 if (!page) 336 if (!page)
333 return NULL; 337 return NULL;
338
339 atomic64_add(size / PAGE_SIZE, (atomic64_t *) &zdev->fmb->allocated_pages);
334 pa = page_to_phys(page); 340 pa = page_to_phys(page);
335 memset((void *) pa, 0, size); 341 memset((void *) pa, 0, size);
336 342
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
index dbed8cd3370c..ec62e3a0dc09 100644
--- a/arch/s390/pci/pci_event.c
+++ b/arch/s390/pci/pci_event.c
@@ -45,6 +45,8 @@ static void zpci_event_log_err(struct zpci_ccdf_err *ccdf)
45{ 45{
46 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); 46 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
47 47
48 zpci_err("SEI error CCD:\n");
49 zpci_err_hex(ccdf, sizeof(*ccdf));
48 dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec); 50 dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec);
49} 51}
50 52