aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/qib/qib_tx.c
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2012-05-07 14:02:42 -0400
committerRoland Dreier <roland@purestorage.com>2012-05-14 15:37:03 -0400
commitbb77a077232e78476d7bc39c080f9e6685cbfd3c (patch)
treed6b07dec8a7a7aa8fbbd752c2fd4b3b0c36088f9 /drivers/infiniband/hw/qib/qib_tx.c
parentcca195a168ac062967fd1fa75c75546167b1e213 (diff)
IB/qib: Optimize pio ack buffer allocation
This patch optimizes pio buffer allocation in the kernel. For qib, kernel pio buffers are used for sending acks. The code to allocate the buffer would always start at 0 until it found a buffer. This means that an average of 64 comparisions were done on each allocate, since the busy bit won't be cleared until the bits are refreshed when buffers are exhausted. This patch adds two new fields in the devdata struct, last_pio and min_kernel_pio. last_pio is the last buffer that was allocated. min_kernel_pio is the lowest potential available buffer. min_kernel_pio is modifed as contexts are allocated and deallocted. Reviewed-by: Ramkrishna Vepa <ramkrishna.vepa@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_tx.c')
-rw-r--r--drivers/infiniband/hw/qib/qib_tx.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/qib/qib_tx.c b/drivers/infiniband/hw/qib/qib_tx.c
index 1bf626c40172..31d3561400a4 100644
--- a/drivers/infiniband/hw/qib/qib_tx.c
+++ b/drivers/infiniband/hw/qib/qib_tx.c
@@ -295,6 +295,7 @@ u32 __iomem *qib_getsendbuf_range(struct qib_devdata *dd, u32 *pbufnum,
295 295
296 nbufs = last - first + 1; /* number in range to check */ 296 nbufs = last - first + 1; /* number in range to check */
297 if (dd->upd_pio_shadow) { 297 if (dd->upd_pio_shadow) {
298update_shadow:
298 /* 299 /*
299 * Minor optimization. If we had no buffers on last call, 300 * Minor optimization. If we had no buffers on last call,
300 * start out by doing the update; continue and do scan even 301 * start out by doing the update; continue and do scan even
@@ -304,37 +305,39 @@ u32 __iomem *qib_getsendbuf_range(struct qib_devdata *dd, u32 *pbufnum,
304 updated++; 305 updated++;
305 } 306 }
306 i = first; 307 i = first;
307rescan:
308 /* 308 /*
309 * While test_and_set_bit() is atomic, we do that and then the 309 * While test_and_set_bit() is atomic, we do that and then the
310 * change_bit(), and the pair is not. See if this is the cause 310 * change_bit(), and the pair is not. See if this is the cause
311 * of the remaining armlaunch errors. 311 * of the remaining armlaunch errors.
312 */ 312 */
313 spin_lock_irqsave(&dd->pioavail_lock, flags); 313 spin_lock_irqsave(&dd->pioavail_lock, flags);
314 if (dd->last_pio >= first && dd->last_pio <= last)
315 i = dd->last_pio + 1;
316 if (!first)
317 /* adjust to min possible */
318 nbufs = last - dd->min_kernel_pio + 1;
314 for (j = 0; j < nbufs; j++, i++) { 319 for (j = 0; j < nbufs; j++, i++) {
315 if (i > last) 320 if (i > last)
316 i = first; 321 i = !first ? dd->min_kernel_pio : first;
317 if (__test_and_set_bit((2 * i) + 1, shadow)) 322 if (__test_and_set_bit((2 * i) + 1, shadow))
318 continue; 323 continue;
319 /* flip generation bit */ 324 /* flip generation bit */
320 __change_bit(2 * i, shadow); 325 __change_bit(2 * i, shadow);
321 /* remember that the buffer can be written to now */ 326 /* remember that the buffer can be written to now */
322 __set_bit(i, dd->pio_writing); 327 __set_bit(i, dd->pio_writing);
328 if (!first && first != last) /* first == last on VL15, avoid */
329 dd->last_pio = i;
323 break; 330 break;
324 } 331 }
325 spin_unlock_irqrestore(&dd->pioavail_lock, flags); 332 spin_unlock_irqrestore(&dd->pioavail_lock, flags);
326 333
327 if (j == nbufs) { 334 if (j == nbufs) {
328 if (!updated) { 335 if (!updated)
329 /* 336 /*
330 * First time through; shadow exhausted, but may be 337 * First time through; shadow exhausted, but may be
331 * buffers available, try an update and then rescan. 338 * buffers available, try an update and then rescan.
332 */ 339 */
333 update_send_bufs(dd); 340 goto update_shadow;
334 updated++;
335 i = first;
336 goto rescan;
337 }
338 no_send_bufs(dd); 341 no_send_bufs(dd);
339 buf = NULL; 342 buf = NULL;
340 } else { 343 } else {
@@ -422,14 +425,20 @@ void qib_chg_pioavailkernel(struct qib_devdata *dd, unsigned start,
422 __clear_bit(QLOGIC_IB_SENDPIOAVAIL_CHECK_SHIFT 425 __clear_bit(QLOGIC_IB_SENDPIOAVAIL_CHECK_SHIFT
423 + start, dd->pioavailshadow); 426 + start, dd->pioavailshadow);
424 __set_bit(start, dd->pioavailkernel); 427 __set_bit(start, dd->pioavailkernel);
428 if ((start >> 1) < dd->min_kernel_pio)
429 dd->min_kernel_pio = start >> 1;
425 } else { 430 } else {
426 __set_bit(start + QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT, 431 __set_bit(start + QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT,
427 dd->pioavailshadow); 432 dd->pioavailshadow);
428 __clear_bit(start, dd->pioavailkernel); 433 __clear_bit(start, dd->pioavailkernel);
434 if ((start >> 1) > dd->min_kernel_pio)
435 dd->min_kernel_pio = start >> 1;
429 } 436 }
430 start += 2; 437 start += 2;
431 } 438 }
432 439
440 if (dd->min_kernel_pio > 0 && dd->last_pio < dd->min_kernel_pio - 1)
441 dd->last_pio = dd->min_kernel_pio - 1;
433 spin_unlock_irqrestore(&dd->pioavail_lock, flags); 442 spin_unlock_irqrestore(&dd->pioavail_lock, flags);
434 443
435 dd->f_txchk_change(dd, ostart, len, avail, rcd); 444 dd->f_txchk_change(dd, ostart, len, avail, rcd);