]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/rds/ib_fmr.c
Merge tag 'acpi-extra-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-artful-kernel.git] / net / rds / ib_fmr.c
index 4fe8f4fec4eee66c826b5beb5b02ae61d19b483a..86ef907067bb084e01ac4f8d5f00d0c17f40ac55 100644 (file)
@@ -78,17 +78,15 @@ struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev, int npages)
        return ibmr;
 
 out_no_cigar:
-       if (ibmr) {
-               if (fmr->fmr)
-                       ib_dealloc_fmr(fmr->fmr);
-               kfree(ibmr);
-       }
+       kfree(ibmr);
        atomic_dec(&pool->item_count);
+
        return ERR_PTR(err);
 }
 
-int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibmr,
-                  struct scatterlist *sg, unsigned int nents)
+static int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev,
+                         struct rds_ib_mr *ibmr, struct scatterlist *sg,
+                         unsigned int nents)
 {
        struct ib_device *dev = rds_ibdev->dev;
        struct rds_ib_fmr *fmr = &ibmr->u.fmr;
@@ -114,29 +112,39 @@ int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibmr,
                u64 dma_addr = ib_sg_dma_address(dev, &scat[i]);
 
                if (dma_addr & ~PAGE_MASK) {
-                       if (i > 0)
+                       if (i > 0) {
+                               ib_dma_unmap_sg(dev, sg, nents,
+                                               DMA_BIDIRECTIONAL);
                                return -EINVAL;
-                       else
+                       } else {
                                ++page_cnt;
+                       }
                }
                if ((dma_addr + dma_len) & ~PAGE_MASK) {
-                       if (i < sg_dma_len - 1)
+                       if (i < sg_dma_len - 1) {
+                               ib_dma_unmap_sg(dev, sg, nents,
+                                               DMA_BIDIRECTIONAL);
                                return -EINVAL;
-                       else
+                       } else {
                                ++page_cnt;
+                       }
                }
 
                len += dma_len;
        }
 
        page_cnt += len >> PAGE_SHIFT;
-       if (page_cnt > ibmr->pool->fmr_attr.max_pages)
+       if (page_cnt > ibmr->pool->fmr_attr.max_pages) {
+               ib_dma_unmap_sg(dev, sg, nents, DMA_BIDIRECTIONAL);
                return -EINVAL;
+       }
 
        dma_pages = kmalloc_node(sizeof(u64) * page_cnt, GFP_ATOMIC,
                                 rdsibdev_to_node(rds_ibdev));
-       if (!dma_pages)
+       if (!dma_pages) {
+               ib_dma_unmap_sg(dev, sg, nents, DMA_BIDIRECTIONAL);
                return -ENOMEM;
+       }
 
        page_cnt = 0;
        for (i = 0; i < sg_dma_len; ++i) {
@@ -149,8 +157,10 @@ int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibmr,
        }
 
        ret = ib_map_phys_fmr(fmr->fmr, dma_pages, page_cnt, io_addr);
-       if (ret)
+       if (ret) {
+               ib_dma_unmap_sg(dev, sg, nents, DMA_BIDIRECTIONAL);
                goto out;
+       }
 
        /* Success - we successfully remapped the MR, so we can
         * safely tear down the old mapping.