Hey Vlad,

This change, along with a libcxgb3 fix resolves bug 353.

You can pull this ofed_1_2 change directly from:

git://staging.openfabrics.org/~swise/ofed_1_2 ofed_1_2

Thanks,

Steve.


---------------------------

Reserve the pages of dma coherent memory for older kernels.

Signed-off-by: Steve Wise <[EMAIL PROTECTED]>
---

 .../2.6.5_sles9_sp3/cxio_hal_to_2.6.14.patch       |  127 
+++++++++++++++++++++++
 .../backport/2.6.9_U2/cxio_hal_to_2.6.14.patch     |  127 
+++++++++++++++++++++++
 .../2.6.9_U2/iwch_provider_to_2.6.9_U4.patch       |   16 +++
 .../backport/2.6.9_U3/cxio_hal_to_2.6.14.patch     |  127 
+++++++++++++++++++++++
 .../2.6.9_U3/iwch_provider_to_2.6.9_U4.patch       |   16 +++
 .../backport/2.6.9_U4/cxio_hal_to_2.6.14.patch     |  127 
+++++++++++++++++++++++
 6 files changed, 540 insertions(+), 0 deletions(-)

diff --git a/kernel_patches/backport/2.6.5_sles9_sp3/cxio_hal_to_2.6.14.patch 
b/kernel_patches/backport/2.6.5_sles9_sp3/cxio_hal_to_2.6.14.patch
new file mode 100644
index 0000000..34556bb
--- /dev/null
+++ b/kernel_patches/backport/2.6.5_sles9_sp3/cxio_hal_to_2.6.14.patch
@@ -0,0 +1,127 @@
+Reserve pages to support userspace mapping in older kernels.
+
+From: Steve Wise <[EMAIL PROTECTED]>
+
+This is needed for kernels prior to 2.6.15 to correctly map kernel
+memory into userspace.
+
+Signed-off-by: Steve Wise <[EMAIL PROTECTED]>
+---
+
+ drivers/infiniband/hw/cxgb3/core/cxio_hal.c |   53 +++++++++++++++++++--------
+ 1 files changed, 38 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/infiniband/hw/cxgb3/core/cxio_hal.c 
b/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
+index 229edd5..067fe46 100644
+--- a/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
++++ b/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
+@@ -170,10 +170,30 @@ int cxio_hal_clear_qp_ctx(struct cxio_rd
+       return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+ }
+ 
++static void reserve_pages(void *p, int size)
++{
++      while (size > 0) {
++              SetPageReserved(virt_to_page(p));
++              p += PAGE_SIZE;
++              size -= PAGE_SIZE;
++      }
++      BUG_ON(size < 0);
++}
++
++static void unreserve_pages(void *p, int size)
++{
++      while (size > 0) {
++              ClearPageReserved(virt_to_page(p));
++              p += PAGE_SIZE;
++              size -= PAGE_SIZE;
++      }
++      BUG_ON(size < 0);
++}
++
+ int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+ {
+       struct rdma_cq_setup setup;
+-      int size = (1UL << (cq->size_log2)) * sizeof(struct t3_cqe);
++      int size = PAGE_ALIGN((1UL << (cq->size_log2)) * sizeof(struct t3_cqe));
+ 
+       cq->cqid = cxio_hal_get_cqid(rdev_p->rscp);
+       if (!cq->cqid)
+@@ -181,16 +201,15 @@ int cxio_create_cq(struct cxio_rdev *rde
+       cq->sw_queue = kzalloc(size, GFP_KERNEL);
+       if (!cq->sw_queue)
+               return -ENOMEM;
+-      cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                                           (1UL << (cq->size_log2)) *
+-                                           sizeof(struct t3_cqe),
+-                                           &(cq->dma_addr), GFP_KERNEL);
++      cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
++                                     &(cq->dma_addr), GFP_KERNEL);
+       if (!cq->queue) {
+               kfree(cq->sw_queue);
+               return -ENOMEM;
+       }
+       pci_unmap_addr_set(cq, mapping, cq->dma_addr);
+       memset(cq->queue, 0, size);
++      reserve_pages(cq->queue, size);
+       setup.id = cq->cqid;
+       setup.base_addr = (u64) (cq->dma_addr);
+       setup.size = 1UL << cq->size_log2;
+@@ -288,6 +307,7 @@ int cxio_create_qp(struct cxio_rdev *rde
+ {
+       int depth = 1UL << wq->size_log2;
+       int rqsize = 1UL << wq->rq_size_log2;
++      int size = PAGE_ALIGN(depth * sizeof(union t3_wr));
+ 
+       wq->qpid = get_qpid(rdev_p, uctx);
+       if (!wq->qpid)
+@@ -305,14 +325,15 @@ int cxio_create_qp(struct cxio_rdev *rde
+       if (!wq->sq)
+               goto err3;
+       
+-      wq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                                           depth * sizeof(union t3_wr),
+-                                           &(wq->dma_addr), GFP_KERNEL);
++      wq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
++                                     &(wq->dma_addr), GFP_KERNEL);
+       if (!wq->queue)
+               goto err4;
+ 
+-      memset(wq->queue, 0, depth * sizeof(union t3_wr));
+       pci_unmap_addr_set(wq, mapping, wq->dma_addr);
++      memset(wq->queue, 0, size);
++      reserve_pages(wq->queue, size);
++
+       wq->doorbell = (void __iomem *)rdev_p->rnic_info.kdb_addr;
+       if (!kernel_domain)
+               wq->udb = (u64)rdev_p->rnic_info.udbell_physbase +
+@@ -334,11 +355,12 @@ err1:
+ int cxio_destroy_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+ {
+       int err;
++      int size = PAGE_ALIGN((1UL << (cq->size_log2)) * sizeof(struct t3_cqe));
++
+       err = cxio_hal_clear_cq_ctx(rdev_p, cq->cqid);
+       kfree(cq->sw_queue);
+-      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                        (1UL << (cq->size_log2))
+-                        * sizeof(struct t3_cqe), cq->queue,
++      unreserve_pages(cq->queue, size);
++      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev), size, cq->queue,
+                         pci_unmap_addr(cq, mapping));
+       cxio_hal_put_cqid(rdev_p->rscp, cq->cqid);
+       return err;
+@@ -347,9 +369,10 @@ int cxio_destroy_cq(struct cxio_rdev *rd
+ int cxio_destroy_qp(struct cxio_rdev *rdev_p, struct t3_wq *wq,
+                   struct cxio_ucontext *uctx)
+ {
+-      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                        (1UL << (wq->size_log2))
+-                        * sizeof(union t3_wr), wq->queue,
++      int size = PAGE_ALIGN((1UL << (wq->size_log2)) * sizeof(union t3_wr));
++
++      unreserve_pages(wq->queue, size);
++      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev), size, wq->queue,
+                         pci_unmap_addr(wq, mapping));
+       kfree(wq->sq);
+       cxio_hal_rqtpool_free(rdev_p, wq->rq_addr, (1UL << wq->rq_size_log2));
diff --git a/kernel_patches/backport/2.6.9_U2/cxio_hal_to_2.6.14.patch 
b/kernel_patches/backport/2.6.9_U2/cxio_hal_to_2.6.14.patch
new file mode 100644
index 0000000..34556bb
--- /dev/null
+++ b/kernel_patches/backport/2.6.9_U2/cxio_hal_to_2.6.14.patch
@@ -0,0 +1,127 @@
+Reserve pages to support userspace mapping in older kernels.
+
+From: Steve Wise <[EMAIL PROTECTED]>
+
+This is needed for kernels prior to 2.6.15 to correctly map kernel
+memory into userspace.
+
+Signed-off-by: Steve Wise <[EMAIL PROTECTED]>
+---
+
+ drivers/infiniband/hw/cxgb3/core/cxio_hal.c |   53 +++++++++++++++++++--------
+ 1 files changed, 38 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/infiniband/hw/cxgb3/core/cxio_hal.c 
b/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
+index 229edd5..067fe46 100644
+--- a/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
++++ b/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
+@@ -170,10 +170,30 @@ int cxio_hal_clear_qp_ctx(struct cxio_rd
+       return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+ }
+ 
++static void reserve_pages(void *p, int size)
++{
++      while (size > 0) {
++              SetPageReserved(virt_to_page(p));
++              p += PAGE_SIZE;
++              size -= PAGE_SIZE;
++      }
++      BUG_ON(size < 0);
++}
++
++static void unreserve_pages(void *p, int size)
++{
++      while (size > 0) {
++              ClearPageReserved(virt_to_page(p));
++              p += PAGE_SIZE;
++              size -= PAGE_SIZE;
++      }
++      BUG_ON(size < 0);
++}
++
+ int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+ {
+       struct rdma_cq_setup setup;
+-      int size = (1UL << (cq->size_log2)) * sizeof(struct t3_cqe);
++      int size = PAGE_ALIGN((1UL << (cq->size_log2)) * sizeof(struct t3_cqe));
+ 
+       cq->cqid = cxio_hal_get_cqid(rdev_p->rscp);
+       if (!cq->cqid)
+@@ -181,16 +201,15 @@ int cxio_create_cq(struct cxio_rdev *rde
+       cq->sw_queue = kzalloc(size, GFP_KERNEL);
+       if (!cq->sw_queue)
+               return -ENOMEM;
+-      cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                                           (1UL << (cq->size_log2)) *
+-                                           sizeof(struct t3_cqe),
+-                                           &(cq->dma_addr), GFP_KERNEL);
++      cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
++                                     &(cq->dma_addr), GFP_KERNEL);
+       if (!cq->queue) {
+               kfree(cq->sw_queue);
+               return -ENOMEM;
+       }
+       pci_unmap_addr_set(cq, mapping, cq->dma_addr);
+       memset(cq->queue, 0, size);
++      reserve_pages(cq->queue, size);
+       setup.id = cq->cqid;
+       setup.base_addr = (u64) (cq->dma_addr);
+       setup.size = 1UL << cq->size_log2;
+@@ -288,6 +307,7 @@ int cxio_create_qp(struct cxio_rdev *rde
+ {
+       int depth = 1UL << wq->size_log2;
+       int rqsize = 1UL << wq->rq_size_log2;
++      int size = PAGE_ALIGN(depth * sizeof(union t3_wr));
+ 
+       wq->qpid = get_qpid(rdev_p, uctx);
+       if (!wq->qpid)
+@@ -305,14 +325,15 @@ int cxio_create_qp(struct cxio_rdev *rde
+       if (!wq->sq)
+               goto err3;
+       
+-      wq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                                           depth * sizeof(union t3_wr),
+-                                           &(wq->dma_addr), GFP_KERNEL);
++      wq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
++                                     &(wq->dma_addr), GFP_KERNEL);
+       if (!wq->queue)
+               goto err4;
+ 
+-      memset(wq->queue, 0, depth * sizeof(union t3_wr));
+       pci_unmap_addr_set(wq, mapping, wq->dma_addr);
++      memset(wq->queue, 0, size);
++      reserve_pages(wq->queue, size);
++
+       wq->doorbell = (void __iomem *)rdev_p->rnic_info.kdb_addr;
+       if (!kernel_domain)
+               wq->udb = (u64)rdev_p->rnic_info.udbell_physbase +
+@@ -334,11 +355,12 @@ err1:
+ int cxio_destroy_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+ {
+       int err;
++      int size = PAGE_ALIGN((1UL << (cq->size_log2)) * sizeof(struct t3_cqe));
++
+       err = cxio_hal_clear_cq_ctx(rdev_p, cq->cqid);
+       kfree(cq->sw_queue);
+-      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                        (1UL << (cq->size_log2))
+-                        * sizeof(struct t3_cqe), cq->queue,
++      unreserve_pages(cq->queue, size);
++      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev), size, cq->queue,
+                         pci_unmap_addr(cq, mapping));
+       cxio_hal_put_cqid(rdev_p->rscp, cq->cqid);
+       return err;
+@@ -347,9 +369,10 @@ int cxio_destroy_cq(struct cxio_rdev *rd
+ int cxio_destroy_qp(struct cxio_rdev *rdev_p, struct t3_wq *wq,
+                   struct cxio_ucontext *uctx)
+ {
+-      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                        (1UL << (wq->size_log2))
+-                        * sizeof(union t3_wr), wq->queue,
++      int size = PAGE_ALIGN((1UL << (wq->size_log2)) * sizeof(union t3_wr));
++
++      unreserve_pages(wq->queue, size);
++      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev), size, wq->queue,
+                         pci_unmap_addr(wq, mapping));
+       kfree(wq->sq);
+       cxio_hal_rqtpool_free(rdev_p, wq->rq_addr, (1UL << wq->rq_size_log2));
diff --git a/kernel_patches/backport/2.6.9_U2/iwch_provider_to_2.6.9_U4.patch 
b/kernel_patches/backport/2.6.9_U2/iwch_provider_to_2.6.9_U4.patch
new file mode 100644
index 0000000..1fbc717
--- /dev/null
+++ b/kernel_patches/backport/2.6.9_U2/iwch_provider_to_2.6.9_U4.patch
@@ -0,0 +1,16 @@
+--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c      2007-01-17 
09:22:39.000000000 -0600
++++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c      2007-01-22 
17:46:16.000000000 -0600
+@@ -337,13 +337,6 @@ static int iwch_mmap(struct ib_ucontext 
+           (pgaddr < (rdev_p->rnic_info.udbell_physbase +
+                      rdev_p->rnic_info.udbell_len))) {
+ 
+-              /*
+-               * Map T3 DB register.
+-               */
+-              if (vma->vm_flags & VM_READ) {
+-                      return -EPERM;
+-              }
+-
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+               vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND;
+               vma->vm_flags &= ~VM_MAYREAD;
diff --git a/kernel_patches/backport/2.6.9_U3/cxio_hal_to_2.6.14.patch 
b/kernel_patches/backport/2.6.9_U3/cxio_hal_to_2.6.14.patch
new file mode 100644
index 0000000..34556bb
--- /dev/null
+++ b/kernel_patches/backport/2.6.9_U3/cxio_hal_to_2.6.14.patch
@@ -0,0 +1,127 @@
+Reserve pages to support userspace mapping in older kernels.
+
+From: Steve Wise <[EMAIL PROTECTED]>
+
+This is needed for kernels prior to 2.6.15 to correctly map kernel
+memory into userspace.
+
+Signed-off-by: Steve Wise <[EMAIL PROTECTED]>
+---
+
+ drivers/infiniband/hw/cxgb3/core/cxio_hal.c |   53 +++++++++++++++++++--------
+ 1 files changed, 38 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/infiniband/hw/cxgb3/core/cxio_hal.c 
b/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
+index 229edd5..067fe46 100644
+--- a/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
++++ b/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
+@@ -170,10 +170,30 @@ int cxio_hal_clear_qp_ctx(struct cxio_rd
+       return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+ }
+ 
++static void reserve_pages(void *p, int size)
++{
++      while (size > 0) {
++              SetPageReserved(virt_to_page(p));
++              p += PAGE_SIZE;
++              size -= PAGE_SIZE;
++      }
++      BUG_ON(size < 0);
++}
++
++static void unreserve_pages(void *p, int size)
++{
++      while (size > 0) {
++              ClearPageReserved(virt_to_page(p));
++              p += PAGE_SIZE;
++              size -= PAGE_SIZE;
++      }
++      BUG_ON(size < 0);
++}
++
+ int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+ {
+       struct rdma_cq_setup setup;
+-      int size = (1UL << (cq->size_log2)) * sizeof(struct t3_cqe);
++      int size = PAGE_ALIGN((1UL << (cq->size_log2)) * sizeof(struct t3_cqe));
+ 
+       cq->cqid = cxio_hal_get_cqid(rdev_p->rscp);
+       if (!cq->cqid)
+@@ -181,16 +201,15 @@ int cxio_create_cq(struct cxio_rdev *rde
+       cq->sw_queue = kzalloc(size, GFP_KERNEL);
+       if (!cq->sw_queue)
+               return -ENOMEM;
+-      cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                                           (1UL << (cq->size_log2)) *
+-                                           sizeof(struct t3_cqe),
+-                                           &(cq->dma_addr), GFP_KERNEL);
++      cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
++                                     &(cq->dma_addr), GFP_KERNEL);
+       if (!cq->queue) {
+               kfree(cq->sw_queue);
+               return -ENOMEM;
+       }
+       pci_unmap_addr_set(cq, mapping, cq->dma_addr);
+       memset(cq->queue, 0, size);
++      reserve_pages(cq->queue, size);
+       setup.id = cq->cqid;
+       setup.base_addr = (u64) (cq->dma_addr);
+       setup.size = 1UL << cq->size_log2;
+@@ -288,6 +307,7 @@ int cxio_create_qp(struct cxio_rdev *rde
+ {
+       int depth = 1UL << wq->size_log2;
+       int rqsize = 1UL << wq->rq_size_log2;
++      int size = PAGE_ALIGN(depth * sizeof(union t3_wr));
+ 
+       wq->qpid = get_qpid(rdev_p, uctx);
+       if (!wq->qpid)
+@@ -305,14 +325,15 @@ int cxio_create_qp(struct cxio_rdev *rde
+       if (!wq->sq)
+               goto err3;
+       
+-      wq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                                           depth * sizeof(union t3_wr),
+-                                           &(wq->dma_addr), GFP_KERNEL);
++      wq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
++                                     &(wq->dma_addr), GFP_KERNEL);
+       if (!wq->queue)
+               goto err4;
+ 
+-      memset(wq->queue, 0, depth * sizeof(union t3_wr));
+       pci_unmap_addr_set(wq, mapping, wq->dma_addr);
++      memset(wq->queue, 0, size);
++      reserve_pages(wq->queue, size);
++
+       wq->doorbell = (void __iomem *)rdev_p->rnic_info.kdb_addr;
+       if (!kernel_domain)
+               wq->udb = (u64)rdev_p->rnic_info.udbell_physbase +
+@@ -334,11 +355,12 @@ err1:
+ int cxio_destroy_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+ {
+       int err;
++      int size = PAGE_ALIGN((1UL << (cq->size_log2)) * sizeof(struct t3_cqe));
++
+       err = cxio_hal_clear_cq_ctx(rdev_p, cq->cqid);
+       kfree(cq->sw_queue);
+-      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                        (1UL << (cq->size_log2))
+-                        * sizeof(struct t3_cqe), cq->queue,
++      unreserve_pages(cq->queue, size);
++      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev), size, cq->queue,
+                         pci_unmap_addr(cq, mapping));
+       cxio_hal_put_cqid(rdev_p->rscp, cq->cqid);
+       return err;
+@@ -347,9 +369,10 @@ int cxio_destroy_cq(struct cxio_rdev *rd
+ int cxio_destroy_qp(struct cxio_rdev *rdev_p, struct t3_wq *wq,
+                   struct cxio_ucontext *uctx)
+ {
+-      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                        (1UL << (wq->size_log2))
+-                        * sizeof(union t3_wr), wq->queue,
++      int size = PAGE_ALIGN((1UL << (wq->size_log2)) * sizeof(union t3_wr));
++
++      unreserve_pages(wq->queue, size);
++      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev), size, wq->queue,
+                         pci_unmap_addr(wq, mapping));
+       kfree(wq->sq);
+       cxio_hal_rqtpool_free(rdev_p, wq->rq_addr, (1UL << wq->rq_size_log2));
diff --git a/kernel_patches/backport/2.6.9_U3/iwch_provider_to_2.6.9_U4.patch 
b/kernel_patches/backport/2.6.9_U3/iwch_provider_to_2.6.9_U4.patch
new file mode 100644
index 0000000..1fbc717
--- /dev/null
+++ b/kernel_patches/backport/2.6.9_U3/iwch_provider_to_2.6.9_U4.patch
@@ -0,0 +1,16 @@
+--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c      2007-01-17 
09:22:39.000000000 -0600
++++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c      2007-01-22 
17:46:16.000000000 -0600
+@@ -337,13 +337,6 @@ static int iwch_mmap(struct ib_ucontext 
+           (pgaddr < (rdev_p->rnic_info.udbell_physbase +
+                      rdev_p->rnic_info.udbell_len))) {
+ 
+-              /*
+-               * Map T3 DB register.
+-               */
+-              if (vma->vm_flags & VM_READ) {
+-                      return -EPERM;
+-              }
+-
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+               vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND;
+               vma->vm_flags &= ~VM_MAYREAD;
diff --git a/kernel_patches/backport/2.6.9_U4/cxio_hal_to_2.6.14.patch 
b/kernel_patches/backport/2.6.9_U4/cxio_hal_to_2.6.14.patch
new file mode 100644
index 0000000..34556bb
--- /dev/null
+++ b/kernel_patches/backport/2.6.9_U4/cxio_hal_to_2.6.14.patch
@@ -0,0 +1,127 @@
+Reserve pages to support userspace mapping in older kernels.
+
+From: Steve Wise <[EMAIL PROTECTED]>
+
+This is needed for kernels prior to 2.6.15 to correctly map kernel
+memory into userspace.
+
+Signed-off-by: Steve Wise <[EMAIL PROTECTED]>
+---
+
+ drivers/infiniband/hw/cxgb3/core/cxio_hal.c |   53 +++++++++++++++++++--------
+ 1 files changed, 38 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/infiniband/hw/cxgb3/core/cxio_hal.c 
b/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
+index 229edd5..067fe46 100644
+--- a/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
++++ b/drivers/infiniband/hw/cxgb3/core/cxio_hal.c
+@@ -170,10 +170,30 @@ int cxio_hal_clear_qp_ctx(struct cxio_rd
+       return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+ }
+ 
++static void reserve_pages(void *p, int size)
++{
++      while (size > 0) {
++              SetPageReserved(virt_to_page(p));
++              p += PAGE_SIZE;
++              size -= PAGE_SIZE;
++      }
++      BUG_ON(size < 0);
++}
++
++static void unreserve_pages(void *p, int size)
++{
++      while (size > 0) {
++              ClearPageReserved(virt_to_page(p));
++              p += PAGE_SIZE;
++              size -= PAGE_SIZE;
++      }
++      BUG_ON(size < 0);
++}
++
+ int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+ {
+       struct rdma_cq_setup setup;
+-      int size = (1UL << (cq->size_log2)) * sizeof(struct t3_cqe);
++      int size = PAGE_ALIGN((1UL << (cq->size_log2)) * sizeof(struct t3_cqe));
+ 
+       cq->cqid = cxio_hal_get_cqid(rdev_p->rscp);
+       if (!cq->cqid)
+@@ -181,16 +201,15 @@ int cxio_create_cq(struct cxio_rdev *rde
+       cq->sw_queue = kzalloc(size, GFP_KERNEL);
+       if (!cq->sw_queue)
+               return -ENOMEM;
+-      cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                                           (1UL << (cq->size_log2)) *
+-                                           sizeof(struct t3_cqe),
+-                                           &(cq->dma_addr), GFP_KERNEL);
++      cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
++                                     &(cq->dma_addr), GFP_KERNEL);
+       if (!cq->queue) {
+               kfree(cq->sw_queue);
+               return -ENOMEM;
+       }
+       pci_unmap_addr_set(cq, mapping, cq->dma_addr);
+       memset(cq->queue, 0, size);
++      reserve_pages(cq->queue, size);
+       setup.id = cq->cqid;
+       setup.base_addr = (u64) (cq->dma_addr);
+       setup.size = 1UL << cq->size_log2;
+@@ -288,6 +307,7 @@ int cxio_create_qp(struct cxio_rdev *rde
+ {
+       int depth = 1UL << wq->size_log2;
+       int rqsize = 1UL << wq->rq_size_log2;
++      int size = PAGE_ALIGN(depth * sizeof(union t3_wr));
+ 
+       wq->qpid = get_qpid(rdev_p, uctx);
+       if (!wq->qpid)
+@@ -305,14 +325,15 @@ int cxio_create_qp(struct cxio_rdev *rde
+       if (!wq->sq)
+               goto err3;
+       
+-      wq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                                           depth * sizeof(union t3_wr),
+-                                           &(wq->dma_addr), GFP_KERNEL);
++      wq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
++                                     &(wq->dma_addr), GFP_KERNEL);
+       if (!wq->queue)
+               goto err4;
+ 
+-      memset(wq->queue, 0, depth * sizeof(union t3_wr));
+       pci_unmap_addr_set(wq, mapping, wq->dma_addr);
++      memset(wq->queue, 0, size);
++      reserve_pages(wq->queue, size);
++
+       wq->doorbell = (void __iomem *)rdev_p->rnic_info.kdb_addr;
+       if (!kernel_domain)
+               wq->udb = (u64)rdev_p->rnic_info.udbell_physbase +
+@@ -334,11 +355,12 @@ err1:
+ int cxio_destroy_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+ {
+       int err;
++      int size = PAGE_ALIGN((1UL << (cq->size_log2)) * sizeof(struct t3_cqe));
++
+       err = cxio_hal_clear_cq_ctx(rdev_p, cq->cqid);
+       kfree(cq->sw_queue);
+-      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                        (1UL << (cq->size_log2))
+-                        * sizeof(struct t3_cqe), cq->queue,
++      unreserve_pages(cq->queue, size);
++      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev), size, cq->queue,
+                         pci_unmap_addr(cq, mapping));
+       cxio_hal_put_cqid(rdev_p->rscp, cq->cqid);
+       return err;
+@@ -347,9 +369,10 @@ int cxio_destroy_cq(struct cxio_rdev *rd
+ int cxio_destroy_qp(struct cxio_rdev *rdev_p, struct t3_wq *wq,
+                   struct cxio_ucontext *uctx)
+ {
+-      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
+-                        (1UL << (wq->size_log2))
+-                        * sizeof(union t3_wr), wq->queue,
++      int size = PAGE_ALIGN((1UL << (wq->size_log2)) * sizeof(union t3_wr));
++
++      unreserve_pages(wq->queue, size);
++      dma_free_coherent(&(rdev_p->rnic_info.pdev->dev), size, wq->queue,
+                         pci_unmap_addr(wq, mapping));
+       kfree(wq->sq);
+       cxio_hal_rqtpool_free(rdev_p, wq->rq_addr, (1UL << wq->rq_size_log2));

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to