Skip to content

Commit 5fd251c

Browse files
yishaihdledford
authored andcommitted
IB/core: Introduce Work Queue object and its verbs
Introduce Work Queue object and its create/destroy/modify verbs. QP can be created without internal WQs "packaged" inside it, this QP can be configured to use "external" WQ object as its receive/send queue. WQ is a necessary component for RSS technology since RSS mechanism is supposed to distribute the traffic between multiple Receive Work Queues. WQ associated (many to one) with Completion Queue and it owns WQ properties (PD, WQ size, etc.). WQ has a type, this patch introduces the IB_WQT_RQ (i.e.receive queue), it may be extend to others such as IB_WQT_SQ. (send queue). WQ from type IB_WQT_RQ contains receive work requests. PD is an attribute of a work queue (i.e. send/receive queue), it's used by the hardware for security validation before scattering to a memory region which is pointed by the WQ. For that, an external WQ object needs a PD, letting the hardware makes that validation. When accessing a memory region that is pointed by the WQ its PD is used and not the QP's PD, this behavior is similar to a SRQ and a QP. WQ context is subject to a well-defined state transitions done by the modify_wq verb. When WQ is created its initial state becomes IB_WQS_RESET. >From IB_WQS_RESET it can be modified to itself or to IB_WQS_RDY. >From IB_WQS_RDY it can be modified to itself, to IB_WQS_RESET or to IB_WQS_ERR. >From IB_WQS_ERR it can be modified to IB_WQS_RESET. Note: transition to IB_WQS_ERR might occur implicitly in case there was some HW error. Signed-off-by: Yishai Hadas <[email protected]> Signed-off-by: Matan Barak <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 16bd020 commit 5fd251c

File tree

2 files changed

+137
-1
lines changed

2 files changed

+137
-1
lines changed

drivers/infiniband/core/verbs.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,88 @@ int ib_dealloc_xrcd(struct ib_xrcd *xrcd)
15541554
}
15551555
EXPORT_SYMBOL(ib_dealloc_xrcd);
15561556

1557+
/**
1558+
* ib_create_wq - Creates a WQ associated with the specified protection
1559+
* domain.
1560+
* @pd: The protection domain associated with the WQ.
1561+
* @wq_init_attr: A list of initial attributes required to create the
1562+
* WQ. If WQ creation succeeds, then the attributes are updated to
1563+
* the actual capabilities of the created WQ.
1564+
*
1565+
* wq_init_attr->max_wr and wq_init_attr->max_sge determine
1566+
* the requested size of the WQ, and set to the actual values allocated
1567+
* on return.
1568+
* If ib_create_wq() succeeds, then max_wr and max_sge will always be
1569+
* at least as large as the requested values.
1570+
*/
1571+
struct ib_wq *ib_create_wq(struct ib_pd *pd,
1572+
struct ib_wq_init_attr *wq_attr)
1573+
{
1574+
struct ib_wq *wq;
1575+
1576+
if (!pd->device->create_wq)
1577+
return ERR_PTR(-ENOSYS);
1578+
1579+
wq = pd->device->create_wq(pd, wq_attr, NULL);
1580+
if (!IS_ERR(wq)) {
1581+
wq->event_handler = wq_attr->event_handler;
1582+
wq->wq_context = wq_attr->wq_context;
1583+
wq->wq_type = wq_attr->wq_type;
1584+
wq->cq = wq_attr->cq;
1585+
wq->device = pd->device;
1586+
wq->pd = pd;
1587+
wq->uobject = NULL;
1588+
atomic_inc(&pd->usecnt);
1589+
atomic_inc(&wq_attr->cq->usecnt);
1590+
atomic_set(&wq->usecnt, 0);
1591+
}
1592+
return wq;
1593+
}
1594+
EXPORT_SYMBOL(ib_create_wq);
1595+
1596+
/**
1597+
* ib_destroy_wq - Destroys the specified WQ.
1598+
* @wq: The WQ to destroy.
1599+
*/
1600+
int ib_destroy_wq(struct ib_wq *wq)
1601+
{
1602+
int err;
1603+
struct ib_cq *cq = wq->cq;
1604+
struct ib_pd *pd = wq->pd;
1605+
1606+
if (atomic_read(&wq->usecnt))
1607+
return -EBUSY;
1608+
1609+
err = wq->device->destroy_wq(wq);
1610+
if (!err) {
1611+
atomic_dec(&pd->usecnt);
1612+
atomic_dec(&cq->usecnt);
1613+
}
1614+
return err;
1615+
}
1616+
EXPORT_SYMBOL(ib_destroy_wq);
1617+
1618+
/**
1619+
* ib_modify_wq - Modifies the specified WQ.
1620+
* @wq: The WQ to modify.
1621+
* @wq_attr: On input, specifies the WQ attributes to modify.
1622+
* @wq_attr_mask: A bit-mask used to specify which attributes of the WQ
1623+
* are being modified.
1624+
* On output, the current values of selected WQ attributes are returned.
1625+
*/
1626+
int ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
1627+
u32 wq_attr_mask)
1628+
{
1629+
int err;
1630+
1631+
if (!wq->device->modify_wq)
1632+
return -ENOSYS;
1633+
1634+
err = wq->device->modify_wq(wq, wq_attr, wq_attr_mask, NULL);
1635+
return err;
1636+
}
1637+
EXPORT_SYMBOL(ib_modify_wq);
1638+
15571639
struct ib_flow *ib_create_flow(struct ib_qp *qp,
15581640
struct ib_flow_attr *flow_attr,
15591641
int domain)

include/rdma/ib_verbs.h

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,48 @@ struct ib_srq {
14281428
} ext;
14291429
};
14301430

1431+
enum ib_wq_type {
1432+
IB_WQT_RQ
1433+
};
1434+
1435+
enum ib_wq_state {
1436+
IB_WQS_RESET,
1437+
IB_WQS_RDY,
1438+
IB_WQS_ERR
1439+
};
1440+
1441+
struct ib_wq {
1442+
struct ib_device *device;
1443+
struct ib_uobject *uobject;
1444+
void *wq_context;
1445+
void (*event_handler)(struct ib_event *, void *);
1446+
struct ib_pd *pd;
1447+
struct ib_cq *cq;
1448+
u32 wq_num;
1449+
enum ib_wq_state state;
1450+
enum ib_wq_type wq_type;
1451+
atomic_t usecnt;
1452+
};
1453+
1454+
struct ib_wq_init_attr {
1455+
void *wq_context;
1456+
enum ib_wq_type wq_type;
1457+
u32 max_wr;
1458+
u32 max_sge;
1459+
struct ib_cq *cq;
1460+
void (*event_handler)(struct ib_event *, void *);
1461+
};
1462+
1463+
enum ib_wq_attr_mask {
1464+
IB_WQ_STATE = 1 << 0,
1465+
IB_WQ_CUR_STATE = 1 << 1,
1466+
};
1467+
1468+
struct ib_wq_attr {
1469+
enum ib_wq_state wq_state;
1470+
enum ib_wq_state curr_wq_state;
1471+
};
1472+
14311473
struct ib_qp {
14321474
struct ib_device *device;
14331475
struct ib_pd *pd;
@@ -1921,7 +1963,14 @@ struct ib_device {
19211963
struct ifla_vf_stats *stats);
19221964
int (*set_vf_guid)(struct ib_device *device, int vf, u8 port, u64 guid,
19231965
int type);
1924-
1966+
struct ib_wq * (*create_wq)(struct ib_pd *pd,
1967+
struct ib_wq_init_attr *init_attr,
1968+
struct ib_udata *udata);
1969+
int (*destroy_wq)(struct ib_wq *wq);
1970+
int (*modify_wq)(struct ib_wq *wq,
1971+
struct ib_wq_attr *attr,
1972+
u32 wq_attr_mask,
1973+
struct ib_udata *udata);
19251974
struct ib_dma_mapping_ops *dma_ops;
19261975

19271976
struct module *owner;
@@ -3167,6 +3216,11 @@ int ib_check_mr_status(struct ib_mr *mr, u32 check_mask,
31673216
struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, u8 port,
31683217
u16 pkey, const union ib_gid *gid,
31693218
const struct sockaddr *addr);
3219+
struct ib_wq *ib_create_wq(struct ib_pd *pd,
3220+
struct ib_wq_init_attr *init_attr);
3221+
int ib_destroy_wq(struct ib_wq *wq);
3222+
int ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *attr,
3223+
u32 wq_attr_mask);
31703224

31713225
int ib_map_mr_sg(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,
31723226
unsigned int *sg_offset, unsigned int page_size);

0 commit comments

Comments
 (0)