On 30/08/2019 9:15, Michal Kalderon wrote: >> From: Gal Pressman <galpress@xxxxxxxxxx> >> Sent: Thursday, August 29, 2019 5:21 PM >> >> On 27/08/2019 16:28, Michal Kalderon wrote: >>> +static void efa_qp_user_mmap_entries_remove(struct efa_ucontext >> *ucontext, >>> + struct efa_qp *qp) >>> +{ >>> + rdma_user_mmap_entry_remove(&ucontext->ibucontext, qp- >>> sq_db_mmap_key); >>> + rdma_user_mmap_entry_remove(&ucontext->ibucontext, >>> + qp->llq_desc_mmap_key); >>> + rdma_user_mmap_entry_remove(&ucontext->ibucontext, qp- >>> rq_mmap_key); >>> + rdma_user_mmap_entry_remove(&ucontext->ibucontext, >>> +qp->rq_db_mmap_key); >> >> Please remove the entries in reverse insertion order. > I don't mind fixing, but why ? So the flows will be symmetric. >> >>> +} >>> + >>> @@ -767,15 +726,17 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd, >>> >>> return &qp->ibqp; >>> >>> +err_remove_mmap_entries: >>> + efa_qp_user_mmap_entries_remove(ucontext, qp); >>> err_destroy_qp: >>> efa_destroy_qp_handle(dev, create_qp_resp.qp_handle); >>> err_free_mapped: >>> - if (qp->rq_size) { >>> + if (qp->rq_dma_addr) >> >> What's the difference? > Seemed a better query since it now only covers the rq_dma_addr unmapping. > >> >>> dma_unmap_single(&dev->pdev->dev, qp->rq_dma_addr, >> qp->rq_size, >>> DMA_TO_DEVICE); >>> - if (!rq_entry_inserted) >>> - free_pages_exact(qp->rq_cpu_addr, qp->rq_size); >>> - } >>> + >>> + if (qp->rq_mmap_key == RDMA_USER_MMAP_INVALID) >>> + free_pages_exact(qp->rq_cpu_addr, qp->rq_size); >> >> This should be inside the previous if statement, otherwise it might try to free >> pages that weren't allocated. > If they weren't allocated the key will be INVALID and they won't be freed. If the key is INVALID you call free_pages_exact, but rq_cpu_addr might have never been allocated (if RQ is of size zero). > >> >>> err_free_qp: >>> kfree(qp); >>> err_out: >>> @@ -887,6 +848,7 @@ static int efa_destroy_cq_idx(struct efa_dev *dev, >>> int cq_idx) >>> >>> void efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) { >>> + struct efa_ucontext *ucontext; >> >> Reverse xmas tree. > ok >> >>> struct efa_dev *dev = to_edev(ibcq->device); >>> struct efa_cq *cq = to_ecq(ibcq); >>> >>> @@ -894,20 +856,33 @@ void efa_destroy_cq(struct ib_cq *ibcq, struct >> ib_udata *udata) >>> "Destroy cq[%d] virt[0x%p] freed: size[%lu], dma[%pad]\n", >>> cq->cq_idx, cq->cpu_addr, cq->size, &cq->dma_addr); >>> >>> + ucontext = rdma_udata_to_drv_context(udata, struct efa_ucontext, >>> + ibucontext); >>> efa_destroy_cq_idx(dev, cq->cq_idx); >>> dma_unmap_single(&dev->pdev->dev, cq->dma_addr, cq->size, >>> DMA_FROM_DEVICE); >>> + rdma_user_mmap_entry_remove(&ucontext->ibucontext, >>> + cq->mmap_key); >> >> Entry removal should be first. > Why ? removing can lead to freeing, why would we want that before unmapping ? Makes sense, thanks. >> >>> } >>>