s390 patches for the 3.8 merge window #2
Hi Linus,
please pull from the 'for-linus' branch of
git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git for-linus
to receive the following updates:
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.
Cornelia Huck (1):
s390/ccwdev: Include asm/schid.h.
Jan Glauber (1):
s390/pci: performance statistics and debug infrastructure
arch/s390/include/asm/ccwdev.h | 4 +- arch/s390/include/asm/pci.h | 39 ++++++++ arch/s390/include/asm/pci_debug.h | 36 +++++++ arch/s390/pci/Makefile | 2 +- arch/s390/pci/pci.c | 73 +++++++++++++- arch/s390/pci/pci_clp.c | 1 + arch/s390/pci/pci_debug.c | 193 +++++++++++++++++++++++++++++++++++++ arch/s390/pci/pci_dma.c | 8 +- arch/s390/pci/pci_event.c | 2 + 9 files changed, 350 insertions(+), 8 deletions(-) create mode 100644 arch/s390/include/asm/pci_debug.h create mode 100644 arch/s390/pci/pci_debug.c
arch/s390/include/asm/ccwdev.h +1 -3
@@ -12,15 +12,13 @@#include <linux/mod_devicetable.h> #include <asm/fcx.h> #include <asm/irq.h> +#include <asm/schid.h> /* structs from asm/cio.h */ struct irb ;struct ccw1 ;struct ccw_dev_id ; -/* from asm/schid.h */ -struct subchannel_id ; -/* simplified initializers for struct ccw_device: * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */
arch/s390/include/asm/pci.h +39 -0
@@ -9,6 +9,7 @@#include <asm-generic/pci.h> #include <asm-generic/pci-dma-compat.h> #include <asm/pci_clp.h> +#include <asm/pci_debug.h> #define PCIBIOS_MIN_IO 0x1000#define PCIBIOS_MIN_MEM 0x10000000
@@ -33,6 +34,25 @@ int pci_proc_domain(struct pci_bus *);#define ZPCI_FC_BLOCKED 0x20#define ZPCI_FC_DMA_ENABLED 0x10 +struct zpci_fmb { +u32 format :8 ; +u32 dma_valid :1 ; + u32 : 23; +u32 samples; +u64 last_update; +/* hardware counters */ +u64 ld_ops; +u64 st_ops; +u64 stb_ops; +u64 rpcit_ops; +u64 dma_rbytes; +u64 dma_wbytes; +/* software counters */ +atomic64_t allocated_pages; +atomic64_t mapped_pages; +atomic64_t unmapped_pages; +} __packed__aligned(16) ; +struct msi_map {unsigned long irq;struct msi_desc *msi;
@@ -92,7 +112,15 @@ struct zpci_dev {u64 end_dma;/* End of available DMA addresses */ u64 dma_mask;/* DMA address space mask */ +/* Function measurement block */ +struct zpci_fmb *fmb; +u16 fmb_update;/* update interval */ +enum pci_bus_speed max_bus_speed; + +struct dentry *debugfs_dev; +struct dentry *debugfs_perf; +struct dentry *debugfs_debug; };struct pci_hp_callback_ops {
@@ -155,4 +183,15 @@ extern struct list_head zpci_list;extern struct pci_hp_callback_ops hotplug_ops;extern unsigned int pci_probe; +/* FMB */ +int zpci_fmb_enable_device (struct zpci_dev *); +int zpci_fmb_disable_device (struct zpci_dev *); + +/* Debug */ +int zpci_debug_init (void ); +void zpci_debug_exit (void ); +void zpci_debug_init_device (struct zpci_dev *); +void zpci_debug_exit_device (struct zpci_dev *); +void zpci_debug_info (struct zpci_dev *,struct seq_file *); +#endif
arch/s390/include/asm/pci_debug.h new file +36 -0
@@ -0,0 +1,36 @@ +#ifndef _S390_ASM_PCI_DEBUG_H +#define _S390_ASM_PCI_DEBUG_H + +#include <asm/debug.h> + +extern debug_info_t *pci_debug_msg_id; +extern debug_info_t *pci_debug_err_id; + +#ifdef CONFIG_PCI_DEBUG +#define zpci_dbg(fmt, args...) \ + do { \ + if (pci_debug_msg_id->level >= 2) \ + debug_sprintf_event(pci_debug_msg_id, 2, fmt , ## args);\ + } while (0) + +#else /* !CONFIG_PCI_DEBUG */ +#define zpci_dbg(fmt, args...) do { } while (0) +#endif + +#define zpci_err(text...) \ + do { \ + char debug_buffer[16]; \ + snprintf(debug_buffer, 16, text); \ + debug_text_event(pci_debug_err_id, 0, debug_buffer); \ + } while (0) + +static inline void zpci_err_hex (void *addr,int len) +{ +while (len >0 ) { +debug_event (pci_debug_err_id,0 , (void *) addr, len); + len -= pci_debug_err_id->buf_size; + addr += pci_debug_err_id->buf_size; + } +} + +#endif
arch/s390/pci/Makefile +1 -1
@@ -3,4 +3,4 @@ # obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \ - pci_sysfs.o pci_event.o + pci_sysfs.o pci_event.o pci_debug.o
arch/s390/pci/pci.c +70 -3
161 lines not on this page · raw message
arch/s390/pci/pci_clp.c +1 -0
@@ -51,6 +51,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev, zdev->tlb_refresh = response->refresh; zdev->dma_mask = response->dasm; zdev->msi_addr = response->msia; + zdev->fmb_update = response->mui;pr_debug ("Supported number of MSI vectors: %u\n" , response->noi);switch (response->version) {
arch/s390/pci/pci_debug.c new file +193 -0
193 lines not on this page · raw message
arch/s390/pci/pci_dma.c +7 -1
@@ -291,8 +291,10 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,if (direction ==DMA_NONE || direction ==DMA_TO_DEVICE ) flags |=ZPCI_TABLE_PROTECTED ; -if (!dma_update_trans (zdev, pa, dma_addr, size, flags)) +if (!dma_update_trans (zdev, pa, dma_addr, size, flags)) { +atomic64_add (nr_pages, (atomic64_t *) &zdev->fmb->mapped_pages);return dma_addr + offset; + } out_free: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, ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID))dev_err (dev,"Failed to unmap addr: %Lx\n" , dma_addr); +atomic64_add (npages, (atomic64_t *) &zdev->fmb->unmapped_pages); iommu_page_index = (dma_addr - zdev->start_dma) >>PAGE_SHIFT ;dma_free_iommu (zdev, iommu_page_index, npages); }
@@ -323,6 +326,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs) { + struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));struct page *page;unsigned long pa;dma_addr_t map;
@@ -331,6 +335,8 @@ static void *s390_dma_alloc(struct device *dev, size_t size, page =alloc_pages (flag,get_order (size));if (!page)return NULL ; + +atomic64_add (size /PAGE_SIZE , (atomic64_t *) &zdev->fmb->allocated_pages); pa =page_to_phys (page);memset ((void *) pa,0 , size);
arch/s390/pci/pci_event.c +2 -0
@@ -45,6 +45,8 @@ static void zpci_event_log_err(struct zpci_ccdf_err *ccdf) {struct zpci_dev *zdev =get_zdev_by_fid (ccdf->fid); +zpci_err ("SEI error CCD:\n" ); +zpci_err_hex (ccdf,sizeof (*ccdf));dev_err (&zdev->pdev->dev,"event code: 0x%x\n" , ccdf->pec); }