DMA_TO_DEVICE);
        }
        sg_free_table(&buf_desc->sgt[SMC_SINGLE_LINK]);
-       if (buf_desc->cpu_addr)
-               free_pages((unsigned long)buf_desc->cpu_addr, buf_desc->order);
+       if (buf_desc->pages)
+               __free_pages(buf_desc->pages, buf_desc->order);
        kfree(buf_desc);
 }
 
        if (!buf_desc)
                return ERR_PTR(-ENOMEM);
 
-       buf_desc->cpu_addr =
-               (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN |
-                                        __GFP_NOMEMALLOC |
-                                        __GFP_NORETRY | __GFP_ZERO,
-                                        get_order(bufsize));
-       if (!buf_desc->cpu_addr) {
+       buf_desc->order = get_order(bufsize);
+       buf_desc->pages = alloc_pages(GFP_KERNEL | __GFP_NOWARN |
+                                     __GFP_NOMEMALLOC | __GFP_COMP |
+                                     __GFP_NORETRY | __GFP_ZERO,
+                                     buf_desc->order);
+       if (!buf_desc->pages) {
                kfree(buf_desc);
                return ERR_PTR(-EAGAIN);
        }
-       buf_desc->order = get_order(bufsize);
+       buf_desc->cpu_addr = (void *)page_address(buf_desc->pages);
 
        /* build the sg table from the pages */
        lnk = &lgr->lnk[SMC_SINGLE_LINK];
 
 struct smc_buf_desc {
        struct list_head        list;
        void                    *cpu_addr;      /* virtual address of buffer */
+       struct page             *pages;
        struct sg_table         sgt[SMC_LINKS_PER_LGR_MAX];/* virtual buffer */
        struct ib_mr            *mr_rx[SMC_LINKS_PER_LGR_MAX];
                                                /* for rmb only: memory region