[IB] mthca: Better limit checking and reporting
Check the sizes of CQs, QPs and SRQs when creating objects, and fail instead of creating too-big queues. Also return real limits instead of just plausible-sounding values from mthca_query_device(). Signed-off-by: Jack Morgenstein <jackm@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
4ab6fb7e5b
commit
efaae8f71f
|
@ -933,9 +933,9 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
|
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
|
||||||
dev_lim->max_srq_sz = 1 << field;
|
dev_lim->max_srq_sz = (1 << field) - 1;
|
||||||
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET);
|
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET);
|
||||||
dev_lim->max_qp_sz = 1 << field;
|
dev_lim->max_qp_sz = (1 << field) - 1;
|
||||||
MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET);
|
MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET);
|
||||||
dev_lim->reserved_qps = 1 << (field & 0xf);
|
dev_lim->reserved_qps = 1 << (field & 0xf);
|
||||||
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET);
|
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET);
|
||||||
|
@ -1045,6 +1045,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
|
||||||
dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars);
|
dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars);
|
||||||
mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n",
|
mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n",
|
||||||
dev_lim->max_pds, dev_lim->reserved_mgms);
|
dev_lim->max_pds, dev_lim->reserved_mgms);
|
||||||
|
mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n",
|
||||||
|
dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz);
|
||||||
|
|
||||||
mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
|
mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,8 @@ enum {
|
||||||
/* Arbel FW gives us these, but we need them for Tavor */
|
/* Arbel FW gives us these, but we need them for Tavor */
|
||||||
MTHCA_MPT_ENTRY_SIZE = 0x40,
|
MTHCA_MPT_ENTRY_SIZE = 0x40,
|
||||||
MTHCA_MTT_SEG_SIZE = 0x40,
|
MTHCA_MTT_SEG_SIZE = 0x40,
|
||||||
|
|
||||||
|
MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -128,12 +130,16 @@ struct mthca_limits {
|
||||||
int num_uars;
|
int num_uars;
|
||||||
int max_sg;
|
int max_sg;
|
||||||
int num_qps;
|
int num_qps;
|
||||||
|
int max_wqes;
|
||||||
|
int max_qp_init_rdma;
|
||||||
int reserved_qps;
|
int reserved_qps;
|
||||||
int num_srqs;
|
int num_srqs;
|
||||||
|
int max_srq_wqes;
|
||||||
int reserved_srqs;
|
int reserved_srqs;
|
||||||
int num_eecs;
|
int num_eecs;
|
||||||
int reserved_eecs;
|
int reserved_eecs;
|
||||||
int num_cqs;
|
int num_cqs;
|
||||||
|
int max_cqes;
|
||||||
int reserved_cqs;
|
int reserved_cqs;
|
||||||
int num_eqs;
|
int num_eqs;
|
||||||
int reserved_eqs;
|
int reserved_eqs;
|
||||||
|
|
|
@ -162,9 +162,18 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
|
||||||
mdev->limits.pkey_table_len = dev_lim->max_pkeys;
|
mdev->limits.pkey_table_len = dev_lim->max_pkeys;
|
||||||
mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay;
|
mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay;
|
||||||
mdev->limits.max_sg = dev_lim->max_sg;
|
mdev->limits.max_sg = dev_lim->max_sg;
|
||||||
|
mdev->limits.max_wqes = dev_lim->max_qp_sz;
|
||||||
|
mdev->limits.max_qp_init_rdma = dev_lim->max_requester_per_qp;
|
||||||
mdev->limits.reserved_qps = dev_lim->reserved_qps;
|
mdev->limits.reserved_qps = dev_lim->reserved_qps;
|
||||||
|
mdev->limits.max_srq_wqes = dev_lim->max_srq_sz;
|
||||||
mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
|
mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
|
||||||
mdev->limits.reserved_eecs = dev_lim->reserved_eecs;
|
mdev->limits.reserved_eecs = dev_lim->reserved_eecs;
|
||||||
|
/*
|
||||||
|
* Subtract 1 from the limit because we need to allocate a
|
||||||
|
* spare CQE so the HCA HW can tell the difference between an
|
||||||
|
* empty CQ and a full CQ.
|
||||||
|
*/
|
||||||
|
mdev->limits.max_cqes = dev_lim->max_cq_sz - 1;
|
||||||
mdev->limits.reserved_cqs = dev_lim->reserved_cqs;
|
mdev->limits.reserved_cqs = dev_lim->reserved_cqs;
|
||||||
mdev->limits.reserved_eqs = dev_lim->reserved_eqs;
|
mdev->limits.reserved_eqs = dev_lim->reserved_eqs;
|
||||||
mdev->limits.reserved_mtts = dev_lim->reserved_mtts;
|
mdev->limits.reserved_mtts = dev_lim->reserved_mtts;
|
||||||
|
|
|
@ -37,10 +37,6 @@
|
||||||
#include "mthca_dev.h"
|
#include "mthca_dev.h"
|
||||||
#include "mthca_cmd.h"
|
#include "mthca_cmd.h"
|
||||||
|
|
||||||
enum {
|
|
||||||
MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mthca_mgm {
|
struct mthca_mgm {
|
||||||
__be32 next_gid_index;
|
__be32 next_gid_index;
|
||||||
u32 reserved[3];
|
u32 reserved[3];
|
||||||
|
|
|
@ -90,17 +90,26 @@ static int mthca_query_device(struct ib_device *ibdev,
|
||||||
|
|
||||||
props->max_mr_size = ~0ull;
|
props->max_mr_size = ~0ull;
|
||||||
props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps;
|
props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps;
|
||||||
props->max_qp_wr = 0xffff;
|
props->max_qp_wr = mdev->limits.max_wqes;
|
||||||
props->max_sge = mdev->limits.max_sg;
|
props->max_sge = mdev->limits.max_sg;
|
||||||
props->max_cq = mdev->limits.num_cqs - mdev->limits.reserved_cqs;
|
props->max_cq = mdev->limits.num_cqs - mdev->limits.reserved_cqs;
|
||||||
props->max_cqe = 0xffff;
|
props->max_cqe = mdev->limits.max_cqes;
|
||||||
props->max_mr = mdev->limits.num_mpts - mdev->limits.reserved_mrws;
|
props->max_mr = mdev->limits.num_mpts - mdev->limits.reserved_mrws;
|
||||||
props->max_pd = mdev->limits.num_pds - mdev->limits.reserved_pds;
|
props->max_pd = mdev->limits.num_pds - mdev->limits.reserved_pds;
|
||||||
props->max_qp_rd_atom = 1 << mdev->qp_table.rdb_shift;
|
props->max_qp_rd_atom = 1 << mdev->qp_table.rdb_shift;
|
||||||
props->max_qp_init_rd_atom = 1 << mdev->qp_table.rdb_shift;
|
props->max_qp_init_rd_atom = mdev->limits.max_qp_init_rdma;
|
||||||
|
props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
|
||||||
|
props->max_srq = mdev->limits.num_srqs - mdev->limits.reserved_srqs;
|
||||||
|
props->max_srq_wr = mdev->limits.max_srq_wqes;
|
||||||
|
props->max_srq_sge = mdev->limits.max_sg;
|
||||||
props->local_ca_ack_delay = mdev->limits.local_ca_ack_delay;
|
props->local_ca_ack_delay = mdev->limits.local_ca_ack_delay;
|
||||||
props->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ?
|
props->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ?
|
||||||
IB_ATOMIC_HCA : IB_ATOMIC_NONE;
|
IB_ATOMIC_HCA : IB_ATOMIC_NONE;
|
||||||
|
props->max_pkeys = mdev->limits.pkey_table_len;
|
||||||
|
props->max_mcast_grp = mdev->limits.num_mgms + mdev->limits.num_amgms;
|
||||||
|
props->max_mcast_qp_attach = MTHCA_QP_PER_MGM;
|
||||||
|
props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
|
||||||
|
props->max_mcast_grp;
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
out:
|
out:
|
||||||
|
@ -640,6 +649,9 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
|
||||||
int nent;
|
int nent;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (entries < 1 || entries > to_mdev(ibdev)->limits.max_cqes)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
|
if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
|
||||||
return ERR_PTR(-EFAULT);
|
return ERR_PTR(-EFAULT);
|
||||||
|
|
|
@ -1112,8 +1112,10 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
|
||||||
struct mthca_qp *qp)
|
struct mthca_qp *qp)
|
||||||
{
|
{
|
||||||
/* Sanity check QP size before proceeding */
|
/* Sanity check QP size before proceeding */
|
||||||
if (cap->max_send_wr > 65536 || cap->max_recv_wr > 65536 ||
|
if (cap->max_send_wr > dev->limits.max_wqes ||
|
||||||
cap->max_send_sge > 64 || cap->max_recv_sge > 64)
|
cap->max_recv_wr > dev->limits.max_wqes ||
|
||||||
|
cap->max_send_sge > dev->limits.max_sg ||
|
||||||
|
cap->max_recv_sge > dev->limits.max_sg)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (mthca_is_memfree(dev)) {
|
if (mthca_is_memfree(dev)) {
|
||||||
|
|
|
@ -186,7 +186,8 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Sanity check SRQ size before proceeding */
|
/* Sanity check SRQ size before proceeding */
|
||||||
if (attr->max_wr > 16 << 20 || attr->max_sge > 64)
|
if (attr->max_wr > dev->limits.max_srq_wqes ||
|
||||||
|
attr->max_sge > dev->limits.max_sg)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
srq->max = attr->max_wr;
|
srq->max = attr->max_wr;
|
||||||
|
|
Loading…
Reference in New Issue