On Wed, Apr 03, 2019 at 04:42:43PM +0300, Leon Romanovsky wrote: > diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c > index 6172019481a4..aa3c80c5c26f 100644 > +++ b/drivers/infiniband/core/verbs.c > @@ -964,31 +964,38 @@ struct ib_srq *ib_create_srq(struct ib_pd *pd, > struct ib_srq_init_attr *srq_init_attr) > { > struct ib_srq *srq; > + int ret; > > if (!pd->device->ops.create_srq) > return ERR_PTR(-EOPNOTSUPP); > > - srq = pd->device->ops.create_srq(pd, srq_init_attr, NULL); > - > - if (!IS_ERR(srq)) { > - srq->device = pd->device; > - srq->pd = pd; > - srq->uobject = NULL; > - srq->event_handler = srq_init_attr->event_handler; > - srq->srq_context = srq_init_attr->srq_context; > - srq->srq_type = srq_init_attr->srq_type; > - if (ib_srq_has_cq(srq->srq_type)) { > - srq->ext.cq = srq_init_attr->ext.cq; > - atomic_inc(&srq->ext.cq->usecnt); > - } > - if (srq->srq_type == IB_SRQT_XRC) { > - srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd; > - atomic_inc(&srq->ext.xrc.xrcd->usecnt); > - } > - atomic_inc(&pd->usecnt); > - atomic_set(&srq->usecnt, 0); > + srq = rdma_zalloc_drv_obj(pd->device, ib_srq); > + if (!srq) > + return ERR_PTR(-ENOMEM); > + > + srq->device = pd->device; > + srq->pd = pd; > + srq->event_handler = srq_init_attr->event_handler; > + srq->srq_context = srq_init_attr->srq_context; > + srq->srq_type = srq_init_attr->srq_type; > + > + ret = pd->device->ops.create_srq(srq, srq_init_attr, NULL); > + if (ret) { > + kfree(srq); > + return ERR_PTR(ret); > } > > + if (ib_srq_has_cq(srq->srq_type)) { > + srq->ext.cq = srq_init_attr->ext.cq; > + atomic_inc(&srq->ext.cq->usecnt); > + } > + if (srq->srq_type == IB_SRQT_XRC) { > + srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd; > + atomic_inc(&srq->ext.xrc.xrcd->usecnt); > + } In the new model the driver call should always be the last thing during create and the first thing during destroy. The driver should always see a fully initialized core object. I fixed it up.. Jason