Skip to content

Commit

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

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
  • Loading branch information
torvalds committed Jan 9, 2018
2 parents d32da58 + a1ffa46 commit 44596f8
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 32 deletions.
2 changes: 1 addition & 1 deletion drivers/infiniband/core/core_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 17 additions & 1 deletion drivers/infiniband/core/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
54 changes: 36 additions & 18 deletions drivers/infiniband/core/nldev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/mlx4/mr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
25 changes: 18 additions & 7 deletions drivers/infiniband/ulp/ipoib/ipoib_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -902,8 +902,8 @@ static int path_rec_start(struct net_device *dev,
return 0;
}

static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
struct net_device *dev)
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);
struct rdma_netdev *rn = netdev_priv(dev);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -1091,8 +1101,9 @@ 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);
return NETDEV_TX_OK;
neigh = neigh_add_path(skb, phdr->hwaddr, dev);
if (likely(!neigh))
return NETDEV_TX_OK;
}
break;
case htons(ETH_P_ARP):
Expand Down
5 changes: 4 additions & 1 deletion drivers/infiniband/ulp/ipoib/ipoib_multicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,10 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
if (!neigh) {
neigh = ipoib_neigh_alloc(daddr, dev);
if (neigh) {
/* Make sure that the neigh will be added only
* once to mcast list.
*/
if (neigh && list_empty(&neigh->list)) {
kref_get(&mcast->ah->ref);
neigh->ah = mcast->ah;
list_add_tail(&neigh->list, &mcast->neigh_list);
Expand Down
5 changes: 2 additions & 3 deletions drivers/infiniband/ulp/srpt/ib_srpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1013,8 +1013,7 @@ static int srpt_init_ch_qp(struct srpt_rdma_ch *ch, struct ib_qp *qp)
return -ENOMEM;

attr->qp_state = IB_QPS_INIT;
attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_READ |
IB_ACCESS_REMOTE_WRITE;
attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE;
attr->port_num = ch->sport->port;
attr->pkey_index = 0;

Expand Down Expand Up @@ -2078,7 +2077,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
goto destroy_ib;
}

guid = (__be16 *)&param->primary_path->sgid.global.interface_id;
guid = (__be16 *)&param->primary_path->dgid.global.interface_id;
snprintf(ch->ini_guid, sizeof(ch->ini_guid), "%04x:%04x:%04x:%04x",
be16_to_cpu(guid[0]), be16_to_cpu(guid[1]),
be16_to_cpu(guid[2]), be16_to_cpu(guid[3]));
Expand Down

0 comments on commit 44596f8

Please sign in to comment.