---
name: "ibv_create_cq_ex"
section: "3"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["linux", "freebsd"]
url: "https://new.carta.tech/ibv_create_cq_ex"
---

# ibv\_create\_cq\_ex(3)

create a completion queue (CQ)

## NAME

ibv\_create\_cq\_ex - create a completion queue (CQ)

## SYNOPSIS

```
#include <infiniband/verbs.h>

struct ibv_cq_ex *ibv_create_cq_ex(struct ibv_context *context,
                                   struct ibv_create_cq_attr_ex *cq_attr);
```

## DESCRIPTION

**ibv\_create\_cq\_ex()** creates a completion queue (CQ) for RDMA device context *context.* The argument *cq\_attr* is a pointer to struct ibv\_cq\_init\_attr\_ex as defined in \<infiniband/verbs.h\>.

```
struct ibv_cq_init_attr_ex {
int                     cqe;               /* Minimum number of entries required for CQ */
void                    *cq_context;       /* Consumer-supplied context returned for completion events */
struct ibv_comp_channel *channel;          /* Completion channel where completion events will be queued. May be NULL if completion events will not be used. */
int                     comp_vector;       /* Completion vector used to signal completion events. Must be >= 0 and < context->num_comp_vectors. */
uint64_t                wc_flags;          /* The wc_flags that should be returned in ibv_poll_cq_ex. Or'ed bit of enum ibv_wc_flags_ex. */
uint32_t                comp_mask;         /* compatibility mask (extended verb). */
uint32_t                flags              /* One or more flags from enum ibv_create_cq_attr_flags */
};
enum ibv_wc_flags_ex {
        IBV_WC_EX_WITH_BYTE_LEN              = 1 << 0,  /* Require byte len in WC */
        IBV_WC_EX_WITH_IMM                   = 1 << 1,  /* Require immediate in WC */
        IBV_WC_EX_WITH_QP_NUM                = 1 << 2,  /* Require QP number in WC */
        IBV_WC_EX_WITH_SRC_QP                = 1 << 3,  /* Require source QP in WC */
        IBV_WC_EX_WITH_SLID                  = 1 << 4,  /* Require slid in WC */
        IBV_WC_EX_WITH_SL                    = 1 << 5,  /* Require sl in WC */
        IBV_WC_EX_WITH_DLID_PATH_BITS        = 1 << 6,  /* Require dlid path bits in WC */
        IBV_WC_EX_WITH_COMPLETION_TIMESTAMP  = 1 << 7,  /* Require completion timestamp in WC /*
        IBV_WC_EX_WITH_CVLAN                 = 1 << 8,  /* Require VLAN info in WC */
        IBV_WC_EX_WITH_FLOW_TAG		     = 1 << 9,  /* Require flow tag in WC */
};
enum ibv_cq_init_attr_mask {
        IBV_CQ_INIT_ATTR_MASK_FLAGS             = 1 << 0,
};
enum ibv_create_cq_attr_flags {
        IBV_CREATE_CQ_ATTR_SINGLE_THREADED      = 1 << 0, /* This CQ is used from a single threaded, thus no locking is required */
};
```

## Polling an extended CQ

In order to poll an extended CQ efficiently, a user could use the following functions.

- **Completion iterator functions**

  **int ibv\_start\_poll(struct ibv\_cq\_ex** *\*cq***, struct ibv\_poll\_cq\_attr** *\*attr***)**\
   Start polling a batch of work completions. *attr* is given in order to make this function easily extensible in the future. This function either returns 0 on success or an error code otherwise. When no completions are available on the CQ, ENOENT is returned, but the CQ remains in a valid state. On success, querying the completion's attribute could be done using the query functions described below. If an error code is given, end\_poll shouldn't be called.

  **int ibv\_next\_poll(struct ibv\_cq\_ex** *\*cq***)**\
   This function is called in order to get the next work completion. It has to be called after *start\_poll* and before *end\_poll* are called. This function either returns 0 on success or an error code otherwise. When no completions are available on the CQ, ENOENT is returned, but the CQ remains in a valid state. On success, querying the completion's attribute could be done using the query functions described below. If an error code is given, end\_poll should still be called, indicating this is the end of the polled batch.

  **void ibv\_end\_poll(struct ibv\_cq\_ex** *\*cq***)**\
   This function indicates the end of polling batch of work completions. After calling this function, the user should start a new batch by calling *start\_poll.*

- **Polling fields in the completion**

  Below members and functions are used in order to poll the current completion. The current completion is the completion which the iterator points to (start\_poll and next\_poll advances this iterator). Only fields that the user requested via wc\_flags in ibv\_create\_cq\_ex could be queried. In addition, some fields are only valid in certain opcodes and status codes.

  **uint64\_t wr\_id - Can be accessed directly from struct ibv\_cq\_ex***.*

  **enum ibv\_wc\_status - Can be accessed directly from struct ibv\_cq\_ex***.*

  **enum ibv\_wc\_opcode ibv\_wc\_read\_opcode(struct ibv\_cq\_ex** *\*cq***);**\
    Get the opcode from the current completion.

  **uint32\_t ibv\_wc\_read\_vendor\_err(struct ibv\_cq\_ex** *\*cq***);**\
    Get the vendor error from the current completion.

  **uint32\_t ibv\_wc\_read\_byte\_len(struct ibv\_cq\_ex** *\*cq***);**\
    Get the vendor error from the current completion.

  **\_\_be32 ibv\_wc\_read\_imm\_data(struct ibv\_cq\_ex** *\*cq***);**\
    Get the immediate data field from the current completion.

  **uint32\_t ibv\_wc\_read\_invalidated\_rkey(struct ibv\_cq\_ex** *\*cq***);**\
    Get the rkey invalided by the SEND\_INVAL from the current completion.

  **uint32\_t ibv\_wc\_read\_qp\_num(struct ibv\_cq\_ex** *\*cq***);**\
    Get the QP number field from the current completion.

  **uint32\_t ibv\_wc\_read\_src\_qp(struct ibv\_cq\_ex** *\*cq***);**\
    Get the source QP number field from the current completion.

  **int ibv\_wc\_read\_wc\_flags(struct ibv\_cq\_ex** *\*cq***);**\
    Get the QP flags field from the current completion.

  **uint16\_t ibv\_wc\_read\_pkey\_index(struct ibv\_cq\_ex** *\*cq***);**\
    Get the pkey index field from the current completion.

  **uint32\_t ibv\_wc\_read\_slid(struct ibv\_cq\_ex** *\*cq***);**\
    Get the slid field from the current completion.

  **uint8\_t ibv\_wc\_read\_sl(struct ibv\_cq\_ex** *\*cq***);**\
    Get the sl field from the current completion.

  **uint8\_t ibv\_wc\_read\_dlid\_path\_bits(struct ibv\_cq\_ex** *\*cq***);**\
    Get the dlid\_path\_bits field from the current completion.

  **uint64\_t ibv\_wc\_read\_completion\_ts(struct ibv\_cq\_ex** *\*cq***);**\
    Get the completion timestamp from the current completion.

  **uint16\_t ibv\_wc\_read\_cvlan(struct ibv\_cq\_ex** *\*cq***);**\
    Get the CVLAN field from the current completion.

  **uint32\_t ibv\_wc\_read\_flow\_tag(struct ibv\_cq\_ex** *\*cq***);**\
    Get flow tag from the current completion.

## RETURN VALUE

**ibv\_create\_cq\_ex()** returns a pointer to the CQ, or NULL if the request fails.

## NOTES

**ibv\_create\_cq\_ex()** may create a CQ with size greater than or equal to the requested size. Check the cqe attribute in the returned CQ for the actual size.

CQ should be destroyed with ibv\_destroy\_cq.

## SEE ALSO

[**ibv\_create\_cq**(3)](/ibv_create_cq/3.md), [**ibv\_destroy\_cq**(3)](/ibv_destroy_cq/3.md), [**ibv\_resize\_cq**(3)](/ibv_resize_cq/3.md), [**ibv\_req\_notify\_cq**(3)](/ibv_req_notify_cq/3.md), [**ibv\_ack\_cq\_events**(3)](/ibv_ack_cq_events/3.md), [**ibv\_create\_qp**(3)](/ibv_create_qp/3.md)

## AUTHORS

- Matan Barak \<matanb@mellanox.com\>
