|
@@ -227,9 +227,11 @@ EXPORT_SYMBOL(rdma_port_get_link_layer);
|
|
|
* Every PD has a local_dma_lkey which can be used as the lkey value for local
|
|
|
* memory operations.
|
|
|
*/
|
|
|
-struct ib_pd *ib_alloc_pd(struct ib_device *device)
|
|
|
+struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
|
|
|
+ const char *caller)
|
|
|
{
|
|
|
struct ib_pd *pd;
|
|
|
+ int mr_access_flags = 0;
|
|
|
|
|
|
pd = device->alloc_pd(device, NULL, NULL);
|
|
|
if (IS_ERR(pd))
|
|
@@ -239,24 +241,39 @@ struct ib_pd *ib_alloc_pd(struct ib_device *device)
|
|
|
pd->uobject = NULL;
|
|
|
pd->__internal_mr = NULL;
|
|
|
atomic_set(&pd->usecnt, 0);
|
|
|
+ pd->flags = flags;
|
|
|
|
|
|
if (device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
|
|
|
pd->local_dma_lkey = device->local_dma_lkey;
|
|
|
- else {
|
|
|
+ else
|
|
|
+ mr_access_flags |= IB_ACCESS_LOCAL_WRITE;
|
|
|
+
|
|
|
+ if (flags & IB_PD_UNSAFE_GLOBAL_RKEY) {
|
|
|
+ pr_warn("%s: enabling unsafe global rkey\n", caller);
|
|
|
+ mr_access_flags |= IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_WRITE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (mr_access_flags) {
|
|
|
struct ib_mr *mr;
|
|
|
|
|
|
- mr = ib_get_dma_mr(pd, IB_ACCESS_LOCAL_WRITE);
|
|
|
+ mr = ib_get_dma_mr(pd, mr_access_flags);
|
|
|
if (IS_ERR(mr)) {
|
|
|
ib_dealloc_pd(pd);
|
|
|
return (struct ib_pd *)mr;
|
|
|
}
|
|
|
|
|
|
pd->__internal_mr = mr;
|
|
|
- pd->local_dma_lkey = pd->__internal_mr->lkey;
|
|
|
+
|
|
|
+ if (!(device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY))
|
|
|
+ pd->local_dma_lkey = pd->__internal_mr->lkey;
|
|
|
+
|
|
|
+ if (flags & IB_PD_UNSAFE_GLOBAL_RKEY)
|
|
|
+ pd->unsafe_global_rkey = pd->__internal_mr->rkey;
|
|
|
}
|
|
|
+
|
|
|
return pd;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(ib_alloc_pd);
|
|
|
+EXPORT_SYMBOL(__ib_alloc_pd);
|
|
|
|
|
|
/**
|
|
|
* ib_dealloc_pd - Deallocates a protection domain.
|