Merge branches 'cma', 'cxgb3', 'ehca', 'ipoib', 'mad', 'mlx4' and 'nes' into for-next
This commit is contained in:

@@ -1942,6 +1942,7 @@ fail4:
|
||||
fail3:
|
||||
cxgb3_free_atid(ep->com.tdev, ep->atid);
|
||||
fail2:
|
||||
cm_id->rem_ref(cm_id);
|
||||
put_ep(&ep->com);
|
||||
out:
|
||||
return err;
|
||||
|
@@ -128,6 +128,8 @@ struct ehca_shca {
|
||||
/* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */
|
||||
u32 hca_cap_mr_pgsize;
|
||||
int max_mtu;
|
||||
int max_num_qps;
|
||||
int max_num_cqs;
|
||||
atomic_t num_cqs;
|
||||
atomic_t num_qps;
|
||||
};
|
||||
|
@@ -132,9 +132,9 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
|
||||
if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (!atomic_add_unless(&shca->num_cqs, 1, ehca_max_cq)) {
|
||||
if (!atomic_add_unless(&shca->num_cqs, 1, shca->max_num_cqs)) {
|
||||
ehca_err(device, "Unable to create CQ, max number of %i "
|
||||
"CQs reached.", ehca_max_cq);
|
||||
"CQs reached.", shca->max_num_cqs);
|
||||
ehca_err(device, "To increase the maximum number of CQs "
|
||||
"use the number_of_cqs module parameter.\n");
|
||||
return ERR_PTR(-ENOSPC);
|
||||
|
@@ -44,6 +44,8 @@
|
||||
#include <linux/slab.h>
|
||||
#endif
|
||||
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/memory.h>
|
||||
#include "ehca_classes.h"
|
||||
#include "ehca_iverbs.h"
|
||||
#include "ehca_mrmw.h"
|
||||
@@ -366,22 +368,23 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
|
||||
shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
|
||||
|
||||
/* Set maximum number of CQs and QPs to calculate EQ size */
|
||||
if (ehca_max_qp == -1)
|
||||
ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES);
|
||||
else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) {
|
||||
ehca_gen_err("Requested number of QPs is out of range (1 - %i) "
|
||||
"specified by HW", rblock->max_qp);
|
||||
ret = -EINVAL;
|
||||
goto sense_attributes1;
|
||||
if (shca->max_num_qps == -1)
|
||||
shca->max_num_qps = min_t(int, rblock->max_qp,
|
||||
EHCA_MAX_NUM_QUEUES);
|
||||
else if (shca->max_num_qps < 1 || shca->max_num_qps > rblock->max_qp) {
|
||||
ehca_gen_warn("The requested number of QPs is out of range "
|
||||
"(1 - %i) specified by HW. Value is set to %i",
|
||||
rblock->max_qp, rblock->max_qp);
|
||||
shca->max_num_qps = rblock->max_qp;
|
||||
}
|
||||
|
||||
if (ehca_max_cq == -1)
|
||||
ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES);
|
||||
else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) {
|
||||
ehca_gen_err("Requested number of CQs is out of range (1 - %i) "
|
||||
"specified by HW", rblock->max_cq);
|
||||
ret = -EINVAL;
|
||||
goto sense_attributes1;
|
||||
if (shca->max_num_cqs == -1)
|
||||
shca->max_num_cqs = min_t(int, rblock->max_cq,
|
||||
EHCA_MAX_NUM_QUEUES);
|
||||
else if (shca->max_num_cqs < 1 || shca->max_num_cqs > rblock->max_cq) {
|
||||
ehca_gen_warn("The requested number of CQs is out of range "
|
||||
"(1 - %i) specified by HW. Value is set to %i",
|
||||
rblock->max_cq, rblock->max_cq);
|
||||
}
|
||||
|
||||
/* query max MTU from first port -- it's the same for all ports */
|
||||
@@ -733,9 +736,13 @@ static int __devinit ehca_probe(struct of_device *dev,
|
||||
ehca_gen_err("Cannot allocate shca memory.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&shca->modify_mutex);
|
||||
atomic_set(&shca->num_cqs, 0);
|
||||
atomic_set(&shca->num_qps, 0);
|
||||
shca->max_num_qps = ehca_max_qp;
|
||||
shca->max_num_cqs = ehca_max_cq;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(shca->sport); i++)
|
||||
spin_lock_init(&shca->sport[i].mod_sqp_lock);
|
||||
|
||||
@@ -755,7 +762,7 @@ static int __devinit ehca_probe(struct of_device *dev,
|
||||
goto probe1;
|
||||
}
|
||||
|
||||
eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp;
|
||||
eq_size = 2 * shca->max_num_cqs + 4 * shca->max_num_qps;
|
||||
/* create event queues */
|
||||
ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size);
|
||||
if (ret) {
|
||||
@@ -964,6 +971,41 @@ void ehca_poll_eqs(unsigned long data)
|
||||
spin_unlock(&shca_list_lock);
|
||||
}
|
||||
|
||||
static int ehca_mem_notifier(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
static unsigned long ehca_dmem_warn_time;
|
||||
|
||||
switch (action) {
|
||||
case MEM_CANCEL_OFFLINE:
|
||||
case MEM_CANCEL_ONLINE:
|
||||
case MEM_ONLINE:
|
||||
case MEM_OFFLINE:
|
||||
return NOTIFY_OK;
|
||||
case MEM_GOING_ONLINE:
|
||||
case MEM_GOING_OFFLINE:
|
||||
/* only ok if no hca is attached to the lpar */
|
||||
spin_lock(&shca_list_lock);
|
||||
if (list_empty(&shca_list)) {
|
||||
spin_unlock(&shca_list_lock);
|
||||
return NOTIFY_OK;
|
||||
} else {
|
||||
spin_unlock(&shca_list_lock);
|
||||
if (printk_timed_ratelimit(&ehca_dmem_warn_time,
|
||||
30 * 1000))
|
||||
ehca_gen_err("DMEM operations are not allowed"
|
||||
"as long as an ehca adapter is"
|
||||
"attached to the LPAR");
|
||||
return NOTIFY_BAD;
|
||||
}
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block ehca_mem_nb = {
|
||||
.notifier_call = ehca_mem_notifier,
|
||||
};
|
||||
|
||||
static int __init ehca_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
@@ -991,6 +1033,12 @@ static int __init ehca_module_init(void)
|
||||
goto module_init2;
|
||||
}
|
||||
|
||||
ret = register_memory_notifier(&ehca_mem_nb);
|
||||
if (ret) {
|
||||
ehca_gen_err("Failed registering memory add/remove notifier");
|
||||
goto module_init3;
|
||||
}
|
||||
|
||||
if (ehca_poll_all_eqs != 1) {
|
||||
ehca_gen_err("WARNING!!!");
|
||||
ehca_gen_err("It is possible to lose interrupts.");
|
||||
@@ -1003,6 +1051,9 @@ static int __init ehca_module_init(void)
|
||||
|
||||
return 0;
|
||||
|
||||
module_init3:
|
||||
ibmebus_unregister_driver(&ehca_driver);
|
||||
|
||||
module_init2:
|
||||
ehca_destroy_slab_caches();
|
||||
|
||||
@@ -1018,6 +1069,8 @@ static void __exit ehca_module_exit(void)
|
||||
|
||||
ibmebus_unregister_driver(&ehca_driver);
|
||||
|
||||
unregister_memory_notifier(&ehca_mem_nb);
|
||||
|
||||
ehca_destroy_slab_caches();
|
||||
|
||||
ehca_destroy_comp_pool();
|
||||
|
@@ -465,9 +465,9 @@ static struct ehca_qp *internal_create_qp(
|
||||
u32 swqe_size = 0, rwqe_size = 0, ib_qp_num;
|
||||
unsigned long flags;
|
||||
|
||||
if (!atomic_add_unless(&shca->num_qps, 1, ehca_max_qp)) {
|
||||
if (!atomic_add_unless(&shca->num_qps, 1, shca->max_num_qps)) {
|
||||
ehca_err(pd->device, "Unable to create QP, max number of %i "
|
||||
"QPs reached.", ehca_max_qp);
|
||||
"QPs reached.", shca->max_num_qps);
|
||||
ehca_err(pd->device, "To increase the maximum number of QPs "
|
||||
"use the number_of_qps module parameter.\n");
|
||||
return ERR_PTR(-ENOSPC);
|
||||
@@ -502,6 +502,12 @@ static struct ehca_qp *internal_create_qp(
|
||||
if (init_attr->srq) {
|
||||
my_srq = container_of(init_attr->srq, struct ehca_qp, ib_srq);
|
||||
|
||||
if (qp_type == IB_QPT_UC) {
|
||||
ehca_err(pd->device, "UC with SRQ not supported");
|
||||
atomic_dec(&shca->num_qps);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
has_srq = 1;
|
||||
parms.ext_type = EQPT_SRQBASE;
|
||||
parms.srq_qpn = my_srq->real_qp_num;
|
||||
|
@@ -298,7 +298,7 @@ int mlx4_ib_mad_init(struct mlx4_ib_dev *dev)
|
||||
int p, q;
|
||||
int ret;
|
||||
|
||||
for (p = 0; p < dev->dev->caps.num_ports; ++p)
|
||||
for (p = 0; p < dev->num_ports; ++p)
|
||||
for (q = 0; q <= 1; ++q) {
|
||||
agent = ib_register_mad_agent(&dev->ib_dev, p + 1,
|
||||
q ? IB_QPT_GSI : IB_QPT_SMI,
|
||||
@@ -314,7 +314,7 @@ int mlx4_ib_mad_init(struct mlx4_ib_dev *dev)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
for (p = 0; p < dev->dev->caps.num_ports; ++p)
|
||||
for (p = 0; p < dev->num_ports; ++p)
|
||||
for (q = 0; q <= 1; ++q)
|
||||
if (dev->send_agent[p][q])
|
||||
ib_unregister_mad_agent(dev->send_agent[p][q]);
|
||||
@@ -327,7 +327,7 @@ void mlx4_ib_mad_cleanup(struct mlx4_ib_dev *dev)
|
||||
struct ib_mad_agent *agent;
|
||||
int p, q;
|
||||
|
||||
for (p = 0; p < dev->dev->caps.num_ports; ++p) {
|
||||
for (p = 0; p < dev->num_ports; ++p) {
|
||||
for (q = 0; q <= 1; ++q) {
|
||||
agent = dev->send_agent[p][q];
|
||||
dev->send_agent[p][q] = NULL;
|
||||
|
@@ -574,7 +574,10 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
|
||||
ibdev->ib_dev.owner = THIS_MODULE;
|
||||
ibdev->ib_dev.node_type = RDMA_NODE_IB_CA;
|
||||
ibdev->ib_dev.local_dma_lkey = dev->caps.reserved_lkey;
|
||||
ibdev->ib_dev.phys_port_cnt = dev->caps.num_ports;
|
||||
ibdev->num_ports = 0;
|
||||
mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
|
||||
ibdev->num_ports++;
|
||||
ibdev->ib_dev.phys_port_cnt = ibdev->num_ports;
|
||||
ibdev->ib_dev.num_comp_vectors = 1;
|
||||
ibdev->ib_dev.dma_device = &dev->pdev->dev;
|
||||
|
||||
@@ -691,7 +694,7 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
|
||||
struct mlx4_ib_dev *ibdev = ibdev_ptr;
|
||||
int p;
|
||||
|
||||
for (p = 1; p <= dev->caps.num_ports; ++p)
|
||||
for (p = 1; p <= ibdev->num_ports; ++p)
|
||||
mlx4_CLOSE_PORT(dev, p);
|
||||
|
||||
mlx4_ib_mad_cleanup(ibdev);
|
||||
@@ -706,6 +709,10 @@ static void mlx4_ib_event(struct mlx4_dev *dev, void *ibdev_ptr,
|
||||
enum mlx4_dev_event event, int port)
|
||||
{
|
||||
struct ib_event ibev;
|
||||
struct mlx4_ib_dev *ibdev = to_mdev((struct ib_device *) ibdev_ptr);
|
||||
|
||||
if (port > ibdev->num_ports)
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case MLX4_DEV_EVENT_PORT_UP:
|
||||
|
@@ -162,6 +162,7 @@ struct mlx4_ib_ah {
|
||||
struct mlx4_ib_dev {
|
||||
struct ib_device ib_dev;
|
||||
struct mlx4_dev *dev;
|
||||
int num_ports;
|
||||
void __iomem *uar_map;
|
||||
|
||||
struct mlx4_uar priv_uar;
|
||||
|
@@ -451,6 +451,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
||||
struct ib_qp_init_attr *init_attr,
|
||||
struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp)
|
||||
{
|
||||
int qpn;
|
||||
int err;
|
||||
|
||||
mutex_init(&qp->mutex);
|
||||
@@ -545,9 +546,17 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
||||
}
|
||||
}
|
||||
|
||||
err = mlx4_qp_alloc(dev->dev, sqpn, &qp->mqp);
|
||||
if (sqpn) {
|
||||
qpn = sqpn;
|
||||
} else {
|
||||
err = mlx4_qp_reserve_range(dev->dev, 1, 1, &qpn);
|
||||
if (err)
|
||||
goto err_wrid;
|
||||
}
|
||||
|
||||
err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp);
|
||||
if (err)
|
||||
goto err_wrid;
|
||||
goto err_qpn;
|
||||
|
||||
/*
|
||||
* Hardware wants QPN written in big-endian order (after
|
||||
@@ -560,6 +569,10 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
||||
|
||||
return 0;
|
||||
|
||||
err_qpn:
|
||||
if (!sqpn)
|
||||
mlx4_qp_release_range(dev->dev, qpn, 1);
|
||||
|
||||
err_wrid:
|
||||
if (pd->uobject) {
|
||||
if (!init_attr->srq)
|
||||
@@ -655,6 +668,10 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
|
||||
mlx4_ib_unlock_cqs(send_cq, recv_cq);
|
||||
|
||||
mlx4_qp_free(dev->dev, &qp->mqp);
|
||||
|
||||
if (!is_sqp(dev, qp))
|
||||
mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1);
|
||||
|
||||
mlx4_mtt_cleanup(dev->dev, &qp->mtt);
|
||||
|
||||
if (is_user) {
|
||||
|
Reference in New Issue
Block a user