Skip to content

Commit

Permalink
Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/roland/infiniband

Pull InfiniBand/RDMA changes for the 3.4 merge window from Roland Dreier:
 "Nothing big really stands out; by patch count lots of fixes to the
  mlx4 driver plus some cleanups and fixes to the core and other
  drivers."

* tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (28 commits)
  mlx4_core: Scale size of MTT table with system RAM
  mlx4_core: Allow dynamic MTU configuration for IB ports
  IB/mlx4: Fix info returned when querying IBoE ports
  IB/mlx4: Fix possible missed completion event
  mlx4_core: Report thermal error events
  mlx4_core: Fix one more static exported function
  IB: Change CQE "csum_ok" field to a bit flag
  RDMA/iwcm: Reject connect requests if cmid is not in LISTEN state
  RDMA/cxgb3: Don't pass irq flags to flush_qp()
  mlx4_core: Get rid of redundant ext_port_cap flags
  RDMA/ucma: Fix AB-BA deadlock
  IB/ehca: Fix ilog2() compile failure
  IB: Use central enum for speed instead of hard-coded values
  IB/iser: Post initial receive buffers before sending the final login request
  IB/iser: Free IB connection resources in the proper place
  IB/srp: Consolidate repetitive sysfs code
  IB/srp: Use pr_fmt() and pr_err()/pr_warn()
  IB/core: Fix SDR rates in sysfs
  mlx4: Enforce device max FMR maps in FMR alloc
  IB/mlx4: Set bad_wr for invalid send opcode
  ...
  • Loading branch information
Linus Torvalds committed Mar 21, 2012
2 parents 5f0e685 + f0e88ae commit 0c2fe82
Show file tree
Hide file tree
Showing 39 changed files with 606 additions and 351 deletions.
24 changes: 13 additions & 11 deletions drivers/infiniband/core/iwcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,17 +624,6 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
*/
BUG_ON(iw_event->status);

/*
* We could be destroying the listening id. If so, ignore this
* upcall.
*/
spin_lock_irqsave(&listen_id_priv->lock, flags);
if (listen_id_priv->state != IW_CM_STATE_LISTEN) {
spin_unlock_irqrestore(&listen_id_priv->lock, flags);
goto out;
}
spin_unlock_irqrestore(&listen_id_priv->lock, flags);

cm_id = iw_create_cm_id(listen_id_priv->id.device,
listen_id_priv->id.cm_handler,
listen_id_priv->id.context);
Expand All @@ -649,6 +638,19 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
cm_id_priv->state = IW_CM_STATE_CONN_RECV;

/*
* We could be destroying the listening id. If so, ignore this
* upcall.
*/
spin_lock_irqsave(&listen_id_priv->lock, flags);
if (listen_id_priv->state != IW_CM_STATE_LISTEN) {
spin_unlock_irqrestore(&listen_id_priv->lock, flags);
iw_cm_reject(cm_id, NULL, 0);
iw_destroy_cm_id(cm_id);
goto out;
}
spin_unlock_irqrestore(&listen_id_priv->lock, flags);

ret = alloc_work_entries(cm_id_priv, 3);
if (ret) {
iw_cm_reject(cm_id, NULL, 0);
Expand Down
21 changes: 21 additions & 0 deletions drivers/infiniband/core/mad.c
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,24 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
}
}

static bool generate_unmatched_resp(struct ib_mad_private *recv,
struct ib_mad_private *response)
{
if (recv->mad.mad.mad_hdr.method == IB_MGMT_METHOD_GET ||
recv->mad.mad.mad_hdr.method == IB_MGMT_METHOD_SET) {
memcpy(response, recv, sizeof *response);
response->header.recv_wc.wc = &response->header.wc;
response->header.recv_wc.recv_buf.mad = &response->mad.mad;
response->header.recv_wc.recv_buf.grh = &response->grh;
response->mad.mad.mad_hdr.method = IB_MGMT_METHOD_GET_RESP;
response->mad.mad.mad_hdr.status =
cpu_to_be16(IB_MGMT_MAD_STATUS_UNSUPPORTED_METHOD_ATTRIB);

return true;
} else {
return false;
}
}
static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
struct ib_wc *wc)
{
Expand Down Expand Up @@ -1963,6 +1981,9 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
* or via recv_handler in ib_mad_complete_recv()
*/
recv = NULL;
} else if (generate_unmatched_resp(recv, response)) {
agent_send_response(&response->mad.mad, &recv->grh, wc,
port_priv->device, port_num, qp_info->qp->qp_num);
}

out:
Expand Down
27 changes: 15 additions & 12 deletions drivers/infiniband/core/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,33 +179,36 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
{
struct ib_port_attr attr;
char *speed = "";
int rate;
int rate = -1; /* in deci-Gb/sec */
ssize_t ret;

ret = ib_query_port(p->ibdev, p->port_num, &attr);
if (ret)
return ret;

rate = (25 * attr.active_speed) / 10;

switch (attr.active_speed) {
case 2:
case IB_SPEED_SDR:
rate = 25;
break;
case IB_SPEED_DDR:
speed = " DDR";
rate = 50;
break;
case 4:
case IB_SPEED_QDR:
speed = " QDR";
rate = 100;
break;
case 8:
case IB_SPEED_FDR10:
speed = " FDR10";
rate = 10;
rate = 100;
break;
case 16:
case IB_SPEED_FDR:
speed = " FDR";
rate = 14;
rate = 140;
break;
case 32:
case IB_SPEED_EDR:
speed = " EDR";
rate = 25;
rate = 250;
break;
}

Expand All @@ -214,7 +217,7 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
return -EINVAL;

return sprintf(buf, "%d%s Gb/sec (%dX%s)\n",
rate, (attr.active_speed == 1) ? ".5" : "",
rate / 10, rate % 10 ? ".5" : "",
ib_width_enum_to_int(attr.active_width), speed);
}

Expand Down
37 changes: 18 additions & 19 deletions drivers/infiniband/core/ucma.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,24 +449,6 @@ static void ucma_cleanup_multicast(struct ucma_context *ctx)
mutex_unlock(&mut);
}

static void ucma_cleanup_events(struct ucma_context *ctx)
{
struct ucma_event *uevent, *tmp;

list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) {
if (uevent->ctx != ctx)
continue;

list_del(&uevent->list);

/* clear incoming connections. */
if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST)
rdma_destroy_id(uevent->cm_id);

kfree(uevent);
}
}

static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
{
struct ucma_event *uevent, *tmp;
Expand All @@ -480,9 +462,16 @@ static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
}
}

/*
* We cannot hold file->mut when calling rdma_destroy_id() or we can
* deadlock. We also acquire file->mut in ucma_event_handler(), and
* rdma_destroy_id() will wait until all callbacks have completed.
*/
static int ucma_free_ctx(struct ucma_context *ctx)
{
int events_reported;
struct ucma_event *uevent, *tmp;
LIST_HEAD(list);

/* No new events will be generated after destroying the id. */
rdma_destroy_id(ctx->cm_id);
Expand All @@ -491,10 +480,20 @@ static int ucma_free_ctx(struct ucma_context *ctx)

/* Cleanup events not yet reported to the user. */
mutex_lock(&ctx->file->mut);
ucma_cleanup_events(ctx);
list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) {
if (uevent->ctx == ctx)
list_move_tail(&uevent->list, &list);
}
list_del(&ctx->list);
mutex_unlock(&ctx->file->mut);

list_for_each_entry_safe(uevent, tmp, &list, list) {
list_del(&uevent->list);
if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST)
rdma_destroy_id(uevent->cm_id);
kfree(uevent);
}

events_reported = ctx->events_reported;
kfree(ctx);
return events_reported;
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/amso1100/c2_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static int c2_query_port(struct ib_device *ibdev,
props->pkey_tbl_len = 1;
props->qkey_viol_cntr = 0;
props->active_width = 1;
props->active_speed = 1;
props->active_speed = IB_SPEED_SDR;

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/cxgb3/iwch_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -1227,7 +1227,7 @@ static int iwch_query_port(struct ib_device *ibdev,
props->gid_tbl_len = 1;
props->pkey_tbl_len = 1;
props->active_width = 2;
props->active_speed = 2;
props->active_speed = IB_SPEED_DDR;
props->max_msg_sz = -1;

return 0;
Expand Down
40 changes: 20 additions & 20 deletions drivers/infiniband/hw/cxgb3/iwch_qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg)
* Assumes qhp lock is held.
*/
static void __flush_qp(struct iwch_qp *qhp, struct iwch_cq *rchp,
struct iwch_cq *schp, unsigned long *flag)
struct iwch_cq *schp)
{
int count;
int flushed;
Expand All @@ -812,44 +812,44 @@ static void __flush_qp(struct iwch_qp *qhp, struct iwch_cq *rchp,
PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp);
/* take a ref on the qhp since we must release the lock */
atomic_inc(&qhp->refcnt);
spin_unlock_irqrestore(&qhp->lock, *flag);
spin_unlock(&qhp->lock);

/* locking hierarchy: cq lock first, then qp lock. */
spin_lock_irqsave(&rchp->lock, *flag);
spin_lock(&rchp->lock);
spin_lock(&qhp->lock);
cxio_flush_hw_cq(&rchp->cq);
cxio_count_rcqes(&rchp->cq, &qhp->wq, &count);
flushed = cxio_flush_rq(&qhp->wq, &rchp->cq, count);
spin_unlock(&qhp->lock);
spin_unlock_irqrestore(&rchp->lock, *flag);
spin_unlock(&rchp->lock);
if (flushed) {
spin_lock_irqsave(&rchp->comp_handler_lock, *flag);
spin_lock(&rchp->comp_handler_lock);
(*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context);
spin_unlock_irqrestore(&rchp->comp_handler_lock, *flag);
spin_unlock(&rchp->comp_handler_lock);
}

/* locking hierarchy: cq lock first, then qp lock. */
spin_lock_irqsave(&schp->lock, *flag);
spin_lock(&schp->lock);
spin_lock(&qhp->lock);
cxio_flush_hw_cq(&schp->cq);
cxio_count_scqes(&schp->cq, &qhp->wq, &count);
flushed = cxio_flush_sq(&qhp->wq, &schp->cq, count);
spin_unlock(&qhp->lock);
spin_unlock_irqrestore(&schp->lock, *flag);
spin_unlock(&schp->lock);
if (flushed) {
spin_lock_irqsave(&schp->comp_handler_lock, *flag);
spin_lock(&schp->comp_handler_lock);
(*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context);
spin_unlock_irqrestore(&schp->comp_handler_lock, *flag);
spin_unlock(&schp->comp_handler_lock);
}

/* deref */
if (atomic_dec_and_test(&qhp->refcnt))
wake_up(&qhp->wait);

spin_lock_irqsave(&qhp->lock, *flag);
spin_lock(&qhp->lock);
}

static void flush_qp(struct iwch_qp *qhp, unsigned long *flag)
static void flush_qp(struct iwch_qp *qhp)
{
struct iwch_cq *rchp, *schp;

Expand All @@ -859,19 +859,19 @@ static void flush_qp(struct iwch_qp *qhp, unsigned long *flag)
if (qhp->ibqp.uobject) {
cxio_set_wq_in_error(&qhp->wq);
cxio_set_cq_in_error(&rchp->cq);
spin_lock_irqsave(&rchp->comp_handler_lock, *flag);
spin_lock(&rchp->comp_handler_lock);
(*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context);
spin_unlock_irqrestore(&rchp->comp_handler_lock, *flag);
spin_unlock(&rchp->comp_handler_lock);
if (schp != rchp) {
cxio_set_cq_in_error(&schp->cq);
spin_lock_irqsave(&schp->comp_handler_lock, *flag);
spin_lock(&schp->comp_handler_lock);
(*schp->ibcq.comp_handler)(&schp->ibcq,
schp->ibcq.cq_context);
spin_unlock_irqrestore(&schp->comp_handler_lock, *flag);
spin_unlock(&schp->comp_handler_lock);
}
return;
}
__flush_qp(qhp, rchp, schp, flag);
__flush_qp(qhp, rchp, schp);
}


Expand Down Expand Up @@ -1030,7 +1030,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
break;
case IWCH_QP_STATE_ERROR:
qhp->attr.state = IWCH_QP_STATE_ERROR;
flush_qp(qhp, &flag);
flush_qp(qhp);
break;
default:
ret = -EINVAL;
Expand Down Expand Up @@ -1078,7 +1078,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
}
switch (attrs->next_state) {
case IWCH_QP_STATE_IDLE:
flush_qp(qhp, &flag);
flush_qp(qhp);
qhp->attr.state = IWCH_QP_STATE_IDLE;
qhp->attr.llp_stream_handle = NULL;
put_ep(&qhp->ep->com);
Expand Down Expand Up @@ -1132,7 +1132,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
free=1;
wake_up(&qhp->wait);
BUG_ON(!ep);
flush_qp(qhp, &flag);
flush_qp(qhp);
out:
spin_unlock_irqrestore(&qhp->lock, flag);

Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/cxgb4/cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
* generated when moving QP to RTS state.
* A TERM message will be sent after QP has moved to RTS state
*/
if ((ep->mpa_attr.version == 2) &&
if ((ep->mpa_attr.version == 2) && peer2peer &&
(ep->mpa_attr.p2p_type != p2p_type)) {
ep->mpa_attr.p2p_type = FW_RI_INIT_P2PTYPE_DISABLED;
rtr_mismatch = 1;
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/cxgb4/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ static int c4iw_query_port(struct ib_device *ibdev, u8 port,
props->gid_tbl_len = 1;
props->pkey_tbl_len = 1;
props->active_width = 2;
props->active_speed = 2;
props->active_speed = IB_SPEED_DDR;
props->max_msg_sz = -1;

return 0;
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/ehca/ehca_hca.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ int ehca_query_port(struct ib_device *ibdev,
props->phys_state = 5;
props->state = rblock->state;
props->active_width = IB_WIDTH_12X;
props->active_speed = 0x1;
props->active_speed = IB_SPEED_SDR;
}

query_port1:
Expand Down
3 changes: 2 additions & 1 deletion drivers/infiniband/hw/ehca/ehca_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,8 @@ static struct task_struct *create_comp_task(struct ehca_comp_pool *pool,
spin_lock_init(&cct->task_lock);
INIT_LIST_HEAD(&cct->cq_list);
init_waitqueue_head(&cct->wait_queue);
cct->task = kthread_create(comp_task, cct, "ehca_comp/%d", cpu);
cct->task = kthread_create_on_node(comp_task, cct, cpu_to_node(cpu),
"ehca_comp/%d", cpu);

return cct->task;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/ehca/ehca_mrmw.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static u32 ehca_encode_hwpage_size(u32 pgsize)

static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
{
return 1UL << ilog2(shca->hca_cap_mr_pgsize);
return rounddown_pow_of_two(shca->hca_cap_mr_pgsize);
}

static struct ehca_mr *ehca_mr_new(void)
Expand Down
6 changes: 3 additions & 3 deletions drivers/infiniband/hw/mlx4/cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,8 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f;
wc->wc_flags |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0;
wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f;
wc->csum_ok = mlx4_ib_ipoib_csum_ok(cqe->status, cqe->checksum);
wc->wc_flags |= mlx4_ib_ipoib_csum_ok(cqe->status,
cqe->checksum) ? IB_WC_IP_CSUM_OK : 0;
if (rdma_port_get_link_layer(wc->qp->device,
(*cur_qp)->port) == IB_LINK_LAYER_ETHERNET)
wc->sl = be16_to_cpu(cqe->sl_vid) >> 13;
Expand All @@ -747,8 +748,7 @@ int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
break;
}

if (npolled)
mlx4_cq_set_ci(&cq->mcq);
mlx4_cq_set_ci(&cq->mcq);

spin_unlock_irqrestore(&cq->lock, flags);

Expand Down
Loading

0 comments on commit 0c2fe82

Please sign in to comment.