]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: Add debugfs for workaround usage statistics
authorTriviño <francisco.trivino@oracle.com>
Fri, 10 Jun 2016 14:44:20 +0000 (16:44 +0200)
committerKnut Omang <knut.omang@oracle.com>
Sun, 3 Jul 2016 14:01:44 +0000 (16:01 +0200)
This commit also adds:

* WA#3714 usage counters and dump info
* Rename 3713 (bug ticket) to 3714 (WA ticket)

Signed-off-by: Triviño <francisco.trivino@oracle.com>
Reviewed-by: Knut Omang <knut.omang@oracle.com>
drivers/infiniband/hw/sif/sif_debug.c
drivers/infiniband/hw/sif/sif_dev.h
drivers/infiniband/hw/sif/sif_qp.c
drivers/infiniband/hw/sif/sif_r3.c
drivers/infiniband/hw/sif/sif_r3.h

index 763f6b4172635650d6a3ea4a573c28e6cf69001b..56ed015b3ee719e7043c1374cef704c8bdd54af8 100644 (file)
@@ -20,6 +20,7 @@
 #include "sif_query.h"
 #include "sif_qp.h"
 #include "sif_defs.h"
+#include "sif_r3.h"
 
 /* A 'reference' element to identify each table type
  */
@@ -41,6 +42,7 @@ struct sif_dfs {
        struct sif_dfs_ref sd_eq;
        struct sif_dfs_ref sd_irq_ch;
        struct sif_dfs_ref sd_ipoffload;
+       struct sif_dfs_ref sd_wa_stats;
 };
 
 /* A simple iterator */
@@ -437,6 +439,57 @@ static const struct file_operations table_fops_rw = {
        .release = sif_seq_release
 };
 
+/**** support for workaround statistics */
+
+static int r_open(struct inode *inode, struct file *file)
+{
+       if (!try_module_get(THIS_MODULE))
+               return -EIO;
+
+       file->private_data = inode->i_private;
+       return 0;
+};
+
+static int r_release(struct inode *inode, struct file *file)
+{
+       module_put(THIS_MODULE);
+       return 0;
+}
+
+static ssize_t rwa_read(struct file *file, char __user *buf, size_t sz, loff_t *off)
+{
+       struct sif_dev *sdev = ((struct sif_dfs_ref *)file->private_data)->sdev;
+       size_t len = 0;
+       struct xchar xc;
+       size_t dump_size = 12000; /* enough space for allocating the workaround statistics dump */
+       char *dump;
+
+       if (*off > 0)
+               return 0;
+
+       dump = kmalloc(dump_size, GFP_KERNEL);
+       if (!dump) {
+               sif_log0(SIF_INFO, "Error allocating temp.storage for wa statistics");
+               return -ENOMEM;
+       }
+
+       memset(dump, 0, dump_size*sizeof(char));
+       xc.buf = dump;
+
+       sif_dfs_print_wa_stats(sdev, xc.buf);
+
+       len = simple_read_from_buffer(buf, sz, off, dump, strlen(dump));
+       kfree(dump);
+
+       return len;
+}
+
+static const struct file_operations wa_fops = {
+       .owner   = THIS_MODULE,
+       .open    = r_open,
+       .read    = rwa_read,
+       .release = r_release,
+};
 
 /* Setup/teardown */
 
@@ -495,6 +548,15 @@ int sif_dfs_register(struct sif_dev *sdev)
                sif_log(sdev, SIF_INFO, "Unable to set up debugfs file for ipoffload qp stat");
                return -ENOMEM;
        }
+       /* Single file for the wa statistics */
+       sdr = &sdev->dfs->sd_wa_stats;
+       sdr->sdev = sdev;
+       df = debugfs_create_file("wa_stats", S_IRUGO, sdev->dfs->root,
+                               (void *)sdr, &wa_fops);
+       if (!df) {
+               sif_log(sdev, SIF_INFO, "Unable to set up debugfs file for wa stat");
+               return -ENOMEM;
+       }
        /* Single file for the int channel coalescing settings */
        sdr = &sdev->dfs->sd_irq_ch;
        sdr->sdev = sdev;
@@ -546,17 +608,6 @@ void sif_dfs_unregister(struct sif_dev *sdev)
 
 /**** support for raw QP state dump */
 
-
-static int rqp_open(struct inode *inode, struct file *file)
-{
-       if (!try_module_get(THIS_MODULE))
-               return -EIO;
-
-       file->private_data = inode->i_private;
-       return 0;
-};
-
-
 static ssize_t rqp_read(struct file *file, char __user *buf, size_t sz, loff_t *off)
 {
        struct sif_qp *qp = (struct sif_qp *)file->private_data;
@@ -597,22 +648,13 @@ static ssize_t rqp_read(struct file *file, char __user *buf, size_t sz, loff_t *
        return len;
 }
 
-
-static int rqp_release(struct inode *inode, struct file *file)
-{
-       module_put(THIS_MODULE);
-       return 0;
-}
-
-
 static const struct file_operations qp_fops = {
        .owner   = THIS_MODULE,
-       .open    = rqp_open,
+       .open    = r_open,
        .read    = rqp_read,
-       .release = rqp_release,
+       .release = r_release,
 };
 
-
 /* TBD: Ref.cnt or other protection probably needed to protect agains "take down" while
  * a query is in progress
  */
index ca133132d9661b9cdbe34d7b201904db0b767ee2..109c3a75aab04b74459eea0422923ed1c9c6bcfe 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "sif_verbs.h"
 
+#include "sif_r3.h"
+
 #define PCI_VENDOR_ID_SUN      0x108e
 #define PCI_DEVICE_ID_PSIF_PF  0x2088
 #define PCI_DEVICE_ID_PSIF_VF  0x2089
@@ -292,7 +294,7 @@ struct sif_dev {
        /* Support for workaround for #3552 - feature_mask create_do_not_evict_qp: */
        u32 dne_qp;
 
-       /* Support for workaround for #3713 */
+       /* Support for WA#3714 */
        u32 flush_qp;
        struct mutex flush_lock;
 
@@ -331,6 +333,8 @@ struct sif_dev {
        /* PSIF is degraded */
        bool degraded;
 
+       /* Owned by sif_r3.c - wa support */
+       struct sif_wa_stats wa_stats;
 };
 
 /* TBD: These should probably come from common pci headers
index 988ed7760e043dee28fcc20048ba7b2d2dea412b..82408cb60313ac0bed87406e6a975c156fbc4e60 100644 (file)
@@ -808,7 +808,7 @@ int modify_qp_hw_wa_qp_retry(struct sif_dev *sdev, struct sif_qp *qp,
                .qp_state        = IB_QPS_ERR
        };
 
-       bool need_wa_3713 = PSIF_REVISION(sdev) <= 3
+       bool need_wa_3714 = PSIF_REVISION(sdev) <= 3
                && IS_PSIF(sdev)
                && qp_attr_mask & IB_QP_STATE && qp_attr->qp_state == IB_QPS_RESET;
 
@@ -820,7 +820,7 @@ int modify_qp_hw_wa_qp_retry(struct sif_dev *sdev, struct sif_qp *qp,
 
        int ret = 0;
 
-       if (need_wa_3713 || need_wa_4074) {
+       if (need_wa_3714 || need_wa_4074) {
                if (qp->type != PSIF_QP_TRANSPORT_MANSP1 && !is_xtgt_qp(qp))
                        ret = pre_process_wa4074(sdev, qp);
 
@@ -830,8 +830,8 @@ int modify_qp_hw_wa_qp_retry(struct sif_dev *sdev, struct sif_qp *qp,
                }
        }
 
-       if (need_wa_3713) {
-               /* Workaround for bug #3713 part 2 - see #3714 */
+       if (need_wa_3714) {
+               /* WA#3714 part 2 - see bug #3714 */
                ret = modify_qp_hw(sdev, qp, &mod_attr, IB_QP_STATE);
                if (ret)
                        sif_log(sdev, SIF_INFO, "implicit modify qp %d to ERR failed - ignoring",
@@ -840,7 +840,7 @@ int modify_qp_hw_wa_qp_retry(struct sif_dev *sdev, struct sif_qp *qp,
 
        ret = modify_qp_hw(sdev, qp, qp_attr, qp_attr_mask);
 
-       if (need_wa_3713 || need_wa_4074) {
+       if (need_wa_3714 || need_wa_4074) {
                struct ib_qp_attr attr = {
                        .qp_state = IB_QPS_RESET
                };
@@ -2273,7 +2273,7 @@ static int reset_qp(struct sif_dev *sdev, struct sif_qp *qp)
        volatile struct psif_qp *qps = &qp->d;
        struct sif_rq *rq = get_rq(sdev, qp);
        struct sif_sq *sq = get_sq(sdev, qp);
-       bool need_wa_3713 = 0;
+       bool need_wa_3714 = 0;
 
        /* Bring down order needed by rev2 according to bug #3480 */
        int ret = poll_wait_for_qp_writeback(sdev, qp);
@@ -2281,15 +2281,15 @@ static int reset_qp(struct sif_dev *sdev, struct sif_qp *qp)
        if (ret)
                goto failed;
 
-       /* WA 3713 special handling */
-       need_wa_3713 = (PSIF_REVISION(sdev) <= 3)
+       /* WA 3714 special handling */
+       need_wa_3714 = (PSIF_REVISION(sdev) <= 3)
                && IS_PSIF(sdev) /* Next check if there is a retry outstanding */
                && !qp->flush_sq_done_wa4074
                && (get_psif_qp_core__retry_tag_committed(&qp->d.state) !=
                        get_psif_qp_core__retry_tag_err(&qp->d.state))
                && (qp->qp_idx != sdev->flush_qp);
 
-       if (need_wa_3713) {
+       if (need_wa_3714) {
                ret = reset_qp_flush_retry(sdev);
                if (ret < 0)
                        sif_log(sdev, SIF_INFO, "Flush_retry special handling failed with ret %d", ret);
index 7bdf3652be0b76e15589b451511ef5ed5a87bf7c..510a287488634aea769c01edf4b69367b711de87 100644 (file)
@@ -363,7 +363,7 @@ int reset_qp_flush_retry(struct sif_dev *sdev)
        mutex_lock(&sdev->flush_lock);
 
        if (!sdev->flush_qp) {
-               sif_log(sdev, SIF_INFO, "special handling WA_3713 failed: flush_qp does not exist");
+               sif_log(sdev, SIF_INFO, "special handling WA_3714 failed: flush_qp does not exist");
                ret = -EINVAL;
                goto err_flush_qp;
        }
@@ -439,15 +439,18 @@ int reset_qp_flush_retry(struct sif_dev *sdev)
                }
        }
 
+       sdev->wa_stats.wa3714[0]++;
        mutex_unlock(&sdev->flush_lock);
        return ret;
 fail:
+       sdev->wa_stats.wa3714[1]++;
        sif_hw_free_flush_qp(sdev);
        sif_hw_allocate_flush_qp(sdev);
        mutex_unlock(&sdev->flush_lock);
        return ret;
 
 err_flush_qp:
+       sdev->wa_stats.wa3714[1]++;
        mutex_unlock(&sdev->flush_lock);
        return ret;
 }
@@ -900,3 +903,15 @@ static u16 cq_walk_wa4074(struct sif_dev *sdev, struct sif_qp *qp, bool *last_se
        spin_unlock_irqrestore(&cq->lock, flags);
        return last_seq;
 }
+
+void sif_dfs_print_wa_stats(struct sif_dev *sdev, char *buf)
+{
+       /* Header */
+       sprintf(buf, "#%7s %10s %10s %20s\n", "WA", "ok", "err", "desc");
+       /* Content */
+       sprintf(buf + strlen(buf), "#%8s %9llu %10llu %20s\n",
+               "WA3714",
+               sdev->wa_stats.wa3714[0],
+               sdev->wa_stats.wa3714[1],
+               "Destroying QPs with a retry in progress");
+}
index 7086483ac2f85bd33bbc97aac045ca1ddee44207..69e4cfba2a9ed5590218105ee51cec5b041d3b85 100644 (file)
 #ifndef _SIF_R3_H
 #define _SIF_R3_H
 
+struct sif_wa_stats {
+       /* Destroying QPs with a retry in progress */
+       u64 wa3714[2];
+};
+
 void sif_r3_pre_init(struct sif_dev *sdev);
 int sif_r3_init(struct sif_dev *sdev);
 void sif_r3_deinit(struct sif_dev *sdev);
 
-/* WA for #3713 */
+/* WA for #3714 */
 int reset_qp_flush_retry(struct sif_dev *sdev);
 void sif_r3_recreate_flush_qp(struct sif_dev *sdev);
 
@@ -27,4 +32,6 @@ int pre_process_wa4074(struct sif_dev *sdev, struct sif_qp *qp);
 int post_process_wa4074(struct sif_dev *sdev, struct sif_qp *qp);
 int sq_flush_wa4074(struct sif_dev *sdev, struct sif_qp *qp);
 
+/* Single file for the wa statistics */
+void sif_dfs_print_wa_stats(struct sif_dev *sdev, char *buf);
 #endif