Skip to content

Commit

Permalink
[IB] mthca: Better limit checking and reporting
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jack Morgenstein authored and Roland Dreier committed Oct 17, 2005
1 parent 4ab6fb7 commit efaae8f
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 12 deletions.
6 changes: 4 additions & 2 deletions drivers/infiniband/hw/mthca/mthca_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,9 +933,9 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
goto out;

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);
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);
dev_lim->reserved_qps = 1 << (field & 0xf);
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET);
Expand Down Expand Up @@ -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);
mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n",
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);

Expand Down
6 changes: 6 additions & 0 deletions drivers/infiniband/hw/mthca/mthca_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ enum {
/* Arbel FW gives us these, but we need them for Tavor */
MTHCA_MPT_ENTRY_SIZE = 0x40,
MTHCA_MTT_SEG_SIZE = 0x40,

MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
};

enum {
Expand Down Expand Up @@ -128,12 +130,16 @@ struct mthca_limits {
int num_uars;
int max_sg;
int num_qps;
int max_wqes;
int max_qp_init_rdma;
int reserved_qps;
int num_srqs;
int max_srq_wqes;
int reserved_srqs;
int num_eecs;
int reserved_eecs;
int num_cqs;
int max_cqes;
int reserved_cqs;
int num_eqs;
int reserved_eqs;
Expand Down
9 changes: 9 additions & 0 deletions drivers/infiniband/hw/mthca/mthca_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.local_ca_ack_delay = dev_lim->local_ca_ack_delay;
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.max_srq_wqes = dev_lim->max_srq_sz;
mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
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_eqs = dev_lim->reserved_eqs;
mdev->limits.reserved_mtts = dev_lim->reserved_mtts;
Expand Down
4 changes: 0 additions & 4 deletions drivers/infiniband/hw/mthca/mthca_mcg.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@
#include "mthca_dev.h"
#include "mthca_cmd.h"

enum {
MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
};

struct mthca_mgm {
__be32 next_gid_index;
u32 reserved[3];
Expand Down
18 changes: 15 additions & 3 deletions drivers/infiniband/hw/mthca/mthca_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,26 @@ static int mthca_query_device(struct ib_device *ibdev,

props->max_mr_size = ~0ull;
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_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_pd = mdev->limits.num_pds - mdev->limits.reserved_pds;
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->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ?
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;
out:
Expand Down Expand Up @@ -640,6 +649,9 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
int nent;
int err;

if (entries < 1 || entries > to_mdev(ibdev)->limits.max_cqes)
return ERR_PTR(-EINVAL);

if (context) {
if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
return ERR_PTR(-EFAULT);
Expand Down
6 changes: 4 additions & 2 deletions drivers/infiniband/hw/mthca/mthca_qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1112,8 +1112,10 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
struct mthca_qp *qp)
{
/* Sanity check QP size before proceeding */
if (cap->max_send_wr > 65536 || cap->max_recv_wr > 65536 ||
cap->max_send_sge > 64 || cap->max_recv_sge > 64)
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)
return -EINVAL;

if (mthca_is_memfree(dev)) {
Expand Down
3 changes: 2 additions & 1 deletion drivers/infiniband/hw/mthca/mthca_srq.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
int err;

/* 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;

srq->max = attr->max_wr;
Expand Down

0 comments on commit efaae8f

Please sign in to comment.