]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
IB/mlx4: Mark user mr as writable if actual virtual memory is writable
authorMoshe Lazer <moshel@mellanox.com>
Tue, 5 Aug 2014 15:16:46 +0000 (18:16 +0300)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Tue, 7 Jul 2015 21:45:22 +0000 (14:45 -0700)
To allow rereg mr (from read only mr to writablemr) without using
get_user_pages again, we need to define the initial mr as writable.
We shouldn't do this in case that user virtual memory is not
writable (e.g. const memory)

Signed-off-by: Moshe Lazer <moshel@mellanox.com>
(Ported from Mellanox OFED 2.4)

Signed-off-by: Mukesh Kacker <mukesh.kacker@oracle.com>
drivers/infiniband/hw/mlx4/mr.c

index 8e4889d447a4347133ee0a60102caca82ff4ff71..1cb08bd30072f254cfddff12f6d7480e7fd2ffb9 100644 (file)
@@ -391,15 +391,25 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        int shift;
        int err;
        int n;
+       struct vm_area_struct *vma;
+       int umem_flags = access_flags;
 
        mr = kmalloc(sizeof *mr, GFP_KERNEL);
        if (!mr)
                return ERR_PTR(-ENOMEM);
 
-       /* Force registering the memory as writable. */
+       /* If actual memory is writable, force registering the memory as writable. */
        /* Used for memory re-registeration. HCA protects the access */
+       if (!(umem_flags & IB_ACCESS_LOCAL_WRITE)) {
+               down_read(&current->mm->mmap_sem);
+               vma = find_vma(current->mm, start);
+               if (vma && (vma->vm_end >= start + length) &&
+                   (vma->vm_start <= start) && (vma->vm_flags & VM_WRITE))
+                       umem_flags |= IB_ACCESS_LOCAL_WRITE;
+               up_read(&current->mm->mmap_sem);
+       }
        mr->umem = ib_umem_get(pd->uobject->context, start, length,
-                              access_flags | IB_ACCESS_LOCAL_WRITE, 0);
+                                 umem_flags, 0);
        if (IS_ERR(mr->umem)) {
                err = PTR_ERR(mr->umem);
                goto err_free;