Skip to content

Commit

Permalink
use FI_SELECTIVE_COMPLETION as a bind flag
Browse files Browse the repository at this point in the history
...instead of overloading the meaning of FI_COMPLETION.  See issue ofiwg#954
for more background on this change.

Signed-off-by: Dave Goodell <dgoodell@cisco.com>
  • Loading branch information
goodell committed Apr 24, 2015
1 parent f690798 commit 0378258
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 67 deletions.
1 change: 1 addition & 0 deletions include/rdma/fabric.h
Expand Up @@ -121,6 +121,7 @@ typedef struct fid *fid_t;
#define FI_TRANSMIT_COMPLETE (1ULL << 27)
#define FI_DELIVERY_COMPLETE (1ULL << 28)

#define FI_SELECTIVE_COMPLETION (1ULL << 55)
#define FI_RMA_EVENT (1ULL << 56)
#define FI_SOURCE (1ULL << 57)
#define FI_NAMED_RX_CTX (1ULL << 58)
Expand Down
52 changes: 34 additions & 18 deletions man/fi_endpoint.3.md
Expand Up @@ -256,42 +256,58 @@ together when binding an endpoint to a completion domain CQ.
: Directs the notification of inbound data transfers to the specified
completion queue. This includes received messages.

*FI_COMPLETION*
*FI_SELECTIVE_COMPLETION*
: By default, data transfer operations generate completion entries
into a completion queue after they have successfully completed.
Applications can use this bind flag to selectively enable
when completions are generated. If FI_COMPLETION is specified,
Applications can use this bind flag to selectively enable when
completions are generated. If FI_SELECTIVE_COMPLETION is specified,
data transfer operations will not generate entries for successful
completions unless FI_COMPLETION is set as an operational flag
for the given operation. FI_COMPLETION must be OR'ed with
FI_SEND and/or FI_RECV flags.

When set the user must determine when a request that does NOT have
FI_COMPLETION set has completed indirectly, usually based on the
completion of a subsequent operation. Use of this flag may improve
performance by allowing the provider to avoid writing a completion
entry for every operation.
completions unless FI_COMPLETION is set as an operational flag for the
given operation. FI_SELECTIVE_COMPLETION must be OR'ed with FI_SEND
and/or FI_RECV flags.

When FI_SELECTIVE_COMPLETION is set, the user must determine when a
request that does NOT have FI_COMPLETION set has completed indirectly,
usually based on the completion of a subsequent operation. Use of
this flag may improve performance by allowing the provider to avoid
writing a completion entry for every operation.

Example: An application can selectively generate send completions by
using the following general approach:

{% highlight c %}
fi_tx_attr::op_flags = 0; // default - no completion
fi_ep_bind(ep, cq, FI_SEND | FI_COMPLETION);
fi_ep_bind(ep, cq, FI_SEND | FI_SELECTIVE_COMPLETION);
fi_send(ep, ...); // no completion
fi_sendv(ep, ...); // no completion
fi_sendmsg(ep, ..., FI_COMPLETION); // completion!
fi_inject(ep, ...); // no completion
{% endhighlight %}

Example: An application can selectively disable send completions by
modifying the operational flags:

{% highlight c %}
fi_tx_attr::op_flags = FI_COMPLETION; // default - completion
fi_ep_bind(ep, cq, FI_SEND | FI_COMPLETION);
fi_ep_bind(ep, cq, FI_SEND | FI_SELECTIVE_COMPLETION);
fi_send(ep, ...); // completion
fi_sendv(ep, ...); // completion
fi_sendmsg(ep, ..., 0); // no completion!
fi_inject(ep, ...); // no completion!
{% endhighlight %}

Example: Omitting FI_SELECTIVE_COMPLETION when binding will generate
completions for all non-fi_inject calls:

{% highlight c %}
fi_tx_attr::op_flags = 0;
fi_ep_bind(ep, cq, FI_SEND); // default - completion
fi_send(ep, ...); // completion
fi_sendv(ep, ...); // completion
fi_sendmsg(ep, ..., 0); // completion!
fi_sendmsg(ep, ..., FI_COMPLETION); // completion
fi_sendmsg(ep, ..., FI_INJECT|FI_COMPLETION); // completion!
fi_inject(ep, ...); // no completion!
{% endhighlight %}

An endpoint may also, or instead, be bound to a fabric counter. When
Expand Down
4 changes: 2 additions & 2 deletions prov/psm/src/psmx.h
Expand Up @@ -524,8 +524,8 @@ struct psmx_fid_ep {
struct psmx_fid_cntr *read_cntr;
struct psmx_fid_cntr *remote_write_cntr;
struct psmx_fid_cntr *remote_read_cntr;
int send_cq_event_flag:1;
int recv_cq_event_flag:1;
int send_selective_completion:1;
int recv_selective_completion:1;
uint64_t flags;
uint64_t caps;
struct fi_context nocomp_send_context;
Expand Down
8 changes: 4 additions & 4 deletions prov/psm/src/psmx_atomic.c
Expand Up @@ -663,7 +663,7 @@ static int psmx_atomic_self(int am_cmd,

gen_local_event:
no_event = ((flags & PSMX_NO_COMPLETION) ||
(ep->send_cq_event_flag && !(flags & FI_COMPLETION)));
(ep->send_selective_completion && !(flags & FI_COMPLETION)));
if (ep->send_cq && !no_event) {
event = psmx_cq_create_event(
ep->send_cq,
Expand Down Expand Up @@ -791,7 +791,7 @@ ssize_t _psmx_atomic_write(struct fid_ep *ep,
}

req->no_event = (flags & PSMX_NO_COMPLETION) ||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION));
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION));

req->op = PSMX_AM_REQ_ATOMIC_WRITE;
req->atomic.buf = (void *)buf;
Expand Down Expand Up @@ -978,7 +978,7 @@ ssize_t _psmx_atomic_readwrite(struct fid_ep *ep,
}

req->no_event = (flags & PSMX_NO_COMPLETION) ||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION));
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION));

req->op = PSMX_AM_REQ_ATOMIC_READWRITE;
req->atomic.buf = (void *)buf;
Expand Down Expand Up @@ -1196,7 +1196,7 @@ ssize_t _psmx_atomic_compwrite(struct fid_ep *ep,
}

req->no_event = (flags & PSMX_NO_COMPLETION) ||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION));
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION));

req->op = PSMX_AM_REQ_ATOMIC_COMPWRITE;
req->atomic.buf = (void *)buf;
Expand Down
14 changes: 7 additions & 7 deletions prov/psm/src/psmx_ep.c
Expand Up @@ -40,23 +40,23 @@ static void psmx_ep_optimize_ops(struct psmx_fid_ep *ep)
FI_INFO(&psmx_prov, FI_LOG_EP_DATA,
"generic tagged ops.\n");
}
else if (ep->send_cq_event_flag && ep->recv_cq_event_flag) {
else if (ep->send_selective_completion && ep->recv_selective_completion) {
if (ep->av && ep->av->type == FI_AV_TABLE)
ep->ep.tagged = &psmx_tagged_ops_no_event_av_table;
else
ep->ep.tagged = &psmx_tagged_ops_no_event_av_map;
FI_INFO(&psmx_prov, FI_LOG_EP_DATA,
"tagged ops optimized for op_flags=0 and event suppression\n");
}
else if (ep->send_cq_event_flag) {
else if (ep->send_selective_completion) {
if (ep->av && ep->av->type == FI_AV_TABLE)
ep->ep.tagged = &psmx_tagged_ops_no_send_event_av_table;
else
ep->ep.tagged = &psmx_tagged_ops_no_send_event_av_map;
FI_INFO(&psmx_prov, FI_LOG_EP_DATA,
"tagged ops optimized for op_flags=0 and send event suppression\n");
}
else if (ep->recv_cq_event_flag) {
else if (ep->recv_selective_completion) {
if (ep->av && ep->av->type == FI_AV_TABLE)
ep->ep.tagged = &psmx_tagged_ops_no_recv_event_av_table;
else
Expand Down Expand Up @@ -177,13 +177,13 @@ static int psmx_ep_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
return -FI_EINVAL;
if (flags & FI_SEND) {
ep->send_cq = cq;
if (flags & FI_COMPLETION)
ep->send_cq_event_flag = 1;
if (flags & FI_SELECTIVE_COMPLETION)
ep->send_selective_completion = 1;
}
if (flags & FI_RECV) {
ep->recv_cq = cq;
if (flags & FI_COMPLETION)
ep->recv_cq_event_flag = 1;
if (flags & FI_SELECTIVE_COMPLETION)
ep->recv_selective_completion = 1;
}
psmx_ep_optimize_ops(ep);
break;
Expand Down
4 changes: 2 additions & 2 deletions prov/psm/src/psmx_msg.c
Expand Up @@ -90,7 +90,7 @@ ssize_t _psmx_recv(struct fid_ep *ep, void *buf, size_t len,
psm_tagsel = PSMX_MSG_BIT;
}

if (ep_priv->recv_cq_event_flag && !(flags & FI_COMPLETION) && !context) {
if (ep_priv->recv_selective_completion && !(flags & FI_COMPLETION) && !context) {
fi_context = &ep_priv->nocomp_recv_context;
}
else {
Expand Down Expand Up @@ -245,7 +245,7 @@ ssize_t _psmx_send(struct fid_ep *ep, const void *buf, size_t len,
psm_tag = ep_priv->domain->psm_epid | PSMX_MSG_BIT;

if ((flags & PSMX_NO_COMPLETION) ||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION)))
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION)))
no_completion = 1;

if (flags & FI_INJECT) {
Expand Down
4 changes: 2 additions & 2 deletions prov/psm/src/psmx_msg2.c
Expand Up @@ -395,7 +395,7 @@ static ssize_t _psmx_recv2(struct fid_ep *ep, void *buf, size_t len,
req->ep = ep_priv;
req->cq_flags = FI_RECV | FI_MSG;

if (ep_priv->recv_cq_event_flag && !(flags & FI_COMPLETION))
if (ep_priv->recv_selective_completion && !(flags & FI_COMPLETION))
req->no_event = 1;

unexp = psmx_am_search_and_dequeue_unexp(ep_priv->domain,
Expand Down Expand Up @@ -553,7 +553,7 @@ static ssize_t _psmx_send2(struct fid_ep *ep, const void *buf, size_t len,
req->cq_flags = FI_SEND | FI_MSG;

if ((flags & PSMX_NO_COMPLETION) ||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION)))
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION)))
req->no_event = 1;

args[0].u32w0 = PSMX_AM_REQ_SEND | (msg_size == len ? PSMX_AM_EOM : 0);
Expand Down
6 changes: 3 additions & 3 deletions prov/psm/src/psmx_rma.c
Expand Up @@ -401,7 +401,7 @@ static ssize_t psmx_rma_self(int am_cmd,
}

no_event = (flags & PSMX_NO_COMPLETION) ||
(ep->send_cq_event_flag && !(flags & FI_COMPLETION));
(ep->send_selective_completion && !(flags & FI_COMPLETION));

if (ep->send_cq && !no_event) {
event = psmx_cq_create_event(
Expand Down Expand Up @@ -551,7 +551,7 @@ ssize_t _psmx_read(struct fid_ep *ep, void *buf, size_t len,
PSMX_CTXT_USER(&req->fi_context) = context;
PSMX_CTXT_EP(&req->fi_context) = ep_priv;

if (ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION)) {
if (ep_priv->send_selective_completion && !(flags & FI_COMPLETION)) {
PSMX_CTXT_TYPE(&req->fi_context) = PSMX_NOCOMP_READ_CONTEXT;
req->no_event = 1;
}
Expand Down Expand Up @@ -708,7 +708,7 @@ ssize_t _psmx_write(struct fid_ep *ep, const void *buf, size_t len,
addr, key, context, flags, data);

no_event = (flags & PSMX_NO_COMPLETION) ||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION));
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION));

if (flags & FI_INJECT) {
if (len > PSMX_INJECT_SIZE)
Expand Down
4 changes: 2 additions & 2 deletions prov/psm/src/psmx_tagged.c
Expand Up @@ -143,7 +143,7 @@ ssize_t _psmx_tagged_recv(struct fid_ep *ep, void *buf, size_t len,
psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;

if (ep_priv->recv_cq_event_flag && !(flags & FI_COMPLETION) && !context) {
if (ep_priv->recv_selective_completion && !(flags & FI_COMPLETION) && !context) {
fi_context = &ep_priv->nocomp_recv_context;
}
else {
Expand Down Expand Up @@ -476,7 +476,7 @@ ssize_t _psmx_tagged_send(struct fid_ep *ep, const void *buf, size_t len,
psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);

if ((flags & PSMX_NO_COMPLETION) ||
(ep_priv->send_cq_event_flag && !(flags & FI_COMPLETION)))
(ep_priv->send_selective_completion && !(flags & FI_COMPLETION)))
no_completion = 1;

if (flags & FI_INJECT) {
Expand Down
24 changes: 12 additions & 12 deletions prov/sockets/src/sock_ep.c
Expand Up @@ -133,19 +133,19 @@ static int sock_ctx_bind_cq(struct fid *fid, struct fid *bfid, uint64_t flags)
tx_ctx = container_of(fid, struct sock_tx_ctx, fid.ctx);
if (flags & FI_SEND) {
tx_ctx->comp.send_cq = sock_cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
tx_ctx->comp.send_cq_event = 1;
}

if (flags & FI_READ) {
tx_ctx->comp.read_cq = sock_cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
tx_ctx->comp.read_cq_event = 1;
}

if (flags & FI_WRITE) {
tx_ctx->comp.write_cq = sock_cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
tx_ctx->comp.write_cq_event = 1;
}

Expand All @@ -158,7 +158,7 @@ static int sock_ctx_bind_cq(struct fid *fid, struct fid *bfid, uint64_t flags)
rx_ctx = container_of(fid, struct sock_rx_ctx, ctx.fid);
if (flags & FI_RECV) {
rx_ctx->comp.recv_cq = sock_cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
rx_ctx->comp.recv_cq_event = 1;
}

Expand All @@ -171,19 +171,19 @@ static int sock_ctx_bind_cq(struct fid *fid, struct fid *bfid, uint64_t flags)
tx_ctx = container_of(fid, struct sock_tx_ctx, fid.stx.fid);
if (flags & FI_SEND) {
tx_ctx->comp.send_cq = sock_cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
tx_ctx->comp.send_cq_event = 1;
}

if (flags & FI_READ) {
tx_ctx->comp.read_cq = sock_cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
tx_ctx->comp.read_cq_event = 1;
}

if (flags & FI_WRITE) {
tx_ctx->comp.write_cq = sock_cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
tx_ctx->comp.write_cq_event = 1;
}

Expand Down Expand Up @@ -674,25 +674,25 @@ static int sock_ep_bind(struct fid *fid, struct fid *bfid, uint64_t flags)

if (flags & FI_SEND) {
ep->comp.send_cq = cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->comp.send_cq_event = 1;
}

if (flags & FI_READ) {
ep->comp.read_cq = cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->comp.read_cq_event = 1;
}

if (flags & FI_WRITE) {
ep->comp.write_cq = cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->comp.write_cq_event = 1;
}

if (flags & FI_RECV) {
ep->comp.recv_cq = cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->comp.recv_cq_event = 1;
}

Expand All @@ -719,7 +719,7 @@ static int sock_ep_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
if (rx_ctx->ctx.fid.fclass == FI_CLASS_SRX_CTX) {
if (flags & FI_RECV) {
ep->comp.recv_cq = cq;
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->comp.recv_cq_event = 1;
}

Expand Down
4 changes: 2 additions & 2 deletions prov/usnic/src/usdf_ep_msg.c
Expand Up @@ -507,7 +507,7 @@ usdf_ep_msg_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
case FI_CLASS_CQ:
if (flags & FI_SEND) {
cq = cq_fidtou(bfid);
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->ep_tx_dflt_signal_comp = 0;
else
ep->ep_tx_dflt_signal_comp = 1;
Expand All @@ -516,7 +516,7 @@ usdf_ep_msg_bind(struct fid *fid, struct fid *bfid, uint64_t flags)

if (flags & FI_RECV) {
cq = cq_fidtou(bfid);
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->ep_rx_dflt_signal_comp = 0;
else
ep->ep_rx_dflt_signal_comp = 1;
Expand Down
4 changes: 2 additions & 2 deletions prov/usnic/src/usdf_ep_rdm.c
Expand Up @@ -497,7 +497,7 @@ usdf_ep_rdm_bind(struct fid *fid, struct fid *bfid, uint64_t flags)
case FI_CLASS_CQ:
if (flags & FI_SEND) {
cq = cq_fidtou(bfid);
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->ep_tx_dflt_signal_comp = 0;
else
ep->ep_tx_dflt_signal_comp = 1;
Expand All @@ -506,7 +506,7 @@ usdf_ep_rdm_bind(struct fid *fid, struct fid *bfid, uint64_t flags)

if (flags & FI_RECV) {
cq = cq_fidtou(bfid);
if (flags & FI_COMPLETION)
if (flags & FI_SELECTIVE_COMPLETION)
ep->ep_rx_dflt_signal_comp = 0;
else
ep->ep_rx_dflt_signal_comp = 1;
Expand Down

0 comments on commit 0378258

Please sign in to comment.