On Thu, Sep 06, 2018 at 04:49:40PM +0800, Yixian Liu wrote: > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c > index b16ad95..5b65f2b 100644 > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c > @@ -1255,6 +1255,10 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev) > HNS_ROCE_CAP_FLAG_RQ_INLINE | > HNS_ROCE_CAP_FLAG_RECORD_DB | > HNS_ROCE_CAP_FLAG_SQ_RECORD_DB; > + > + if (hr_dev->pci_dev->revision == 0x21) > + caps->flags |= HNS_ROCE_CAP_FLAG_MW; No extra horizontal space > diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c > index c5cae9a..ff71d91 100644 > +++ b/drivers/infiniband/hw/hns/hns_roce_main.c > @@ -584,6 +584,12 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) > ib_dev->uverbs_cmd_mask |= (1ULL << IB_USER_VERBS_CMD_REREG_MR); > } > > + /* MW */ > + if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_MW) { > + ib_dev->alloc_mw = hns_roce_alloc_mw; > + ib_dev->uverbs_cmd_mask |= (1ULL << IB_USER_VERBS_CMD_ALLOC_MW); > + } No extra horizontal space > +struct ib_mw *hns_roce_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type, > + struct ib_udata *udata) > +{ > + struct hns_roce_dev *hr_dev = to_hr_dev(ib_pd->device); > + struct hns_roce_mw *mw; > + unsigned long index = 0; > + int ret; > + > + mw = kmalloc(sizeof(*mw), GFP_KERNEL); > + if (!mw) > + return ERR_PTR(-ENOMEM); > + > + /* Allocate a key for mw from bitmap */ > + ret = hns_roce_bitmap_alloc(&hr_dev->mr_table.mtpt_bitmap, &index); > + if (ret) > + goto err_bitmap; > + > + mw->rkey = hw_index_to_key(index); > + > + if (ib_pd->uobject) { > + mw->ibmw.device = ib_pd->device; > + mw->ibmw.pd = ib_pd; > + mw->ibmw.uobject = ib_pd->uobject; What is this? ib_uverbs_alloc_mw does all of this: mw->device = pd->device; mw->pd = pd; mw->uobject = uobj; Why is there a user-space difference to this flow anyhow? very surprising. Jason