aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@mellanox.co.il>2006-04-11 11:16:27 -0400
committerRoland Dreier <rolandd@cisco.com>2006-04-12 14:42:30 -0400
commit59fef3b1e96217c6e736372ff8cc95cbcca1b6aa (patch)
tree5373713d77df970b52e9dd968a69252d469433a9 /drivers/infiniband/hw
parentce684df05a531904ea055d01aeee75321fa0db1e (diff)
IB/mthca: Fix max_srq_sge returned by ib_query_device for Tavor devices
The driver allocates SRQ WQEs size with a power of 2 size both for Tavor and for memfree. For Tavor, however, the hardware only requires the WQE size to be a multiple of 16, not a power of 2, and the max number of scatter-gather allowed is reported accordingly by the firmware (and this is the value currently returned by ib_query_device() and ibv_query_device()). If the max number of scatter/gather entries reported by the FW is used when creating an SRQ, the creation will fail for Tavor, since the required WQE size will be increased to the next power of 2, which turns out to be larger than the device permitted max WQE size (which is not a power of 2). This patch reduces the reported SRQ max wqe size so that it can be used successfully in creating an SRQ on Tavor HCAs. Signed-off-by: Jack Morgenstein <jackm@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c27
4 files changed, 30 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 49d0eae5518a..4c1dcb4c1822 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -151,6 +151,7 @@ struct mthca_limits {
151 int reserved_qps; 151 int reserved_qps;
152 int num_srqs; 152 int num_srqs;
153 int max_srq_wqes; 153 int max_srq_wqes;
154 int max_srq_sge;
154 int reserved_srqs; 155 int reserved_srqs;
155 int num_eecs; 156 int num_eecs;
156 int reserved_eecs; 157 int reserved_eecs;
@@ -507,6 +508,7 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
507int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, 508int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
508 enum ib_srq_attr_mask attr_mask); 509 enum ib_srq_attr_mask attr_mask);
509int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr); 510int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
511int mthca_max_srq_sge(struct mthca_dev *dev);
510void mthca_srq_event(struct mthca_dev *dev, u32 srqn, 512void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
511 enum ib_event_type event_type); 513 enum ib_event_type event_type);
512void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr); 514void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 7e9c97b09404..9b9ff7bff357 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -191,6 +191,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
191 mdev->limits.reserved_srqs = dev_lim->reserved_srqs; 191 mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
192 mdev->limits.reserved_eecs = dev_lim->reserved_eecs; 192 mdev->limits.reserved_eecs = dev_lim->reserved_eecs;
193 mdev->limits.max_desc_sz = dev_lim->max_desc_sz; 193 mdev->limits.max_desc_sz = dev_lim->max_desc_sz;
194 mdev->limits.max_srq_sge = mthca_max_srq_sge(mdev);
194 /* 195 /*
195 * Subtract 1 from the limit because we need to allocate a 196 * Subtract 1 from the limit because we need to allocate a
196 * spare CQE so the HCA HW can tell the difference between an 197 * spare CQE so the HCA HW can tell the difference between an
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 2c250bc11c33..565a24b1756f 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -106,7 +106,7 @@ static int mthca_query_device(struct ib_device *ibdev,
106 props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp; 106 props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
107 props->max_srq = mdev->limits.num_srqs - mdev->limits.reserved_srqs; 107 props->max_srq = mdev->limits.num_srqs - mdev->limits.reserved_srqs;
108 props->max_srq_wr = mdev->limits.max_srq_wqes; 108 props->max_srq_wr = mdev->limits.max_srq_wqes;
109 props->max_srq_sge = mdev->limits.max_sg; 109 props->max_srq_sge = mdev->limits.max_srq_sge;
110 props->local_ca_ack_delay = mdev->limits.local_ca_ack_delay; 110 props->local_ca_ack_delay = mdev->limits.local_ca_ack_delay;
111 props->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ? 111 props->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ?
112 IB_ATOMIC_HCA : IB_ATOMIC_NONE; 112 IB_ATOMIC_HCA : IB_ATOMIC_NONE;
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 2dd3aea05341..adcaf85355ae 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -192,7 +192,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
192 192
193 /* Sanity check SRQ size before proceeding */ 193 /* Sanity check SRQ size before proceeding */
194 if (attr->max_wr > dev->limits.max_srq_wqes || 194 if (attr->max_wr > dev->limits.max_srq_wqes ||
195 attr->max_sge > dev->limits.max_sg) 195 attr->max_sge > dev->limits.max_srq_sge)
196 return -EINVAL; 196 return -EINVAL;
197 197
198 srq->max = attr->max_wr; 198 srq->max = attr->max_wr;
@@ -660,6 +660,31 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
660 return err; 660 return err;
661} 661}
662 662
663int mthca_max_srq_sge(struct mthca_dev *dev)
664{
665 if (mthca_is_memfree(dev))
666 return dev->limits.max_sg;
667
668 /*
669 * SRQ allocations are based on powers of 2 for Tavor,
670 * (although they only need to be multiples of 16 bytes).
671 *
672 * Therefore, we need to base the max number of sg entries on
673 * the largest power of 2 descriptor size that is <= to the
674 * actual max WQE descriptor size, rather than return the
675 * max_sg value given by the firmware (which is based on WQE
676 * sizes as multiples of 16, not powers of 2).
677 *
678 * If SRQ implementation is changed for Tavor to be based on
679 * multiples of 16, the calculation below can be deleted and
680 * the FW max_sg value returned.
681 */
682 return min_t(int, dev->limits.max_sg,
683 ((1 << (fls(dev->limits.max_desc_sz) - 1)) -
684 sizeof (struct mthca_next_seg)) /
685 sizeof (struct mthca_data_seg));
686}
687
663int __devinit mthca_init_srq_table(struct mthca_dev *dev) 688int __devinit mthca_init_srq_table(struct mthca_dev *dev)
664{ 689{
665 int err; 690 int err;