Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
IBV_GET_CQ_EVENT(3)	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.

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 ac-
       knowledgement and acking	several	 completion  events  in	 one  call  to
       ibv_ack_cq_events().

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)

NAME | SYNOPSIS | DESCRIPTION | RETURN VALUE | NOTES | EXAMPLES | SEE ALSO | AUTHORS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=ibv_get_cq_event&sektion=3&manpath=FreeBSD+12.1-RELEASE+and+Ports>

home | help