aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/qib/qib.h9
-rw-r--r--drivers/infiniband/hw/qib/qib_iba6120.c1
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7220.c1
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c1
-rw-r--r--drivers/infiniband/hw/qib/qib_tx.c25
5 files changed, 28 insertions, 9 deletions
diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h
index 6b811e3e8bd1..2d638877c4af 100644
--- a/drivers/infiniband/hw/qib/qib.h
+++ b/drivers/infiniband/hw/qib/qib.h
@@ -873,7 +873,14 @@ struct qib_devdata {
873 * pio_writing. 873 * pio_writing.
874 */ 874 */
875 spinlock_t pioavail_lock; 875 spinlock_t pioavail_lock;
876 876 /*
877 * index of last buffer to optimize search for next
878 */
879 u32 last_pio;
880 /*
881 * min kernel pio buffer to optimize search
882 */
883 u32 min_kernel_pio;
877 /* 884 /*
878 * Shadow copies of registers; size indicates read access size. 885 * Shadow copies of registers; size indicates read access size.
879 * Most of them are readonly, but some are write-only register, 886 * Most of them are readonly, but some are write-only register,
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c
index d0c64d514813..4d352b90750a 100644
--- a/drivers/infiniband/hw/qib/qib_iba6120.c
+++ b/drivers/infiniband/hw/qib/qib_iba6120.c
@@ -3132,6 +3132,7 @@ static void get_6120_chip_params(struct qib_devdata *dd)
3132 val = qib_read_kreg64(dd, kr_sendpiobufcnt); 3132 val = qib_read_kreg64(dd, kr_sendpiobufcnt);
3133 dd->piobcnt2k = val & ~0U; 3133 dd->piobcnt2k = val & ~0U;
3134 dd->piobcnt4k = val >> 32; 3134 dd->piobcnt4k = val >> 32;
3135 dd->last_pio = dd->piobcnt4k + dd->piobcnt2k - 1;
3135 /* these may be adjusted in init_chip_wc_pat() */ 3136 /* these may be adjusted in init_chip_wc_pat() */
3136 dd->pio2kbase = (u32 __iomem *) 3137 dd->pio2kbase = (u32 __iomem *)
3137 (((char __iomem *)dd->kregbase) + dd->pio2k_bufbase); 3138 (((char __iomem *)dd->kregbase) + dd->pio2k_bufbase);
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c
index 3c722f79d6f6..86a0ba7ca0c2 100644
--- a/drivers/infiniband/hw/qib/qib_iba7220.c
+++ b/drivers/infiniband/hw/qib/qib_iba7220.c
@@ -4157,6 +4157,7 @@ static int qib_init_7220_variables(struct qib_devdata *dd)
4157 dd->cspec->sdmabufcnt; 4157 dd->cspec->sdmabufcnt;
4158 dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs; 4158 dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs;
4159 dd->cspec->lastbuf_for_pio--; /* range is <= , not < */ 4159 dd->cspec->lastbuf_for_pio--; /* range is <= , not < */
4160 dd->last_pio = dd->cspec->lastbuf_for_pio;
4160 dd->pbufsctxt = dd->lastctxt_piobuf / 4161 dd->pbufsctxt = dd->lastctxt_piobuf /
4161 (dd->cfgctxts - dd->first_user_ctxt); 4162 (dd->cfgctxts - dd->first_user_ctxt);
4162 4163
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
index 060b96064469..e7b9ad34fe2e 100644
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
@@ -6379,6 +6379,7 @@ static int qib_init_7322_variables(struct qib_devdata *dd)
6379 dd->cspec->sdmabufcnt; 6379 dd->cspec->sdmabufcnt;
6380 dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs; 6380 dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs;
6381 dd->cspec->lastbuf_for_pio--; /* range is <= , not < */ 6381 dd->cspec->lastbuf_for_pio--; /* range is <= , not < */
6382 dd->last_pio = dd->cspec->lastbuf_for_pio;
6382 dd->pbufsctxt = (dd->cfgctxts > dd->first_user_ctxt) ? 6383 dd->pbufsctxt = (dd->cfgctxts > dd->first_user_ctxt) ?
6383 dd->lastctxt_piobuf / (dd->cfgctxts - dd->first_user_ctxt) : 0; 6384 dd->lastctxt_piobuf / (dd->cfgctxts - dd->first_user_ctxt) : 0;
6384 6385
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);