IB/qib: Correct nfreectxts for multiple HCAs
authorMike Marciniszyn <mike.marciniszyn@qlogic.com>
Thu, 6 Oct 2011 16:33:35 +0000 (09:33 -0700)
committerRoland Dreier <roland@purestorage.com>
Thu, 6 Oct 2011 16:33:35 +0000 (09:33 -0700)
The code that was recently introduced to report the number
of free contexts is flawed for multiple HCAs:

       /* Return the number of free user ports (contexts) available. */
       return scnprintf(buf, PAGE_SIZE, "%u\n", dd->cfgctxts -
                dd->first_user_ctxt - (u32)qib_stats.sps_ctxts);

The qib_stats is global to the module, not per HCA, so the code is broken
for multiple HCAs.

This patch adds a qib_devdata field, freectxts, that reflects the free
contexts for this HCA.

Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Reviewed-by: Ram Vepa <ram.vepa@qlogic.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/qib/qib.h
drivers/infiniband/hw/qib/qib_file_ops.c
drivers/infiniband/hw/qib/qib_init.c
drivers/infiniband/hw/qib/qib_sysfs.c

index c9624ea872098a6c5b36b285620d63633eade977..ee993e725d38e36d883180bc4e34ca6b2d862d79 100644 (file)
@@ -807,6 +807,10 @@ struct qib_devdata {
         * supports, less gives more pio bufs/ctxt, etc.
         */
        u32 cfgctxts;
+       /*
+        * number of ctxts available for PSM open
+        */
+       u32 freectxts;
 
        /*
         * hint that we should update pioavailshadow before
index 26253039d2c7117a1d45f3c9afd13ee804406c93..77633666f81c385edafc326a815797896a919068 100644 (file)
@@ -1284,6 +1284,7 @@ static int setup_ctxt(struct qib_pportdata *ppd, int ctxt,
        strlcpy(rcd->comm, current->comm, sizeof(rcd->comm));
        ctxt_fp(fp) = rcd;
        qib_stats.sps_ctxts++;
+       dd->freectxts++;
        ret = 0;
        goto bail;
 
@@ -1792,6 +1793,7 @@ static int qib_close(struct inode *in, struct file *fp)
                if (dd->pageshadow)
                        unlock_expected_tids(rcd);
                qib_stats.sps_ctxts--;
+               dd->freectxts--;
        }
 
        mutex_unlock(&qib_mutex);
index a01f3fce8eb3f10616efe2e31e6ec2b660df9c65..021636dbeae69ea62d091af071f090b5263c4c2b 100644 (file)
@@ -398,6 +398,7 @@ static void enable_chip(struct qib_devdata *dd)
                if (rcd)
                        dd->f_rcvctrl(rcd->ppd, rcvmask, i);
        }
+       dd->freectxts = dd->cfgctxts - dd->first_user_ctxt;
 }
 
 static void verify_interrupt(unsigned long opaque)
index 14d129de43207e9385449402e6e5506068e656a6..78fbd56879d417610fc4b88dd4898741b56843d3 100644 (file)
@@ -515,8 +515,7 @@ static ssize_t show_nfreectxts(struct device *device,
        struct qib_devdata *dd = dd_from_dev(dev);
 
        /* Return the number of free user ports (contexts) available. */
-       return scnprintf(buf, PAGE_SIZE, "%u\n", dd->cfgctxts -
-               dd->first_user_ctxt - (u32)qib_stats.sps_ctxts);
+       return scnprintf(buf, PAGE_SIZE, "%u\n", dd->freectxts);
 }
 
 static ssize_t show_serial(struct device *device,