Go to main content

man pages section 3: Library Interfaces and Headers

Exit Print View

Updated: Wednesday, July 27, 2022
 
 

ibv_get_cq_event (3)

Name

ibv_get_cq_event - get and acknowledge completion queue (CQ) events

Synopsis

#include <infiniband/verbs.h>

int ibv_get_cq_event(struct ibv_comp_channel *channel,
struct ibv_cq **cq, void **cq_context);

void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents);

Description

Libibverbs Programmer's Manual                             IBV_GET_CQ_EVENT(3)



NAME
       ibv_get_cq_event,  ibv_ack_cq_events  -  get and acknowledge completion
       queue (CQ) events


SYNOPSIS
       #include <infiniband/verbs.h>

       int ibv_get_cq_event(struct ibv_comp_channel *channel,
                            struct ibv_cq **cq, void **cq_context);

       void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents);


DESCRIPTION
       ibv_get_cq_event() waits for the next completion event in  the  comple-
       tion  event  channel  channel.  Fills the arguments cq with the CQ that
       got the event and cq_context with the CQ's context.

       ibv_ack_cq_events() acknowledges nevents events on the CQ cq.


RETURN VALUE
       ibv_get_cq_event() returns 0 on success, and -1 on error.

       ibv_ack_cq_events() returns no value.


ATTRIBUTES
       See attributes(7) for descriptions of the following attributes:


       +---------------+-----------------------+
       |ATTRIBUTE TYPE |   ATTRIBUTE VALUE     |
       +---------------+-----------------------+
       |Availability   | network/open-fabrics  |
       +---------------+-----------------------+
       |Stability      | Pass-through volatile |
       +---------------+-----------------------+

NOTES
       All completion events that ibv_get_cq_event() returns must be  acknowl-
       edged  using ibv_ack_cq_events().  To avoid races, destroying a CQ will
       wait for all completion events to be acknowledged;  this  guarantees  a
       one-to-one correspondence between acks and successful gets.

       Calling  ibv_ack_cq_events()  may  be relatively expensive in the data-
       path, since it must take a mutex.  Therefore it may be better to  amor-
       tize  this  cost  by  keeping  a  count of the number of events needing
       acknowledgement and acking several completion events  in  one  call  to
       ibv_ack_cq_events().

       Source  code  for open source software components in Oracle Solaris can
       be found at https://www.oracle.com/downloads/opensource/solaris-source-
       code-downloads.html.

       This     software     was    built    from    source    available    at
       https://github.com/oracle/solaris-userland.   The  original   community
       source   was   downloaded   from    ['https://www.openfabrics.org/down-
       loads/ibutils/ibutils-1.5.7-0.2.gbd7e502.tar.gz', 'https://www.openfab-
       rics.org/downloads/libibverbs/libibverbs-1.1.8.tar.gz',
       'https://www.openfabrics.org/downloads/libmlx4/libmlx4-1.0.6.tar.gz',
       'https://www.openfabrics.org/downloads/libsdp/lib-
       sdp-1.1.108-0.15.gd7fdb72.tar.gz',   'https://www.openfabrics.org/down-
       loads/management/infiniband-diags-1.6.5.tar.gz',  'https://www.openfab-
       rics.org/downloads/management/libibmad-1.3.12.tar.gz',
       'https://www.openfabrics.org/downloads/management/libibu-
       mad-1.3.10.2.tar.gz',    'https://www.openfabrics.org/downloads/manage-
       ment/opensm-3.3.19.tar.gz',          'https://www.openfabrics.org/down-
       loads/perftest/perftest-1.3.0-0.42.gf350d3d.tar.gz', 'https://www.open-
       fabrics.org/downloads/qperf/qperf-0.4.9.tar.gz',  'https://www.openfab-
       rics.org/downloads/rdmacm/librdmacm-1.0.21.tar.gz',  'https://www.open-
       fabrics.org/downloads/rds-tools/rds-tools-2.0.4.tar.gz'].

       Further information about this software can be found on the open source
       community website at http://www.openfabrics.org/.

EXAMPLES
       The following code example demonstrates one possible way to  work  with
       completion events. It performs the following steps:

       Stage I: Preparation
       1. Creates a CQ
       2. Requests for notification upon a new (first) completion event

       Stage II: Completion Handling Routine
       3. Wait for the completion event and ack it
       4. Request for notification upon the next completion event
       5. Empty the CQ

       Note  that an extra event may be triggered without having a correspond-
       ing completion entry in the CQ.  This occurs if a completion  entry  is
       added  to  the CQ between Step 4 and Step 5, and the CQ is then emptied
       (polled) in Step 5.

       cq = ibv_create_cq(ctx, 1, ev_ctx, channel, 0);
       if (!cq) {
               fprintf(stderr, "Failed to create CQ\n");
               return 1;
       }

       /* Request notification before any completion can be created */
       if (ibv_req_notify_cq(cq, 0)) {
               fprintf(stderr, "Couldn't request CQ notification\n");
               return 1;
       }

       .
       .
       .

       /* Wait for the completion event */
       if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) {
               fprintf(stderr, "Failed to get cq_event\n");
               return 1;
       }

       /* Ack the event */
       ibv_ack_cq_events(ev_cq, 1);

       /* Request notification upon the next completion event */
       if (ibv_req_notify_cq(ev_cq, 0)) {
               fprintf(stderr, "Couldn't request CQ notification\n");
               return 1;
       }

       /* Empty the CQ: poll all of the completions from the CQ (if any exist) */
       do {
               ne = ibv_poll_cq(cq, 1, &wc);
               if (ne < 0) {
                       fprintf(stderr, "Failed to poll completions from the CQ\n");
                       return 1;
               }

               /* there may be an extra event with no completion in the CQ */
               if (ne == 0)
                       continue;

               if (wc.status != IBV_WC_SUCCESS) {
                       fprintf(stderr, "Completion with status 0x%x was found\n", wc.status);
                       return 1;
               }
       } while (ne);

       The following code example demonstrates one possible way to  work  with
       completion  events  in  non-blocking  mode.   It performs the following
       steps:

       1. Set the completion event channel to be non-blocked
       2. Poll the channel until there it has a completion event
       3. Get the completion event and ack it

       /* change the blocking mode of the completion channel */
       flags = fcntl(channel->fd, F_GETFL);
       rc = fcntl(channel->fd, F_SETFL, flags | O_NONBLOCK);
       if (rc < 0) {
                      fprintf(stderr, "Failed to change file descriptor of completion event channel\n");
                      return 1;
       }


       /*
        * poll the channel until it has an event and sleep ms_timeout
        * milliseconds between any iteration
        */
       my_pollfd.fd      = channel->fd;
       my_pollfd.events  = POLLIN;
       my_pollfd.revents = 0;

       do {
                      rc = poll(&my_pollfd, 1, ms_timeout);
       } while (rc == 0);
       if (rc < 0) {
                      fprintf(stderr, "poll failed\n");
                      return 1;
       }
       ev_cq = cq;

       /* Wait for the completion event */
       if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) {
               fprintf(stderr, "Failed to get cq_event\n");
               return 1;
       }

       /* Ack the event */
       ibv_ack_cq_events(ev_cq, 1);


SEE ALSO
       ibv_create_comp_channel(3),   ibv_create_cq(3),   ibv_req_notify_cq(3),
       ibv_poll_cq(3)


AUTHORS
       Dotan Barak
              <dotanba@gmail.com>




libibverbs                        2006-10-31               IBV_GET_CQ_EVENT(3)