Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c2fe82a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
  ...
parents 5f0e685f f0e88aeb
Loading
Loading
Loading
Loading
+13 −11
Original line number Original line Diff line number Diff line
@@ -624,17 +624,6 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
	 */
	 */
	BUG_ON(iw_event->status);
	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,
	cm_id = iw_create_cm_id(listen_id_priv->id.device,
				listen_id_priv->id.cm_handler,
				listen_id_priv->id.cm_handler,
				listen_id_priv->id.context);
				listen_id_priv->id.context);
@@ -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 = container_of(cm_id, struct iwcm_id_private, id);
	cm_id_priv->state = IW_CM_STATE_CONN_RECV;
	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);
	ret = alloc_work_entries(cm_id_priv, 3);
	if (ret) {
	if (ret) {
		iw_cm_reject(cm_id, NULL, 0);
		iw_cm_reject(cm_id, NULL, 0);
+21 −0
Original line number Original line Diff line number Diff line
@@ -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,
static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
				     struct ib_wc *wc)
				     struct ib_wc *wc)
{
{
@@ -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()
		 * or via recv_handler in ib_mad_complete_recv()
		 */
		 */
		recv = NULL;
		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:
out:
+15 −12
Original line number Original line Diff line number Diff line
@@ -179,33 +179,36 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
{
{
	struct ib_port_attr attr;
	struct ib_port_attr attr;
	char *speed = "";
	char *speed = "";
	int rate;
	int rate = -1;		/* in deci-Gb/sec */
	ssize_t ret;
	ssize_t ret;


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


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

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


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


	return sprintf(buf, "%d%s Gb/sec (%dX%s)\n",
	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);
		       ib_width_enum_to_int(attr.active_width), speed);
}
}


+18 −19
Original line number Original line Diff line number Diff line
@@ -449,24 +449,6 @@ static void ucma_cleanup_multicast(struct ucma_context *ctx)
	mutex_unlock(&mut);
	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)
static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
{
{
	struct ucma_event *uevent, *tmp;
	struct ucma_event *uevent, *tmp;
@@ -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)
static int ucma_free_ctx(struct ucma_context *ctx)
{
{
	int events_reported;
	int events_reported;
	struct ucma_event *uevent, *tmp;
	LIST_HEAD(list);


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


	/* Cleanup events not yet reported to the user. */
	/* Cleanup events not yet reported to the user. */
	mutex_lock(&ctx->file->mut);
	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);
	list_del(&ctx->list);
	mutex_unlock(&ctx->file->mut);
	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;
	events_reported = ctx->events_reported;
	kfree(ctx);
	kfree(ctx);
	return events_reported;
	return events_reported;
+1 −1
Original line number Original line Diff line number Diff line
@@ -94,7 +94,7 @@ static int c2_query_port(struct ib_device *ibdev,
	props->pkey_tbl_len = 1;
	props->pkey_tbl_len = 1;
	props->qkey_viol_cntr = 0;
	props->qkey_viol_cntr = 0;
	props->active_width = 1;
	props->active_width = 1;
	props->active_speed = 1;
	props->active_speed = IB_SPEED_SDR;


	return 0;
	return 0;
}
}
Loading