@@ -254,6 +254,7 @@ int efa_query_device(struct ib_device *ibdev,
254254 resp .max_rdma_size = dev_attr -> max_rdma_size ;
255255
256256 resp .device_caps |= EFA_QUERY_DEVICE_CAPS_CQ_WITH_SGID ;
257+ resp .device_caps |= EFA_QUERY_DEVICE_CAPS_CQ_WITH_EXT_MEM ;
257258 if (EFA_DEV_CAP (dev , RDMA_READ ))
258259 resp .device_caps |= EFA_QUERY_DEVICE_CAPS_RDMA_READ ;
259260
@@ -1087,8 +1088,11 @@ int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
10871088 xa_erase (& dev -> cqs_xa , cq -> cq_idx );
10881089 synchronize_irq (cq -> eq -> irq .irqn );
10891090 }
1090- efa_free_mapped (dev , cq -> cpu_addr , cq -> dma_addr , cq -> size ,
1091- DMA_FROM_DEVICE );
1091+
1092+ if (cq -> umem )
1093+ ib_umem_release (cq -> umem );
1094+ else
1095+ efa_free_mapped (dev , cq -> cpu_addr , cq -> dma_addr , cq -> size , DMA_FROM_DEVICE );
10921096 return 0 ;
10931097}
10941098
@@ -1127,8 +1131,8 @@ static int cq_mmap_entries_setup(struct efa_dev *dev, struct efa_cq *cq,
11271131 return 0 ;
11281132}
11291133
1130- int efa_create_cq (struct ib_cq * ibcq , const struct ib_cq_init_attr * attr ,
1131- struct uverbs_attr_bundle * attrs )
1134+ int efa_create_cq_umem (struct ib_cq * ibcq , const struct ib_cq_init_attr * attr ,
1135+ struct ib_umem * umem , struct uverbs_attr_bundle * attrs )
11321136{
11331137 struct ib_udata * udata = & attrs -> driver_udata ;
11341138 struct efa_ucontext * ucontext = rdma_udata_to_drv_context (
@@ -1207,11 +1211,30 @@ int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
12071211
12081212 cq -> ucontext = ucontext ;
12091213 cq -> size = PAGE_ALIGN (cmd .cq_entry_size * entries * cmd .num_sub_cqs );
1210- cq -> cpu_addr = efa_zalloc_mapped (dev , & cq -> dma_addr , cq -> size ,
1211- DMA_FROM_DEVICE );
1212- if (!cq -> cpu_addr ) {
1213- err = - ENOMEM ;
1214- goto err_out ;
1214+
1215+ if (umem ) {
1216+ if (umem -> length < cq -> size ) {
1217+ ibdev_dbg (& dev -> ibdev , "External memory too small\n" );
1218+ err = - EINVAL ;
1219+ goto err_free_mem ;
1220+ }
1221+
1222+ if (!ib_umem_is_contiguous (umem )) {
1223+ ibdev_dbg (& dev -> ibdev , "Non contiguous CQ unsupported\n" );
1224+ err = - EINVAL ;
1225+ goto err_free_mem ;
1226+ }
1227+
1228+ cq -> cpu_addr = NULL ;
1229+ cq -> dma_addr = ib_umem_start_dma_addr (umem );
1230+ cq -> umem = umem ;
1231+ } else {
1232+ cq -> cpu_addr = efa_zalloc_mapped (dev , & cq -> dma_addr , cq -> size ,
1233+ DMA_FROM_DEVICE );
1234+ if (!cq -> cpu_addr ) {
1235+ err = - ENOMEM ;
1236+ goto err_out ;
1237+ }
12151238 }
12161239
12171240 params .uarn = cq -> ucontext -> uarn ;
@@ -1228,15 +1251,17 @@ int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
12281251
12291252 err = efa_com_create_cq (& dev -> edev , & params , & result );
12301253 if (err )
1231- goto err_free_mapped ;
1254+ goto err_free_mem ;
12321255
12331256 resp .db_off = result .db_off ;
12341257 resp .cq_idx = result .cq_idx ;
12351258 cq -> cq_idx = result .cq_idx ;
12361259 cq -> ibcq .cqe = result .actual_depth ;
12371260 WARN_ON_ONCE (entries != result .actual_depth );
12381261
1239- err = cq_mmap_entries_setup (dev , cq , & resp , result .db_valid );
1262+ if (!umem )
1263+ err = cq_mmap_entries_setup (dev , cq , & resp , result .db_valid );
1264+
12401265 if (err ) {
12411266 ibdev_dbg (ibdev , "Could not setup cq[%u] mmap entries\n" ,
12421267 cq -> cq_idx );
@@ -1274,15 +1299,23 @@ int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
12741299 efa_cq_user_mmap_entries_remove (cq );
12751300err_destroy_cq :
12761301 efa_destroy_cq_idx (dev , cq -> cq_idx );
1277- err_free_mapped :
1278- efa_free_mapped (dev , cq -> cpu_addr , cq -> dma_addr , cq -> size ,
1279- DMA_FROM_DEVICE );
1302+ err_free_mem :
1303+ if (umem )
1304+ ib_umem_release (umem );
1305+ else
1306+ efa_free_mapped (dev , cq -> cpu_addr , cq -> dma_addr , cq -> size , DMA_FROM_DEVICE );
12801307
12811308err_out :
12821309 atomic64_inc (& dev -> stats .create_cq_err );
12831310 return err ;
12841311}
12851312
1313+ int efa_create_cq (struct ib_cq * ibcq , const struct ib_cq_init_attr * attr ,
1314+ struct uverbs_attr_bundle * attrs )
1315+ {
1316+ return efa_create_cq_umem (ibcq , attr , NULL , attrs );
1317+ }
1318+
12861319static int umem_to_page_list (struct efa_dev * dev ,
12871320 struct ib_umem * umem ,
12881321 u64 * page_list ,
0 commit comments