]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Add IB fix for http://article.gmane.org/gmane.linux.drivers.openib/21118,
authorChris Wright <chrisw@sous-sol.org>
Mon, 27 Feb 2006 22:03:42 +0000 (14:03 -0800)
committerChris Wright <chrisw@sous-sol.org>
Mon, 27 Feb 2006 22:03:42 +0000 (14:03 -0800)
fwd from Roland.

queue/ib-mthca-max_inline_data-handling-tweaks.patch [new file with mode: 0644]
queue/series

diff --git a/queue/ib-mthca-max_inline_data-handling-tweaks.patch b/queue/ib-mthca-max_inline_data-handling-tweaks.patch
new file mode 100644 (file)
index 0000000..d4026d3
--- /dev/null
@@ -0,0 +1,139 @@
+From stable-bounces@linux.kernel.org  Mon Feb 27 13:48:39 2006
+Date: Mon, 27 Feb 2006 13:44:40 -0800
+From: Roland Dreier <rdreier@cisco.com>
+To: stable@kernel.org
+Cc: 
+Subject: [PATCH] IB/mthca: max_inline_data handling tweaks
+
+From: Jack Morgenstein <jackm@mellanox.co.il>
+
+Fix a case where copying max_inline_data from a successful create_qp
+capabilities output to create_qp input could cause EINVAL error:
+
+mthca_set_qp_size must check max_inline_data directly against
+max_desc_sz; checking qp->sq.max_gs is wrong since max_inline_data
+depends on the qp type and does not involve max_sg.
+
+Signed-off-by: Jack Morgenstein <jackm@mellanox.co.il>
+Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
+Signed-off-by: Roland Dreier <rolandd@cisco.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ drivers/infiniband/hw/mthca/mthca_qp.c |   62 +++++++++++++++++++--------------
+ 1 files changed, 36 insertions(+), 26 deletions(-)
+
+--- linux-2.6.15.4.orig/drivers/infiniband/hw/mthca/mthca_qp.c
++++ linux-2.6.15.4/drivers/infiniband/hw/mthca/mthca_qp.c
+@@ -885,18 +885,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
+       return err;
+ }
+-static void mthca_adjust_qp_caps(struct mthca_dev *dev,
+-                               struct mthca_pd *pd,
+-                               struct mthca_qp *qp)
++static int mthca_max_data_size(struct mthca_dev *dev, struct mthca_qp *qp, int desc_sz)
+ {
+-      int max_data_size;
+-
+       /*
+        * Calculate the maximum size of WQE s/g segments, excluding
+        * the next segment and other non-data segments.
+        */
+-      max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) -
+-              sizeof (struct mthca_next_seg);
++      int max_data_size = desc_sz - sizeof (struct mthca_next_seg);
+       switch (qp->transport) {
+       case MLX:
+@@ -915,11 +910,24 @@ static void mthca_adjust_qp_caps(struct 
+               break;
+       }
++      return max_data_size;
++}
++
++static inline int mthca_max_inline_data(struct mthca_pd *pd, int max_data_size)
++{
+       /* We don't support inline data for kernel QPs (yet). */
+-      if (!pd->ibpd.uobject)
+-              qp->max_inline_data = 0;
+-        else
+-              qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
++      return pd->ibpd.uobject ? max_data_size - MTHCA_INLINE_HEADER_SIZE : 0;
++}
++
++static void mthca_adjust_qp_caps(struct mthca_dev *dev,
++                               struct mthca_pd *pd,
++                               struct mthca_qp *qp)
++{
++      int max_data_size = mthca_max_data_size(dev, qp,
++                                              min(dev->limits.max_desc_sz,
++                                                  1 << qp->sq.wqe_shift));
++
++      qp->max_inline_data = mthca_max_inline_data(pd, max_data_size);
+       qp->sq.max_gs = min_t(int, dev->limits.max_sg,
+                             max_data_size / sizeof (struct mthca_data_seg));
+@@ -1186,13 +1194,23 @@ static int mthca_alloc_qp_common(struct 
+ }
+ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
+-                           struct mthca_qp *qp)
++                           struct mthca_pd *pd, struct mthca_qp *qp)
+ {
++      int max_data_size = mthca_max_data_size(dev, qp, dev->limits.max_desc_sz);
++
+       /* Sanity check QP size before proceeding */
+-      if (cap->max_send_wr  > dev->limits.max_wqes ||
+-          cap->max_recv_wr  > dev->limits.max_wqes ||
+-          cap->max_send_sge > dev->limits.max_sg   ||
+-          cap->max_recv_sge > dev->limits.max_sg)
++      if (cap->max_send_wr     > dev->limits.max_wqes ||
++          cap->max_recv_wr     > dev->limits.max_wqes ||
++          cap->max_send_sge    > dev->limits.max_sg   ||
++          cap->max_recv_sge    > dev->limits.max_sg   ||
++          cap->max_inline_data > mthca_max_inline_data(pd, max_data_size))
++              return -EINVAL;
++
++      /*
++       * For MLX transport we need 2 extra S/G entries:
++       * one for the header and one for the checksum at the end
++       */
++      if (qp->transport == MLX && cap->max_recv_sge + 2 > dev->limits.max_sg)
+               return -EINVAL;
+       if (mthca_is_memfree(dev)) {
+@@ -1211,14 +1229,6 @@ static int mthca_set_qp_size(struct mthc
+                                   MTHCA_INLINE_CHUNK_SIZE) /
+                             sizeof (struct mthca_data_seg));
+-      /*
+-       * For MLX transport we need 2 extra S/G entries:
+-       * one for the header and one for the checksum at the end
+-       */
+-      if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) ||
+-          qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg)
+-              return -EINVAL;
+-
+       return 0;
+ }
+@@ -1233,7 +1243,7 @@ int mthca_alloc_qp(struct mthca_dev *dev
+ {
+       int err;
+-      err = mthca_set_qp_size(dev, cap, qp);
++      err = mthca_set_qp_size(dev, cap, pd, qp);
+       if (err)
+               return err;
+@@ -1276,7 +1286,7 @@ int mthca_alloc_sqp(struct mthca_dev *de
+       u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1;
+       int err;
+-      err = mthca_set_qp_size(dev, cap, &sqp->qp);
++      err = mthca_set_qp_size(dev, cap, pd, &sqp->qp);
+       if (err)
+               return err;
index 06fcea1f3cbafd48cffca1a980f8dedbbed60241..944403a1928684595e7d2db195adee1e987e078f 100644 (file)
@@ -36,3 +36,4 @@ sd-fix-memory-corruption-with-broken-mode-page-headers.patch
 sbp2-fix-another-deadlock-after-disconnection.patch
 xfs-ftruncate-bug-could-expose-stale-data.patch
 normal-user-can-panic-nfs-client-with-direct-i-o.patch
+ib-mthca-max_inline_data-handling-tweaks.patch