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

Commit 44596f86 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Doug Ledford:

 - One line fix to mlx4 error flow (same as mlx5 fix in last pull
   request, just in the mlx4 driver)

 - Fix a race condition in the IPoIB driver. This patch is larger than
   just a one line fix, but resolves a race condition in a fairly
   straight forward manner

 - Fix a locking issue in the RDMA netlink code. This patch is also
   larger than I would like for a late -rc. It has, however, had a week
   to bake in the rdma tree prior to this pull request

 - One line fix to fix granting remote machine access to memory that
   they don't need and shouldn't have

 - One line fix to correct the fact that our sgid/dgid pair is swapped
   from what you would expect when receiving an incoming connection
   request

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  IB/srpt: Fix ACL lookup during login
  IB/srpt: Disable RDMA access by the initiator
  RDMA/netlink: Fix locking around __ib_get_device_by_index
  IB/ipoib: Fix race condition in neigh creation
  IB/mlx4: Fix mlx4_ib_alloc_mr error flow
parents d32da584 a1ffa467
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -314,7 +314,7 @@ static inline int ib_mad_enforce_security(struct ib_mad_agent_private *map,
}
#endif

struct ib_device *__ib_device_get_by_index(u32 ifindex);
struct ib_device *ib_device_get_by_index(u32 ifindex);
/* RDMA device netlink */
void nldev_init(void);
void nldev_exit(void);
+17 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ static int ib_device_check_mandatory(struct ib_device *device)
	return 0;
}

struct ib_device *__ib_device_get_by_index(u32 index)
static struct ib_device *__ib_device_get_by_index(u32 index)
{
	struct ib_device *device;

@@ -145,6 +145,22 @@ struct ib_device *__ib_device_get_by_index(u32 index)
	return NULL;
}

/*
 * Caller is responsible to return refrerence count by calling put_device()
 */
struct ib_device *ib_device_get_by_index(u32 index)
{
	struct ib_device *device;

	down_read(&lists_rwsem);
	device = __ib_device_get_by_index(index);
	if (device)
		get_device(&device->dev);

	up_read(&lists_rwsem);
	return device;
}

static struct ib_device *__ib_device_get_by_name(const char *name)
{
	struct ib_device *device;
+36 −18
Original line number Diff line number Diff line
@@ -142,27 +142,34 @@ static int nldev_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,

	index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);

	device = __ib_device_get_by_index(index);
	device = ib_device_get_by_index(index);
	if (!device)
		return -EINVAL;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;
	if (!msg) {
		err = -ENOMEM;
		goto err;
	}

	nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
			RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET),
			0, 0);

	err = fill_dev_info(msg, device);
	if (err) {
		nlmsg_free(msg);
		return err;
	}
	if (err)
		goto err_free;

	nlmsg_end(msg, nlh);

	put_device(&device->dev);
	return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);

err_free:
	nlmsg_free(msg);
err:
	put_device(&device->dev);
	return err;
}

static int _nldev_get_dumpit(struct ib_device *device,
@@ -220,31 +227,40 @@ static int nldev_port_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
		return -EINVAL;

	index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
	device = __ib_device_get_by_index(index);
	device = ib_device_get_by_index(index);
	if (!device)
		return -EINVAL;

	port = nla_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
	if (!rdma_is_port_valid(device, port))
		return -EINVAL;
	if (!rdma_is_port_valid(device, port)) {
		err = -EINVAL;
		goto err;
	}

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;
	if (!msg) {
		err = -ENOMEM;
		goto err;
	}

	nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
			RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET),
			0, 0);

	err = fill_port_info(msg, device, port);
	if (err) {
		nlmsg_free(msg);
		return err;
	}
	if (err)
		goto err_free;

	nlmsg_end(msg, nlh);
	put_device(&device->dev);

	return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);

err_free:
	nlmsg_free(msg);
err:
	put_device(&device->dev);
	return err;
}

static int nldev_port_get_dumpit(struct sk_buff *skb,
@@ -265,7 +281,7 @@ static int nldev_port_get_dumpit(struct sk_buff *skb,
		return -EINVAL;

	ifindex = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
	device = __ib_device_get_by_index(ifindex);
	device = ib_device_get_by_index(ifindex);
	if (!device)
		return -EINVAL;

@@ -299,7 +315,9 @@ static int nldev_port_get_dumpit(struct sk_buff *skb,
		nlmsg_end(skb, nlh);
	}

out:	cb->args[0] = idx;
out:
	put_device(&device->dev);
	cb->args[0] = idx;
	return skb->len;
}

+1 −1
Original line number Diff line number Diff line
@@ -642,7 +642,6 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd,
		goto err_free_mr;

	mr->max_pages = max_num_sg;

	err = mlx4_mr_enable(dev->dev, &mr->mmr);
	if (err)
		goto err_free_pl;
@@ -653,6 +652,7 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd,
	return &mr->ibmr;

err_free_pl:
	mr->ibmr.device = pd->device;
	mlx4_free_priv_pages(mr);
err_free_mr:
	(void) mlx4_mr_free(dev->dev, &mr->mmr);
+18 −7
Original line number Diff line number Diff line
@@ -902,7 +902,7 @@ static int path_rec_start(struct net_device *dev,
	return 0;
}

static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
static struct ipoib_neigh *neigh_add_path(struct sk_buff *skb, u8 *daddr,
					  struct net_device *dev)
{
	struct ipoib_dev_priv *priv = ipoib_priv(dev);
@@ -917,7 +917,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
		spin_unlock_irqrestore(&priv->lock, flags);
		++dev->stats.tx_dropped;
		dev_kfree_skb_any(skb);
		return;
		return NULL;
	}

	/* To avoid race condition, make sure that the
	 * neigh will be added only once.
	 */
	if (unlikely(!list_empty(&neigh->list))) {
		spin_unlock_irqrestore(&priv->lock, flags);
		return neigh;
	}

	path = __path_find(dev, daddr + 4);
@@ -956,7 +964,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
			path->ah->last_send = rn->send(dev, skb, path->ah->ah,
						       IPOIB_QPN(daddr));
			ipoib_neigh_put(neigh);
			return;
			return NULL;
		}
	} else {
		neigh->ah  = NULL;
@@ -973,7 +981,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,

	spin_unlock_irqrestore(&priv->lock, flags);
	ipoib_neigh_put(neigh);
	return;
	return NULL;

err_path:
	ipoib_neigh_free(neigh);
@@ -983,6 +991,8 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,

	spin_unlock_irqrestore(&priv->lock, flags);
	ipoib_neigh_put(neigh);

	return NULL;
}

static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
@@ -1091,7 +1101,8 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
	case htons(ETH_P_TIPC):
		neigh = ipoib_neigh_get(dev, phdr->hwaddr);
		if (unlikely(!neigh)) {
			neigh_add_path(skb, phdr->hwaddr, dev);
			neigh = neigh_add_path(skb, phdr->hwaddr, dev);
			if (likely(!neigh))
				return NETDEV_TX_OK;
		}
		break;
Loading