Commit 7b077868 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 16e024f3 1f1c9610
...@@ -12,15 +12,13 @@ ...@@ -12,15 +12,13 @@
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <asm/fcx.h> #include <asm/fcx.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/schid.h>
/* structs from asm/cio.h */ /* structs from asm/cio.h */
struct irb; struct irb;
struct ccw1; struct ccw1;
struct ccw_dev_id; struct ccw_dev_id;
/* from asm/schid.h */
struct subchannel_id;
/* simplified initializers for struct ccw_device: /* simplified initializers for struct ccw_device:
* CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one
* entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */ * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <asm-generic/pci.h> #include <asm-generic/pci.h>
#include <asm-generic/pci-dma-compat.h> #include <asm-generic/pci-dma-compat.h>
#include <asm/pci_clp.h> #include <asm/pci_clp.h>
#include <asm/pci_debug.h>
#define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x10000000 #define PCIBIOS_MIN_MEM 0x10000000
...@@ -33,6 +34,25 @@ int pci_proc_domain(struct pci_bus *); ...@@ -33,6 +34,25 @@ int pci_proc_domain(struct pci_bus *);
#define ZPCI_FC_BLOCKED 0x20 #define ZPCI_FC_BLOCKED 0x20
#define ZPCI_FC_DMA_ENABLED 0x10 #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 { struct msi_map {
unsigned long irq; unsigned long irq;
struct msi_desc *msi; struct msi_desc *msi;
...@@ -92,7 +112,15 @@ struct zpci_dev { ...@@ -92,7 +112,15 @@ struct zpci_dev {
u64 end_dma; /* End of available DMA addresses */ u64 end_dma; /* End of available DMA addresses */
u64 dma_mask; /* DMA address space mask */ 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; enum pci_bus_speed max_bus_speed;
struct dentry *debugfs_dev;
struct dentry *debugfs_perf;
struct dentry *debugfs_debug;
}; };
struct pci_hp_callback_ops { struct pci_hp_callback_ops {
...@@ -155,4 +183,15 @@ extern struct list_head zpci_list; ...@@ -155,4 +183,15 @@ extern struct list_head zpci_list;
extern struct pci_hp_callback_ops hotplug_ops; extern struct pci_hp_callback_ops hotplug_ops;
extern unsigned int pci_probe; 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 #endif
#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
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
# #
obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \ 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
...@@ -98,6 +98,10 @@ EXPORT_SYMBOL_GPL(zpci_iomap_start); ...@@ -98,6 +98,10 @@ EXPORT_SYMBOL_GPL(zpci_iomap_start);
static int __read_mostly aisb_max; static int __read_mostly aisb_max;
static struct kmem_cache *zdev_irq_cache; static struct kmem_cache *zdev_irq_cache;
static struct kmem_cache *zdev_fmb_cache;
debug_info_t *pci_debug_msg_id;
debug_info_t *pci_debug_err_id;
static inline int irq_to_msi_nr(unsigned int irq) static inline int irq_to_msi_nr(unsigned int irq)
{ {
...@@ -216,6 +220,7 @@ struct mod_pci_args { ...@@ -216,6 +220,7 @@ struct mod_pci_args {
u64 base; u64 base;
u64 limit; u64 limit;
u64 iota; u64 iota;
u64 fmb_addr;
}; };
static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args) 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 ...@@ -232,6 +237,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args
fib->pba = args->base; fib->pba = args->base;
fib->pal = args->limit; fib->pal = args->limit;
fib->iota = args->iota; fib->iota = args->iota;
fib->fmb_addr = args->fmb_addr;
rc = mpcifc_instr(req, fib); rc = mpcifc_instr(req, fib);
free_page((unsigned long) fib); 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 ...@@ -242,7 +248,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args
int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas, int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
u64 base, u64 limit, u64 iota) u64 base, u64 limit, u64 iota)
{ {
struct mod_pci_args args = { base, limit, iota }; struct mod_pci_args args = { base, limit, iota, 0 };
WARN_ON_ONCE(iota & 0x3fff); WARN_ON_ONCE(iota & 0x3fff);
args.iota |= ZPCI_IOTA_RTTO_FLAG; args.iota |= ZPCI_IOTA_RTTO_FLAG;
...@@ -252,7 +258,7 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas, ...@@ -252,7 +258,7 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
/* Modify PCI: Unregister I/O address translation parameters */ /* Modify PCI: Unregister I/O address translation parameters */
int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas) int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
{ {
struct mod_pci_args args = { 0, 0, 0 }; struct mod_pci_args args = { 0, 0, 0, 0 };
return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args); return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args);
} }
...@@ -260,11 +266,46 @@ int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas) ...@@ -260,11 +266,46 @@ int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
/* Modify PCI: Unregister adapter interruptions */ /* Modify PCI: Unregister adapter interruptions */
static int zpci_unregister_airq(struct zpci_dev *zdev) static int zpci_unregister_airq(struct zpci_dev *zdev)
{ {
struct mod_pci_args args = { 0, 0, 0 }; struct mod_pci_args args = { 0, 0, 0, 0 };
return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args); return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args);
} }
/* Modify PCI: Set PCI function measurement parameters */
int zpci_fmb_enable_device(struct zpci_dev *zdev)
{
struct mod_pci_args args = { 0, 0, 0, 0 };
if (zdev->fmb)
return -EINVAL;
zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL);
if (!zdev->fmb)
return -ENOMEM;
memset(zdev->fmb, 0, sizeof(*zdev->fmb));
WARN_ON((u64) zdev->fmb & 0xf);
args.fmb_addr = virt_to_phys(zdev->fmb);
return mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
}
/* Modify PCI: Disable PCI function measurement */
int zpci_fmb_disable_device(struct zpci_dev *zdev)
{
struct mod_pci_args args = { 0, 0, 0, 0 };
int rc;
if (!zdev->fmb)
return -EINVAL;
/* Function measurement is disabled if fmb address is zero */
rc = mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
kmem_cache_free(zdev_fmb_cache, zdev->fmb);
zdev->fmb = NULL;
return rc;
}
#define ZPCI_PCIAS_CFGSPC 15 #define ZPCI_PCIAS_CFGSPC 15
static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) 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) ...@@ -633,6 +674,7 @@ static void zpci_remove_device(struct pci_dev *pdev)
dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); dev_info(&pdev->dev, "Removing device %u\n", zdev->domain);
zdev->state = ZPCI_FN_STATE_CONFIGURED; zdev->state = ZPCI_FN_STATE_CONFIGURED;
zpci_dma_exit_device(zdev); zpci_dma_exit_device(zdev);
zpci_fmb_disable_device(zdev);
zpci_sysfs_remove_device(&pdev->dev); zpci_sysfs_remove_device(&pdev->dev);
zpci_unmap_resources(pdev); zpci_unmap_resources(pdev);
list_del(&zdev->entry); /* can be called from init */ list_del(&zdev->entry); /* can be called from init */
...@@ -799,6 +841,16 @@ static void zpci_irq_exit(void) ...@@ -799,6 +841,16 @@ static void zpci_irq_exit(void)
kfree(bucket); kfree(bucket);
} }
void zpci_debug_info(struct zpci_dev *zdev, struct seq_file *m)
{
if (!zdev)
return;
seq_printf(m, "global irq retries: %u\n", atomic_read(&irq_retries));
seq_printf(m, "aibv[0]:%016lx aibv[1]:%016lx aisb:%016lx\n",
get_imap(0)->aibv, get_imap(1)->aibv, *bucket->aisb);
}
static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
unsigned long flags, int domain) unsigned long flags, int domain)
{ {
...@@ -994,6 +1046,8 @@ int zpci_scan_device(struct zpci_dev *zdev) ...@@ -994,6 +1046,8 @@ int zpci_scan_device(struct zpci_dev *zdev)
goto out; goto out;
} }
zpci_debug_init_device(zdev);
zpci_fmb_enable_device(zdev);
zpci_map_resources(zdev); zpci_map_resources(zdev);
pci_bus_add_devices(zdev->bus); pci_bus_add_devices(zdev->bus);
...@@ -1020,6 +1074,11 @@ static int zpci_mem_init(void) ...@@ -1020,6 +1074,11 @@ static int zpci_mem_init(void)
if (!zdev_irq_cache) if (!zdev_irq_cache)
goto error_zdev; goto error_zdev;
zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
16, 0, NULL);
if (!zdev_fmb_cache)
goto error_fmb;
/* TODO: use realloc */ /* TODO: use realloc */
zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
GFP_KERNEL); GFP_KERNEL);
...@@ -1028,6 +1087,8 @@ static int zpci_mem_init(void) ...@@ -1028,6 +1087,8 @@ static int zpci_mem_init(void)
return 0; return 0;
error_iomap: error_iomap:
kmem_cache_destroy(zdev_fmb_cache);
error_fmb:
kmem_cache_destroy(zdev_irq_cache); kmem_cache_destroy(zdev_irq_cache);
error_zdev: error_zdev:
return -ENOMEM; return -ENOMEM;
...@@ -1037,6 +1098,7 @@ static void zpci_mem_exit(void) ...@@ -1037,6 +1098,7 @@ static void zpci_mem_exit(void)
{ {
kfree(zpci_iomap_start); kfree(zpci_iomap_start);
kmem_cache_destroy(zdev_irq_cache); kmem_cache_destroy(zdev_irq_cache);
kmem_cache_destroy(zdev_fmb_cache);
} }
unsigned int pci_probe = 1; unsigned int pci_probe = 1;
...@@ -1066,6 +1128,10 @@ static int __init pci_base_init(void) ...@@ -1066,6 +1128,10 @@ static int __init pci_base_init(void)
test_facility(69), test_facility(70), test_facility(69), test_facility(70),
test_facility(71)); test_facility(71));
rc = zpci_debug_init();
if (rc)
return rc;
rc = zpci_mem_init(); rc = zpci_mem_init();
if (rc) if (rc)
goto out_mem; goto out_mem;
...@@ -1098,6 +1164,7 @@ static int __init pci_base_init(void) ...@@ -1098,6 +1164,7 @@ static int __init pci_base_init(void)
out_hash: out_hash:
zpci_mem_exit(); zpci_mem_exit();
out_mem: out_mem:
zpci_debug_exit();
return rc; return rc;
} }
subsys_initcall(pci_base_init); subsys_initcall(pci_base_init);
...@@ -51,6 +51,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev, ...@@ -51,6 +51,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
zdev->tlb_refresh = response->refresh; zdev->tlb_refresh = response->refresh;
zdev->dma_mask = response->dasm; zdev->dma_mask = response->dasm;
zdev->msi_addr = response->msia; zdev->msi_addr = response->msia;
zdev->fmb_update = response->mui;
pr_debug("Supported number of MSI vectors: %u\n", response->noi); pr_debug("Supported number of MSI vectors: %u\n", response->noi);
switch (response->version) { switch (response->version) {
......
/*
* Copyright IBM Corp. 2012
*
* Author(s):
* Jan Glauber <jang@linux.vnet.ibm.com>
*/
#define COMPONENT "zPCI"
#define pr_fmt(fmt) COMPONENT ": " fmt
#include <linux/kernel.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/pci.h>
#include <asm/debug.h>
#include <asm/pci_dma.h>
static struct dentry *debugfs_root;
static char *pci_perf_names[] = {
/* hardware counters */
"Load operations",
"Store operations",
"Store block operations",
"Refresh operations",
"DMA read bytes",
"DMA write bytes",
/* software counters */
"Allocated pages",
"Mapped pages",
"Unmapped pages",
};
static int pci_perf_show(struct seq_file *m, void *v)
{
struct zpci_dev *zdev = m->private;
u64 *stat;
int i;
if (!zdev)
return 0;
if (!zdev->fmb)
return seq_printf(m, "FMB statistics disabled\n");
/* header */
seq_printf(m, "FMB @ %p\n", zdev->fmb);
seq_printf(m, "Update interval: %u ms\n", zdev->fmb_update);
seq_printf(m, "Samples: %u\n", zdev->fmb->samples);
seq_printf(m, "Last update TOD: %Lx\n", zdev->fmb->last_update);
/* hardware counters */
stat = (u64 *) &zdev->fmb->ld_ops;
for (i = 0; i < 4; i++)
seq_printf(m, "%26s:\t%llu\n",
pci_perf_names[i], *(stat + i));
if (zdev->fmb->dma_valid)
for (i = 4; i < 6; i++)
seq_printf(m, "%26s:\t%llu\n",
pci_perf_names[i], *(stat + i));
/* software counters */
for (i = 6; i < ARRAY_SIZE(pci_perf_names); i++)
seq_printf(m, "%26s:\t%llu\n",
pci_perf_names[i],
atomic64_read((atomic64_t *) (stat + i)));
return 0;
}
static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *off)
{
struct zpci_dev *zdev = ((struct seq_file *) file->private_data)->private;
unsigned long val;
int rc;
if (!zdev)
return 0;
rc = kstrtoul_from_user(ubuf, count, 10, &val);
if (rc)
return rc;
switch (val) {
case 0:
rc = zpci_fmb_disable_device(zdev);
if (rc)
return rc;
break;
case 1:
rc = zpci_fmb_enable_device(zdev);
if (rc)
return rc;
break;
}
return count;
}
static int pci_perf_seq_open(struct inode *inode, struct file *filp)
{
return single_open(filp, pci_perf_show,
filp->f_path.dentry->d_inode->i_private);
}
static const struct file_operations debugfs_pci_perf_fops = {
.open = pci_perf_seq_open,
.read = seq_read,
.write = pci_perf_seq_write,
.llseek = seq_lseek,
.release = single_release,
};
static int pci_debug_show(struct seq_file *m, void *v)
{
struct zpci_dev *zdev = m->private;
zpci_debug_info(zdev, m);
return 0;
}
static int pci_debug_seq_open(struct inode *inode, struct file *filp)
{
return single_open(filp, pci_debug_show,
filp->f_path.dentry->d_inode->i_private);
}
static const struct file_operations debugfs_pci_debug_fops = {
.open = pci_debug_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
void zpci_debug_init_device(struct zpci_dev *zdev)
{
zdev->debugfs_dev = debugfs_create_dir(dev_name(&zdev->pdev->dev),
debugfs_root);
if (IS_ERR(zdev->debugfs_dev))
zdev->debugfs_dev = NULL;
zdev->debugfs_perf = debugfs_create_file("statistics",
S_IFREG | S_IRUGO | S_IWUSR,
zdev->debugfs_dev, zdev,
&debugfs_pci_perf_fops);
if (IS_ERR(zdev->debugfs_perf))
zdev->debugfs_perf = NULL;
zdev->debugfs_debug = debugfs_create_file("debug",
S_IFREG | S_IRUGO | S_IWUSR,
zdev->debugfs_dev, zdev,
&debugfs_pci_debug_fops);
if (IS_ERR(zdev->debugfs_debug))
zdev->debugfs_debug = NULL;
}
void zpci_debug_exit_device(struct zpci_dev *zdev)
{
debugfs_remove(zdev->debugfs_perf);
debugfs_remove(zdev->debugfs_debug);
debugfs_remove(zdev->debugfs_dev);
}
int __init zpci_debug_init(void)
{
/* event trace buffer */
pci_debug_msg_id = debug_register("pci_msg", 16, 1, 16 * sizeof(long));
if (!pci_debug_msg_id)
return -EINVAL;
debug_register_view(pci_debug_msg_id, &debug_sprintf_view);
debug_set_level(pci_debug_msg_id, 3);
zpci_dbg("Debug view initialized\n");
/* error log */
pci_debug_err_id = debug_register("pci_error", 2, 1, 16);
if (!pci_debug_err_id)
return -EINVAL;
debug_register_view(pci_debug_err_id, &debug_hex_ascii_view);
debug_set_level(pci_debug_err_id, 6);
zpci_err("Debug view initialized\n");
debugfs_root = debugfs_create_dir("pci", NULL);
return 0;
}
void zpci_debug_exit(void)
{
if (pci_debug_msg_id)
debug_unregister(pci_debug_msg_id);
if (pci_debug_err_id)
debug_unregister(pci_debug_err_id);
debugfs_remove(debugfs_root);
}
...@@ -291,8 +291,10 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, ...@@ -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) if (direction == DMA_NONE || direction == DMA_TO_DEVICE)
flags |= ZPCI_TABLE_PROTECTED; 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; return dma_addr + offset;
}
out_free: out_free:
dma_free_iommu(zdev, iommu_page_index, nr_pages); 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,6 +317,7 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID))
dev_err(dev, "Failed to unmap addr: %Lx\n", dma_addr); 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; iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT;
dma_free_iommu(zdev, iommu_page_index, npages); dma_free_iommu(zdev, iommu_page_index, npages);
} }
...@@ -323,6 +326,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size, ...@@ -323,6 +326,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag, dma_addr_t *dma_handle, gfp_t flag,
struct dma_attrs *attrs) struct dma_attrs *attrs)
{ {
struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
struct page *page; struct page *page;
unsigned long pa; unsigned long pa;
dma_addr_t map; dma_addr_t map;
...@@ -331,6 +335,8 @@ static void *s390_dma_alloc(struct device *dev, size_t size, ...@@ -331,6 +335,8 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
page = alloc_pages(flag, get_order(size)); page = alloc_pages(flag, get_order(size));
if (!page) if (!page)
return NULL; return NULL;
atomic64_add(size / PAGE_SIZE, (atomic64_t *) &zdev->fmb->allocated_pages);
pa = page_to_phys(page); pa = page_to_phys(page);
memset((void *) pa, 0, size); memset((void *) pa, 0, size);
......
...@@ -45,6 +45,8 @@ static void zpci_event_log_err(struct zpci_ccdf_err *ccdf) ...@@ -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); 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); dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment