static int rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep) { struct list_head sched_list; struct ib_wc *wcs; int budget, count, rc; INIT_LIST_HEAD(&sched_list); budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE; do { wcs = ep->rep_recv_wcs; rc = ib_poll_cq(cq, RPCRDMA_POLLSIZE, wcs); if (rc <= 0) goto out_schedule; count = rc; while (count-- > 0) rpcrdma_recvcq_process_wc(wcs++, &sched_list); } while (rc == RPCRDMA_POLLSIZE && --budget); rc = 0; out_schedule: rpcrdma_schedule_tasklet(&sched_list); return rc; }
static void rpcrdma_flush_cqs(struct rpcrdma_ep *ep) { struct ib_wc wc; while (ib_poll_cq(ep->rep_attr.recv_cq, 1, &wc) > 0) rpcrdma_recvcq_process_wc(&wc); while (ib_poll_cq(ep->rep_attr.send_cq, 1, &wc) > 0) rpcrdma_sendcq_process_wc(&wc); }
static void rpcrdma_flush_cqs(struct rpcrdma_ep *ep) { struct ib_wc wc; LIST_HEAD(sched_list); while (ib_poll_cq(ep->rep_attr.recv_cq, 1, &wc) > 0) rpcrdma_recvcq_process_wc(&wc, &sched_list); if (!list_empty(&sched_list)) rpcrdma_schedule_tasklet(&sched_list); while (ib_poll_cq(ep->rep_attr.send_cq, 1, &wc) > 0) rpcrdma_sendcq_process_wc(&wc); }
/* The wc array is on stack: automatic memory is always CPU-local. * * struct ib_wc is 64 bytes, making the poll array potentially * large. But this is at the bottom of the call chain. Further * substantial work is done in another thread. */ static void rpcrdma_recvcq_poll(struct ib_cq *cq) { struct ib_wc *pos, wcs[4]; int count, rc; do { pos = wcs; rc = ib_poll_cq(cq, ARRAY_SIZE(wcs), pos); if (rc < 0) break; count = rc; while (count-- > 0) rpcrdma_recvcq_process_wc(pos++); } while (rc == ARRAY_SIZE(wcs)); }
static int rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep) { struct ib_wc *wcs; int budget, count, rc; budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE; do { wcs = ep->rep_recv_wcs; rc = ib_poll_cq(cq, RPCRDMA_POLLSIZE, wcs); if (rc <= 0) return rc; count = rc; while (count-- > 0) rpcrdma_recvcq_process_wc(wcs++); } while (rc == RPCRDMA_POLLSIZE && --budget); return 0; }