IB/qib: Eliminate divide/mod in converting idx to egr buf pointer
authorMike Marciniszyn <mike.marciniszyn@qlogic.com>
Fri, 23 Sep 2011 17:16:39 +0000 (13:16 -0400)
committerRoland Dreier <roland@purestorage.com>
Fri, 21 Oct 2011 16:38:52 +0000 (09:38 -0700)
The context init now saves a shift from rcvegrbufs_perchunk
rcvegrbufs_perchunk_shift using ilog2.   A BUG_ON() protects the
power of 2 assumption.

Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/qib/qib.h
drivers/infiniband/hw/qib/qib_driver.c
drivers/infiniband/hw/qib/qib_iba6120.c
drivers/infiniband/hw/qib/qib_iba7220.c
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/infiniband/hw/qib/qib_init.c

index ee993e725d38e36d883180bc4e34ca6b2d862d79..97e623383e1a06699e60505111b84f8ae3efa008 100644 (file)
@@ -171,7 +171,9 @@ struct qib_ctxtdata {
        /* how many alloc_pages() chunks in rcvegrbuf_pages */
        u32 rcvegrbuf_chunks;
        /* how many egrbufs per chunk */
-       u32 rcvegrbufs_perchunk;
+       u16 rcvegrbufs_perchunk;
+       /* ilog2 of above */
+       u16 rcvegrbufs_perchunk_shift;
        /* order for rcvegrbuf_pages */
        size_t rcvegrbuf_size;
        /* rcvhdrq size (for freeing) */
@@ -940,7 +942,9 @@ struct qib_devdata {
        /* chip address space used by 4k pio buffers */
        u32 align4k;
        /* size of each rcvegrbuffer */
-       u32 rcvegrbufsize;
+       u16 rcvegrbufsize;
+       /* log2 of above */
+       u16 rcvegrbufsize_shift;
        /* localbus width (1, 2,4,8,16,32) from config space  */
        u32 lbus_width;
        /* localbus speed in MHz */
index 23e584f4c36c772c2647e72f3e60c962a74c23aa..89264ffc7ee97336d1282e22dbba4cf989e6b427 100644 (file)
@@ -279,10 +279,10 @@ bail:
  */
 static inline void *qib_get_egrbuf(const struct qib_ctxtdata *rcd, u32 etail)
 {
-       const u32 chunk = etail / rcd->rcvegrbufs_perchunk;
-       const u32 idx =  etail % rcd->rcvegrbufs_perchunk;
+       const u32 chunk = etail >> rcd->rcvegrbufs_perchunk_shift;
+       const u32 idx =  etail & ((u32)rcd->rcvegrbufs_perchunk - 1);
 
-       return rcd->rcvegrbuf[chunk] + idx * rcd->dd->rcvegrbufsize;
+       return rcd->rcvegrbuf[chunk] + (idx << rcd->dd->rcvegrbufsize_shift);
 }
 
 /*
index d8ca0a0b970d39879e7d981acbf5cb1647dca424..781a802a321f069d3a8b6552713a3cb550d52803 100644 (file)
@@ -3273,6 +3273,8 @@ static int init_6120_variables(struct qib_devdata *dd)
        /* we always allocate at least 2048 bytes for eager buffers */
        ret = ib_mtu_enum_to_int(qib_ibmtu);
        dd->rcvegrbufsize = ret != -1 ? max(ret, 2048) : QIB_DEFAULT_MTU;
+       BUG_ON(!is_power_of_2(dd->rcvegrbufsize));
+       dd->rcvegrbufsize_shift = ilog2(dd->rcvegrbufsize);
 
        qib_6120_tidtemplate(dd);
 
index e1f947446c2a5bac53c28699c3ac3792924fea9b..3f1d562ba89824694808a6bd91f1f94dbaa12e4b 100644 (file)
@@ -4085,6 +4085,8 @@ static int qib_init_7220_variables(struct qib_devdata *dd)
        /* we always allocate at least 2048 bytes for eager buffers */
        ret = ib_mtu_enum_to_int(qib_ibmtu);
        dd->rcvegrbufsize = ret != -1 ? max(ret, 2048) : QIB_DEFAULT_MTU;
+       BUG_ON(!is_power_of_2(dd->rcvegrbufsize));
+       dd->rcvegrbufsize_shift = ilog2(dd->rcvegrbufsize);
 
        qib_7220_tidtemplate(dd);
 
index 5ea9ece23b33996bedbcb652ecb2bb116c5c5ec2..f3f4b55262c211e2b78497fe4967bf9717bcfa0c 100644 (file)
@@ -6205,6 +6205,8 @@ static int qib_init_7322_variables(struct qib_devdata *dd)
 
        /* we always allocate at least 2048 bytes for eager buffers */
        dd->rcvegrbufsize = max(mtu, 2048);
+       BUG_ON(!is_power_of_2(dd->rcvegrbufsize));
+       dd->rcvegrbufsize_shift = ilog2(dd->rcvegrbufsize);
 
        qib_7322_tidtemplate(dd);
 
index 021636dbeae69ea62d091af071f090b5263c4c2b..21ffa7c0915f041db05128f7b7896a82501cdc69 100644 (file)
@@ -183,6 +183,9 @@ struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *ppd, u32 ctxt)
                rcd->rcvegrbuf_chunks = (rcd->rcvegrcnt +
                        rcd->rcvegrbufs_perchunk - 1) /
                        rcd->rcvegrbufs_perchunk;
+               BUG_ON(!is_power_of_2(rcd->rcvegrbufs_perchunk));
+               rcd->rcvegrbufs_perchunk_shift =
+                       ilog2(rcd->rcvegrbufs_perchunk);
        }
        return rcd;
 }