s390/pci: add locking for fmb access
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Fri, 10 Apr 2015 12:34:33 +0000 (14:34 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 15 Apr 2015 10:23:53 +0000 (12:23 +0200)
Function measurement can be toggled at runtime. Make sure that
all access to the fmb is protected via a mutex.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/pci.h
arch/s390/pci/pci.c
arch/s390/pci/pci_debug.c

index d318e38..a648338 100644 (file)
@@ -7,6 +7,7 @@
 #define PCI_BAR_COUNT  6
 
 #include <linux/pci.h>
+#include <linux/mutex.h>
 #include <asm-generic/pci.h>
 #include <asm-generic/pci-dma-compat.h>
 #include <asm/pci_clp.h>
@@ -76,6 +77,7 @@ struct zpci_dev {
        u8              pft;            /* pci function type */
        u16             domain;
 
+       struct mutex lock;
        u8 pfip[CLP_PFIP_NR_SEGMENTS];  /* pci function internal path */
        u32 uid;                        /* user defined id */
        u8 util_str[CLP_UTIL_STR_LEN];  /* utility string */
index 2818938..598f023 100644 (file)
@@ -827,6 +827,7 @@ int zpci_create_device(struct zpci_dev *zdev)
        if (rc)
                goto out;
 
+       mutex_init(&zdev->lock);
        if (zdev->state == ZPCI_FN_STATE_CONFIGURED) {
                rc = zpci_enable_device(zdev);
                if (rc)
index 97db1a4..3fc9b4d 100644 (file)
@@ -58,8 +58,12 @@ static int pci_perf_show(struct seq_file *m, void *v)
 
        if (!zdev)
                return 0;
-       if (!zdev->fmb)
+
+       mutex_lock(&zdev->lock);
+       if (!zdev->fmb) {
+               mutex_unlock(&zdev->lock);
                return seq_printf(m, "FMB statistics disabled\n");
+       }
 
        /* header */
        seq_printf(m, "FMB @ %p\n", zdev->fmb);
@@ -78,6 +82,7 @@ static int pci_perf_show(struct seq_file *m, void *v)
                                   pci_perf_names[i], *(stat + i));
 
        pci_sw_counter_show(m);
+       mutex_unlock(&zdev->lock);
        return 0;
 }
 
@@ -95,19 +100,17 @@ static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
        if (rc)
                return rc;
 
+       mutex_lock(&zdev->lock);
        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;
+       mutex_unlock(&zdev->lock);
+       return rc ? rc : count;
 }
 
 static int pci_perf_seq_open(struct inode *inode, struct file *filp)