struct rpcrdma_frmr *f = &r->frmr;
        int rc;
 
-       f->fr_mr = ib_alloc_mr(ia->ri_pd, IB_MR_TYPE_MEM_REG, depth);
+       f->fr_mr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype, depth);
        if (IS_ERR(f->fr_mr))
                goto out_mr_err;
 
                return rc;
        }
 
-       f->fr_mr = ib_alloc_mr(ia->ri_pd, IB_MR_TYPE_MEM_REG,
+       f->fr_mr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype,
                               ia->ri_max_frmr_depth);
        if (IS_ERR(f->fr_mr)) {
                pr_warn("rpcrdma: ib_alloc_mr status %ld, frwr %p orphaned\n",
 frwr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
             struct rpcrdma_create_data_internal *cdata)
 {
+       struct ib_device_attr *attrs = &ia->ri_device->attrs;
        int depth, delta;
 
+       ia->ri_mrtype = IB_MR_TYPE_MEM_REG;
+       if (attrs->device_cap_flags & IB_DEVICE_SG_GAPS_REG)
+               ia->ri_mrtype = IB_MR_TYPE_SG_GAPS;
+
        ia->ri_max_frmr_depth =
                        min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
-                             ia->ri_device->attrs.max_fast_reg_page_list_len);
+                             attrs->max_fast_reg_page_list_len);
        dprintk("RPC:       %s: device's max FR page list len = %u\n",
                __func__, ia->ri_max_frmr_depth);
 
        }
 
        ep->rep_attr.cap.max_send_wr *= depth;
-       if (ep->rep_attr.cap.max_send_wr > ia->ri_device->attrs.max_qp_wr) {
-               cdata->max_requests = ia->ri_device->attrs.max_qp_wr / depth;
+       if (ep->rep_attr.cap.max_send_wr > attrs->max_qp_wr) {
+               cdata->max_requests = attrs->max_qp_wr / depth;
                if (!cdata->max_requests)
                        return -EINVAL;
                ep->rep_attr.cap.max_send_wr = cdata->max_requests *
            int nsegs, bool writing, struct rpcrdma_mw **out)
 {
        struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+       bool holes_ok = ia->ri_mrtype == IB_MR_TYPE_SG_GAPS;
        struct rpcrdma_mw *mw;
        struct rpcrdma_frmr *frmr;
        struct ib_mr *mr;
 
                ++seg;
                ++i;
-
-               /* Check for holes */
+               if (holes_ok)
+                       continue;
                if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
                    offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
                        break;