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

Commit 1e60508c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Doug Ledford:
 "Three late 4.4-rc fixes.

  The first two were very small in terms of number of lines, the third
  is more lines of change than I like this late in the cycle, but there
  are positive test results from Avagotech and from my own test setup
  with the target hardware, and given the problem was a 100% failure
  case, I sent it through.

   - A previous patch updated the mlx4 driver to use vmalloc when there
     was not enough memory to get a contiguous region large enough for
     our needs, so we need kvfree() whenever we free that item.  We
     missed one place, so fix that now.

   - A previous patch added code to match incoming packets against a
     specific device, but failed to compensate for devices that have
     both InfiniBand and Ethernet ports.  Fix that.

   - Under certain vlan conditions, the ocrdma driver would fail to
     bring up any vlan interfaces and would print out a circular locking
     failure.  Fix that"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma:
  RDMA/be2net: Remove open and close entry points
  RDMA/ocrdma: Depend on async link events from CNA
  RDMA/ocrdma: Dispatch only port event when port state changes
  RDMA/ocrdma: Fix vlan-id assignment in qp parameters
  IB/mlx4: Replace kfree with kvfree in mlx4_ib_destroy_srq
  IB/cma: cma_match_net_dev needs to take into account port_num
parents 85133421 f41647ef
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -1265,15 +1265,17 @@ static bool cma_protocol_roce(const struct rdma_cm_id *id)
	return cma_protocol_roce_dev_port(device, port_num);
}

static bool cma_match_net_dev(const struct rdma_id_private *id_priv,
			      const struct net_device *net_dev)
static bool cma_match_net_dev(const struct rdma_cm_id *id,
			      const struct net_device *net_dev,
			      u8 port_num)
{
	const struct rdma_addr *addr = &id_priv->id.route.addr;
	const struct rdma_addr *addr = &id->route.addr;

	if (!net_dev)
		/* This request is an AF_IB request or a RoCE request */
		return addr->src_addr.ss_family == AF_IB ||
		       cma_protocol_roce(&id_priv->id);
		return (!id->port_num || id->port_num == port_num) &&
		       (addr->src_addr.ss_family == AF_IB ||
			cma_protocol_roce_dev_port(id->device, port_num));

	return !addr->dev_addr.bound_dev_if ||
	       (net_eq(dev_net(net_dev), addr->dev_addr.net) &&
@@ -1295,13 +1297,13 @@ static struct rdma_id_private *cma_find_listener(
	hlist_for_each_entry(id_priv, &bind_list->owners, node) {
		if (cma_match_private_data(id_priv, ib_event->private_data)) {
			if (id_priv->id.device == cm_id->device &&
			    cma_match_net_dev(id_priv, net_dev))
			    cma_match_net_dev(&id_priv->id, net_dev, req->port))
				return id_priv;
			list_for_each_entry(id_priv_dev,
					    &id_priv->listen_list,
					    listen_list) {
				if (id_priv_dev->id.device == cm_id->device &&
				    cma_match_net_dev(id_priv_dev, net_dev))
				    cma_match_net_dev(&id_priv_dev->id, net_dev, req->port))
					return id_priv_dev;
			}
		}
+1 −1
Original line number Diff line number Diff line
@@ -286,7 +286,7 @@ int mlx4_ib_destroy_srq(struct ib_srq *srq)
		mlx4_ib_db_unmap_user(to_mucontext(srq->uobject->context), &msrq->db);
		ib_umem_release(msrq->umem);
	} else {
		kfree(msrq->wrid);
		kvfree(msrq->wrid);
		mlx4_buf_free(dev->dev, msrq->msrq.max << msrq->msrq.wqe_shift,
			      &msrq->buf);
		mlx4_db_free(dev->dev, &msrq->db);
+10 −0
Original line number Diff line number Diff line
@@ -232,6 +232,10 @@ struct phy_info {
	u16 interface_type;
};

enum ocrdma_flags {
	OCRDMA_FLAGS_LINK_STATUS_INIT = 0x01
};

struct ocrdma_dev {
	struct ib_device ibdev;
	struct ocrdma_dev_attr attr;
@@ -287,6 +291,7 @@ struct ocrdma_dev {
	atomic_t update_sl;
	u16 pvid;
	u32 asic_id;
	u32 flags;

	ulong last_stats_time;
	struct mutex stats_lock; /* provide synch for debugfs operations */
@@ -591,4 +596,9 @@ static inline u8 ocrdma_is_enabled_and_synced(u32 state)
		(state & OCRDMA_STATE_FLAG_SYNC);
}

static inline u8 ocrdma_get_ae_link_state(u32 ae_state)
{
	return ((ae_state & OCRDMA_AE_LSC_LS_MASK) >> OCRDMA_AE_LSC_LS_SHIFT);
}

#endif
+39 −10
Original line number Diff line number Diff line
@@ -579,6 +579,8 @@ static int ocrdma_mbx_create_mq(struct ocrdma_dev *dev,

	cmd->async_event_bitmap = BIT(OCRDMA_ASYNC_GRP5_EVE_CODE);
	cmd->async_event_bitmap |= BIT(OCRDMA_ASYNC_RDMA_EVE_CODE);
	/* Request link events on this  MQ. */
	cmd->async_event_bitmap |= BIT(OCRDMA_ASYNC_LINK_EVE_CODE);

	cmd->async_cqid_ringsize = cq->id;
	cmd->async_cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) <<
@@ -819,21 +821,43 @@ static void ocrdma_process_grp5_aync(struct ocrdma_dev *dev,
	}
}

static void ocrdma_process_link_state(struct ocrdma_dev *dev,
				      struct ocrdma_ae_mcqe *cqe)
{
	struct ocrdma_ae_lnkst_mcqe *evt;
	u8 lstate;

	evt = (struct ocrdma_ae_lnkst_mcqe *)cqe;
	lstate = ocrdma_get_ae_link_state(evt->speed_state_ptn);

	if (!(lstate & OCRDMA_AE_LSC_LLINK_MASK))
		return;

	if (dev->flags & OCRDMA_FLAGS_LINK_STATUS_INIT)
		ocrdma_update_link_state(dev, (lstate & OCRDMA_LINK_ST_MASK));
}

static void ocrdma_process_acqe(struct ocrdma_dev *dev, void *ae_cqe)
{
	/* async CQE processing */
	struct ocrdma_ae_mcqe *cqe = ae_cqe;
	u32 evt_code = (cqe->valid_ae_event & OCRDMA_AE_MCQE_EVENT_CODE_MASK) >>
			OCRDMA_AE_MCQE_EVENT_CODE_SHIFT;

	if (evt_code == OCRDMA_ASYNC_RDMA_EVE_CODE)
	switch (evt_code) {
	case OCRDMA_ASYNC_LINK_EVE_CODE:
		ocrdma_process_link_state(dev, cqe);
		break;
	case OCRDMA_ASYNC_RDMA_EVE_CODE:
		ocrdma_dispatch_ibevent(dev, cqe);
	else if (evt_code == OCRDMA_ASYNC_GRP5_EVE_CODE)
		break;
	case OCRDMA_ASYNC_GRP5_EVE_CODE:
		ocrdma_process_grp5_aync(dev, cqe);
	else
		break;
	default:
		pr_err("%s(%d) invalid evt code=0x%x\n", __func__,
		       dev->id, evt_code);
	}
}

static void ocrdma_process_mcqe(struct ocrdma_dev *dev, struct ocrdma_mcqe *cqe)
{
@@ -1363,7 +1387,8 @@ static int ocrdma_mbx_query_dev(struct ocrdma_dev *dev)
	return status;
}

int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed)
int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed,
			      u8 *lnk_state)
{
	int status = -ENOMEM;
	struct ocrdma_get_link_speed_rsp *rsp;
@@ -1384,8 +1409,11 @@ int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed)
		goto mbx_err;

	rsp = (struct ocrdma_get_link_speed_rsp *)cmd;
	if (lnk_speed)
		*lnk_speed = (rsp->pflt_pps_ld_pnum & OCRDMA_PHY_PS_MASK)
			      >> OCRDMA_PHY_PS_SHIFT;
	if (lnk_state)
		*lnk_state = (rsp->res_lnk_st & OCRDMA_LINK_ST_MASK);

mbx_err:
	kfree(cmd);
@@ -2515,9 +2543,10 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
	ocrdma_cpu_to_le32(&cmd->params.sgid[0], sizeof(cmd->params.sgid));
	cmd->params.vlan_dmac_b4_to_b5 = mac_addr[4] | (mac_addr[5] << 8);

	if (vlan_id < 0x1000) {
		if (dev->pfc_state) {
	if (vlan_id == 0xFFFF)
		vlan_id = 0;
	if (vlan_id || dev->pfc_state) {
		if (!vlan_id) {
			pr_err("ocrdma%d:Using VLAN with PFC is recommended\n",
			       dev->id);
			pr_err("ocrdma%d:Using VLAN 0 for this connection\n",
+3 −1
Original line number Diff line number Diff line
@@ -106,7 +106,8 @@ void ocrdma_ring_cq_db(struct ocrdma_dev *, u16 cq_id, bool armed,
		       bool solicited, u16 cqe_popped);

/* verbs specific mailbox commands */
int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed);
int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed,
			      u8 *lnk_st);
int ocrdma_query_config(struct ocrdma_dev *,
			struct ocrdma_mbx_query_config *config);

@@ -153,5 +154,6 @@ char *port_speed_string(struct ocrdma_dev *dev);
void ocrdma_init_service_level(struct ocrdma_dev *);
void ocrdma_alloc_pd_pool(struct ocrdma_dev *dev);
void ocrdma_free_pd_range(struct ocrdma_dev *dev);
void ocrdma_update_link_state(struct ocrdma_dev *dev, u8 lstate);

#endif				/* __OCRDMA_HW_H__ */
Loading