Skip to content

Commit 0b79b27

Browse files
mjruhljgunthorpe
authored andcommitted
IB/{hfi1, qib, rdmavt}: Schedule multi RC/UC packets instead of posting
The post_send() path determines if it should post directly or, schedule the post for later. The current logic is: if the swqe ring is empty or (for hfi1) wqe->length <= piothreshold post the send else schedule This can allow large requests to call the send engine directly. Large requests can potentially produce a large number of packets prior to returning to the caller, blocking the caller from posting more requests, and allowing better parallel processing. Allow the driver(s) more say in this logic (pass call_send to the driver, rather than examining a return value). Update hfi1/qib logic to schedule the send engine if an RC or UC message is larger than the QP MTU size. Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
1 parent 3e5d60b commit 0b79b27

File tree

6 files changed

+32
-27
lines changed

6 files changed

+32
-27
lines changed

drivers/infiniband/hw/hfi1/qp.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,13 @@ void hfi1_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
285285
* hfi1_check_send_wqe - validate wqe
286286
* @qp - The qp
287287
* @wqe - The built wqe
288-
*
289-
* validate wqe. This is called
290-
* prior to inserting the wqe into
291-
* the ring but after the wqe has been
292-
* setup.
288+
* @call_send - Determine if the send should be posted or scheduled.
293289
*
294290
* Returns 0 on success, -EINVAL on failure
295291
*
296292
*/
297293
int hfi1_check_send_wqe(struct rvt_qp *qp,
298-
struct rvt_swqe *wqe)
294+
struct rvt_swqe *wqe, bool *call_send)
299295
{
300296
struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
301297
struct rvt_ah *ah;
@@ -305,6 +301,8 @@ int hfi1_check_send_wqe(struct rvt_qp *qp,
305301
case IB_QPT_UC:
306302
if (wqe->length > 0x80000000U)
307303
return -EINVAL;
304+
if (wqe->length > qp->pmtu)
305+
*call_send = false;
308306
break;
309307
case IB_QPT_SMI:
310308
ah = ibah_to_rvtah(wqe->ud_wr.ah);
@@ -321,7 +319,7 @@ int hfi1_check_send_wqe(struct rvt_qp *qp,
321319
default:
322320
break;
323321
}
324-
return wqe->length <= piothreshold;
322+
return 0;
325323
}
326324

327325
/**

drivers/infiniband/hw/hfi1/verbs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,8 @@ int hfi1_check_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
343343
void hfi1_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
344344
int attr_mask, struct ib_udata *udata);
345345
void hfi1_restart_rc(struct rvt_qp *qp, u32 psn, int wait);
346-
int hfi1_check_send_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe);
346+
int hfi1_check_send_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe,
347+
bool *call_send);
347348

348349
extern const u32 rc_only_opcode;
349350
extern const u32 uc_only_opcode;

drivers/infiniband/hw/qib/qib_qp.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -378,25 +378,22 @@ void qib_flush_qp_waiters(struct rvt_qp *qp)
378378
* qib_check_send_wqe - validate wr/wqe
379379
* @qp - The qp
380380
* @wqe - The built wqe
381+
* @call_send - Determine if the send should be posted or scheduled
381382
*
382-
* validate wr/wqe. This is called
383-
* prior to inserting the wqe into
384-
* the ring but after the wqe has been
385-
* setup.
386-
*
387-
* Returns 1 to force direct progress, 0 otherwise, -EINVAL on failure
383+
* Returns 0 on success, -EINVAL on failure
388384
*/
389385
int qib_check_send_wqe(struct rvt_qp *qp,
390-
struct rvt_swqe *wqe)
386+
struct rvt_swqe *wqe, bool *call_send)
391387
{
392388
struct rvt_ah *ah;
393-
int ret = 0;
394389

395390
switch (qp->ibqp.qp_type) {
396391
case IB_QPT_RC:
397392
case IB_QPT_UC:
398393
if (wqe->length > 0x80000000U)
399394
return -EINVAL;
395+
if (wqe->length > qp->pmtu)
396+
*call_send = false;
400397
break;
401398
case IB_QPT_SMI:
402399
case IB_QPT_GSI:
@@ -405,12 +402,12 @@ int qib_check_send_wqe(struct rvt_qp *qp,
405402
if (wqe->length > (1 << ah->log_pmtu))
406403
return -EINVAL;
407404
/* progress hint */
408-
ret = 1;
405+
*call_send = true;
409406
break;
410407
default:
411408
break;
412409
}
413-
return ret;
410+
return 0;
414411
}
415412

416413
#ifdef CONFIG_DEBUG_FS

drivers/infiniband/hw/qib/qib_verbs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct ib_header *hdr,
303303

304304
int qib_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr);
305305

306-
int qib_check_send_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe);
306+
int qib_check_send_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe,
307+
bool *call_send);
307308

308309
struct ib_ah *qib_create_qp0_ah(struct qib_ibport *ibp, u16 dlid);
309310

drivers/infiniband/sw/rdmavt/qp.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,7 +1718,7 @@ static inline int rvt_qp_is_avail(
17181718
*/
17191719
static int rvt_post_one_wr(struct rvt_qp *qp,
17201720
const struct ib_send_wr *wr,
1721-
int *call_send)
1721+
bool *call_send)
17221722
{
17231723
struct rvt_swqe *wqe;
17241724
u32 next;
@@ -1825,11 +1825,9 @@ static int rvt_post_one_wr(struct rvt_qp *qp,
18251825

18261826
/* general part of wqe valid - allow for driver checks */
18271827
if (rdi->driver_f.check_send_wqe) {
1828-
ret = rdi->driver_f.check_send_wqe(qp, wqe);
1828+
ret = rdi->driver_f.check_send_wqe(qp, wqe, call_send);
18291829
if (ret < 0)
18301830
goto bail_inval_free;
1831-
if (ret)
1832-
*call_send = ret;
18331831
}
18341832

18351833
log_pmtu = qp->log_pmtu;
@@ -1897,7 +1895,7 @@ int rvt_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
18971895
struct rvt_qp *qp = ibqp_to_rvtqp(ibqp);
18981896
struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device);
18991897
unsigned long flags = 0;
1900-
int call_send;
1898+
bool call_send;
19011899
unsigned nreq = 0;
19021900
int err = 0;
19031901

@@ -1930,7 +1928,11 @@ int rvt_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
19301928
bail:
19311929
spin_unlock_irqrestore(&qp->s_hlock, flags);
19321930
if (nreq) {
1933-
if (call_send)
1931+
/*
1932+
* Only call do_send if there is exactly one packet, and the
1933+
* driver said it was ok.
1934+
*/
1935+
if (nreq == 1 && call_send)
19341936
rdi->driver_f.do_send(qp);
19351937
else
19361938
rdi->driver_f.schedule_send_no_lock(qp);

include/rdma/rdma_vt.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,14 @@ struct rvt_driver_provided {
214214
void (*schedule_send)(struct rvt_qp *qp);
215215
void (*schedule_send_no_lock)(struct rvt_qp *qp);
216216

217-
/* Driver specific work request checking */
218-
int (*check_send_wqe)(struct rvt_qp *qp, struct rvt_swqe *wqe);
217+
/*
218+
* Validate the wqe. This needs to be done prior to inserting the
219+
* wqe into the ring, but after the wqe has been set up. Allow for
220+
* driver specific work request checking by providing a callback.
221+
* call_send indicates if the wqe should be posted or scheduled.
222+
*/
223+
int (*check_send_wqe)(struct rvt_qp *qp, struct rvt_swqe *wqe,
224+
bool *call_send);
219225

220226
/*
221227
* Sometimes rdmavt needs to kick the driver's send progress. That is

0 commit comments

Comments
 (0)