Skip to content

Commit 7b07786

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 update #2 from Martin Schwidefsky: "The main patch is the function measurement blocks extension for PCI to do performance statistics and help with debugging. The other patch is a small cleanup in ccwdev.h." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/ccwdev: Include asm/schid.h. s390/pci: performance statistics and debug infrastructure
2 parents 16e024f + 1f1c961 commit 7b07786

9 files changed

Lines changed: 350 additions & 8 deletions

File tree

arch/s390/include/asm/ccwdev.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
#include <linux/mod_devicetable.h>
1313
#include <asm/fcx.h>
1414
#include <asm/irq.h>
15+
#include <asm/schid.h>
1516

1617
/* structs from asm/cio.h */
1718
struct irb;
1819
struct ccw1;
1920
struct ccw_dev_id;
2021

21-
/* from asm/schid.h */
22-
struct subchannel_id;
23-
2422
/* simplified initializers for struct ccw_device:
2523
* CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one
2624
* entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */

arch/s390/include/asm/pci.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <asm-generic/pci.h>
1010
#include <asm-generic/pci-dma-compat.h>
1111
#include <asm/pci_clp.h>
12+
#include <asm/pci_debug.h>
1213

1314
#define PCIBIOS_MIN_IO 0x1000
1415
#define PCIBIOS_MIN_MEM 0x10000000
@@ -33,6 +34,25 @@ int pci_proc_domain(struct pci_bus *);
3334
#define ZPCI_FC_BLOCKED 0x20
3435
#define ZPCI_FC_DMA_ENABLED 0x10
3536

37+
struct 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+
3656
struct msi_map {
3757
unsigned long irq;
3858
struct msi_desc *msi;
@@ -92,7 +112,15 @@ struct zpci_dev {
92112
u64 end_dma; /* End of available DMA addresses */
93113
u64 dma_mask; /* DMA address space mask */
94114

115+
/* Function measurement block */
116+
struct zpci_fmb *fmb;
117+
u16 fmb_update; /* update interval */
118+
95119
enum pci_bus_speed max_bus_speed;
120+
121+
struct dentry *debugfs_dev;
122+
struct dentry *debugfs_perf;
123+
struct dentry *debugfs_debug;
96124
};
97125

98126
struct pci_hp_callback_ops {
@@ -155,4 +183,15 @@ extern struct list_head zpci_list;
155183
extern struct pci_hp_callback_ops hotplug_ops;
156184
extern unsigned int pci_probe;
157185

186+
/* FMB */
187+
int zpci_fmb_enable_device(struct zpci_dev *);
188+
int zpci_fmb_disable_device(struct zpci_dev *);
189+
190+
/* Debug */
191+
int zpci_debug_init(void);
192+
void zpci_debug_exit(void);
193+
void zpci_debug_init_device(struct zpci_dev *);
194+
void zpci_debug_exit_device(struct zpci_dev *);
195+
void zpci_debug_info(struct zpci_dev *, struct seq_file *);
196+
158197
#endif

arch/s390/include/asm/pci_debug.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
6+
extern debug_info_t *pci_debug_msg_id;
7+
extern 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+
27+
static 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

arch/s390/pci/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
#
44

55
obj-$(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

arch/s390/pci/pci.c

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ EXPORT_SYMBOL_GPL(zpci_iomap_start);
9898
static int __read_mostly aisb_max;
9999

100100
static struct kmem_cache *zdev_irq_cache;
101+
static struct kmem_cache *zdev_fmb_cache;
102+
103+
debug_info_t *pci_debug_msg_id;
104+
debug_info_t *pci_debug_err_id;
101105

102106
static inline int irq_to_msi_nr(unsigned int irq)
103107
{
@@ -216,6 +220,7 @@ struct mod_pci_args {
216220
u64 base;
217221
u64 limit;
218222
u64 iota;
223+
u64 fmb_addr;
219224
};
220225

221226
static 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
232237
fib->pba = args->base;
233238
fib->pal = args->limit;
234239
fib->iota = args->iota;
240+
fib->fmb_addr = args->fmb_addr;
235241

236242
rc = mpcifc_instr(req, fib);
237243
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
242248
int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
243249
u64 base, u64 limit, u64 iota)
244250
{
245-
struct mod_pci_args args = { base, limit, iota };
251+
struct mod_pci_args args = { base, limit, iota, 0 };
246252

247253
WARN_ON_ONCE(iota & 0x3fff);
248254
args.iota |= ZPCI_IOTA_RTTO_FLAG;
@@ -252,19 +258,54 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
252258
/* Modify PCI: Unregister I/O address translation parameters */
253259
int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
254260
{
255-
struct mod_pci_args args = { 0, 0, 0 };
261+
struct mod_pci_args args = { 0, 0, 0, 0 };
256262

257263
return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args);
258264
}
259265

260266
/* Modify PCI: Unregister adapter interruptions */
261267
static int zpci_unregister_airq(struct zpci_dev *zdev)
262268
{
263-
struct mod_pci_args args = { 0, 0, 0 };
269+
struct mod_pci_args args = { 0, 0, 0, 0 };
264270

265271
return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args);
266272
}
267273

274+
/* Modify PCI: Set PCI function measurement parameters */
275+
int 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 */
293+
int 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+
268309
#define ZPCI_PCIAS_CFGSPC 15
269310

270311
static 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)
633674
dev_info(&pdev->dev, "Removing device %u\n", zdev->domain);
634675
zdev->state = ZPCI_FN_STATE_CONFIGURED;
635676
zpci_dma_exit_device(zdev);
677+
zpci_fmb_disable_device(zdev);
636678
zpci_sysfs_remove_device(&pdev->dev);
637679
zpci_unmap_resources(pdev);
638680
list_del(&zdev->entry); /* can be called from init */
@@ -799,6 +841,16 @@ static void zpci_irq_exit(void)
799841
kfree(bucket);
800842
}
801843

844+
void 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+
802854
static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
803855
unsigned long flags, int domain)
804856
{
@@ -994,6 +1046,8 @@ int zpci_scan_device(struct zpci_dev *zdev)
9941046
goto out;
9951047
}
9961048

1049+
zpci_debug_init_device(zdev);
1050+
zpci_fmb_enable_device(zdev);
9971051
zpci_map_resources(zdev);
9981052
pci_bus_add_devices(zdev->bus);
9991053

@@ -1020,6 +1074,11 @@ static int zpci_mem_init(void)
10201074
if (!zdev_irq_cache)
10211075
goto error_zdev;
10221076

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+
10231082
/* TODO: use realloc */
10241083
zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
10251084
GFP_KERNEL);
@@ -1028,6 +1087,8 @@ static int zpci_mem_init(void)
10281087
return 0;
10291088

10301089
error_iomap:
1090+
kmem_cache_destroy(zdev_fmb_cache);
1091+
error_fmb:
10311092
kmem_cache_destroy(zdev_irq_cache);
10321093
error_zdev:
10331094
return -ENOMEM;
@@ -1037,6 +1098,7 @@ static void zpci_mem_exit(void)
10371098
{
10381099
kfree(zpci_iomap_start);
10391100
kmem_cache_destroy(zdev_irq_cache);
1101+
kmem_cache_destroy(zdev_fmb_cache);
10401102
}
10411103

10421104
unsigned int pci_probe = 1;
@@ -1066,6 +1128,10 @@ static int __init pci_base_init(void)
10661128
test_facility(69), test_facility(70),
10671129
test_facility(71));
10681130

1131+
rc = zpci_debug_init();
1132+
if (rc)
1133+
return rc;
1134+
10691135
rc = zpci_mem_init();
10701136
if (rc)
10711137
goto out_mem;
@@ -1098,6 +1164,7 @@ static int __init pci_base_init(void)
10981164
out_hash:
10991165
zpci_mem_exit();
11001166
out_mem:
1167+
zpci_debug_exit();
11011168
return rc;
11021169
}
11031170
subsys_initcall(pci_base_init);

arch/s390/pci/pci_clp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
5151
zdev->tlb_refresh = response->refresh;
5252
zdev->dma_mask = response->dasm;
5353
zdev->msi_addr = response->msia;
54+
zdev->fmb_update = response->mui;
5455

5556
pr_debug("Supported number of MSI vectors: %u\n", response->noi);
5657
switch (response->version) {

0 commit comments

Comments
 (0)