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/dledford/rdma

Pull rdma fixes from Doug Ledford:
 "First set of -rc fixes for 4.13 cycle:

   - misc iSER fixes

   - namespace fixups

   - fix the fact that IPoIB didn't use the proper API for noio mem allocs

   - rxe driver fixes

   - hns_roce fixes

   - misc core fixes

   - misc IPoIB fixes"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (27 commits)
  IB/core: Allow QP state transition from reset to error
  IB/hns: Fix for checkpatch.pl comment style warnings
  IB/hns: Fix the bug with modifying the MAC address without removing the driver
  IB/hns: Fix the bug with rdma operation
  IB/hns: Fix the bug with wild pointer when destroy rc qp
  IB/hns: Fix the bug of polling cq failed for loopback Qps
  IB/rxe: Set dma_mask and coherent_dma_mask
  IB/rxe: Fix kernel panic from skb destructor
  IB/ipoib: Let lower driver handle get_stats64 call
  IB/core: Add ordered workqueue for RoCE GID management
  IB/mlx5: Clean mr_cache debugfs in case of failure
  IB/core: Remove NOIO QP create flag
  {net, IB}/mlx4: Remove gfp flags argument
  IB/{rdmavt, qib, hfi1}: Remove gfp flags argument
  IB/IPoIB: Convert IPoIB to memalloc_noio_* calls
  IB/IPoIB: Forward MTU change to driver below
  IB: Convert msleep below 20ms to usleep_range
  IB/uverbs: Make use of ib_modify_qp variant to avoid resolving DMAC
  IB/core: Introduce modify QP operation with udata
  IB/core: Don't resolve IP address to the loopback device
  ...
  • Loading branch information
Linus Torvalds committed Jul 18, 2017
2 parents 15b0a8d + ebc9ca4 commit bef85bd
Show file tree
Hide file tree
Showing 43 changed files with 366 additions and 290 deletions.
8 changes: 8 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -10868,6 +10868,14 @@ L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/qedf/

QLOGIC QL4xxx RDMA DRIVER
M: Ram Amrani <Ram.Amrani@cavium.com>
M: Ariel Elior <Ariel.Elior@cavium.com>
L: linux-rdma@vger.kernel.org
S: Supported
F: drivers/infiniband/hw/qedr/
F: include/uapi/rdma/qedr-abi.h

QNX4 FILESYSTEM
M: Anders Larsen <al@alarsen.net>
W: http://www.alarsen.net/linux/qnx4fs/
Expand Down
46 changes: 34 additions & 12 deletions drivers/infiniband/core/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
return ret;

ret = rdma_copy_addr(dev_addr, dev, NULL);
dev_addr->bound_dev_if = dev->ifindex;
if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(dev);
dev_put(dev);
Expand All @@ -280,6 +281,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
&((const struct sockaddr_in6 *)addr)->sin6_addr,
dev, 1)) {
ret = rdma_copy_addr(dev_addr, dev, NULL);
dev_addr->bound_dev_if = dev->ifindex;
if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(dev);
break;
Expand Down Expand Up @@ -405,10 +407,10 @@ static int addr4_resolve(struct sockaddr_in *src_in,
fl4.saddr = src_ip;
fl4.flowi4_oif = addr->bound_dev_if;
rt = ip_route_output_key(addr->net, &fl4);
if (IS_ERR(rt)) {
ret = PTR_ERR(rt);
goto out;
}
ret = PTR_ERR_OR_ZERO(rt);
if (ret)
return ret;

src_in->sin_family = AF_INET;
src_in->sin_addr.s_addr = fl4.saddr;

Expand All @@ -423,8 +425,6 @@ static int addr4_resolve(struct sockaddr_in *src_in,

*prt = rt;
return 0;
out:
return ret;
}

#if IS_ENABLED(CONFIG_IPV6)
Expand Down Expand Up @@ -509,6 +509,11 @@ static int addr_resolve(struct sockaddr *src_in,
struct dst_entry *dst;
int ret;

if (!addr->net) {
pr_warn_ratelimited("%s: missing namespace\n", __func__);
return -EINVAL;
}

if (src_in->sa_family == AF_INET) {
struct rtable *rt = NULL;
const struct sockaddr_in *dst_in4 =
Expand All @@ -522,8 +527,12 @@ static int addr_resolve(struct sockaddr *src_in,
if (resolve_neigh)
ret = addr_resolve_neigh(&rt->dst, dst_in, addr, seq);

ndev = rt->dst.dev;
dev_hold(ndev);
if (addr->bound_dev_if) {
ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
} else {
ndev = rt->dst.dev;
dev_hold(ndev);
}

ip_rt_put(rt);
} else {
Expand All @@ -539,14 +548,27 @@ static int addr_resolve(struct sockaddr *src_in,
if (resolve_neigh)
ret = addr_resolve_neigh(dst, dst_in, addr, seq);

ndev = dst->dev;
dev_hold(ndev);
if (addr->bound_dev_if) {
ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
} else {
ndev = dst->dev;
dev_hold(ndev);
}

dst_release(dst);
}

addr->bound_dev_if = ndev->ifindex;
addr->net = dev_net(ndev);
if (ndev->flags & IFF_LOOPBACK) {
ret = rdma_translate_ip(dst_in, addr, NULL);
/*
* Put the loopback device and get the translated
* device instead.
*/
dev_put(ndev);
ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
} else {
addr->bound_dev_if = ndev->ifindex;
}
dev_put(ndev);

return ret;
Expand Down
32 changes: 3 additions & 29 deletions drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,22 +623,11 @@ static inline int cma_validate_port(struct ib_device *device, u8 port,
if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port))
return ret;

if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) {
if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port))
ndev = dev_get_by_index(&init_net, bound_if_index);
if (ndev && ndev->flags & IFF_LOOPBACK) {
pr_info("detected loopback device\n");
dev_put(ndev);

if (!device->get_netdev)
return -EOPNOTSUPP;

ndev = device->get_netdev(device, port);
if (!ndev)
return -ENODEV;
}
} else {
else
gid_type = IB_GID_TYPE_IB;
}


ret = ib_find_cached_gid_by_port(device, gid, gid_type, port,
ndev, NULL);
Expand Down Expand Up @@ -2569,21 +2558,6 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
goto err2;
}

if (ndev->flags & IFF_LOOPBACK) {
dev_put(ndev);
if (!id_priv->id.device->get_netdev) {
ret = -EOPNOTSUPP;
goto err2;
}

ndev = id_priv->id.device->get_netdev(id_priv->id.device,
id_priv->id.port_num);
if (!ndev) {
ret = -ENODEV;
goto err2;
}
}

supported_gids = roce_gid_type_mask_support(id_priv->id.device,
id_priv->id.port_num);
gid_type = cma_route_gid_type(addr->dev_addr.network,
Expand Down
11 changes: 9 additions & 2 deletions drivers/infiniband/core/roce_gid_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include <rdma/ib_cache.h>
#include <rdma/ib_addr.h>

static struct workqueue_struct *gid_cache_wq;

enum gid_op_type {
GID_DEL = 0,
GID_ADD
Expand Down Expand Up @@ -560,7 +562,7 @@ static int netdevice_queue_work(struct netdev_event_work_cmd *cmds,
}
INIT_WORK(&ndev_work->work, netdevice_event_work_handler);

queue_work(ib_wq, &ndev_work->work);
queue_work(gid_cache_wq, &ndev_work->work);

return NOTIFY_DONE;
}
Expand Down Expand Up @@ -693,7 +695,7 @@ static int addr_event(struct notifier_block *this, unsigned long event,
dev_hold(ndev);
work->gid_attr.ndev = ndev;

queue_work(ib_wq, &work->work);
queue_work(gid_cache_wq, &work->work);

return NOTIFY_DONE;
}
Expand Down Expand Up @@ -740,6 +742,10 @@ static struct notifier_block nb_inet6addr = {

int __init roce_gid_mgmt_init(void)
{
gid_cache_wq = alloc_ordered_workqueue("gid-cache-wq", 0);
if (!gid_cache_wq)
return -ENOMEM;

register_inetaddr_notifier(&nb_inetaddr);
if (IS_ENABLED(CONFIG_IPV6))
register_inet6addr_notifier(&nb_inet6addr);
Expand All @@ -764,4 +770,5 @@ void __exit roce_gid_mgmt_cleanup(void)
* ib-core is removed, all physical devices have been removed,
* so no issue with remaining hardware contexts.
*/
destroy_workqueue(gid_cache_wq);
}
23 changes: 4 additions & 19 deletions drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2005,28 +2005,13 @@ static int modify_qp(struct ib_uverbs_file *file,
rdma_ah_set_port_num(&attr->alt_ah_attr,
cmd->base.alt_dest.port_num);

if (qp->real_qp == qp) {
if (cmd->base.attr_mask & IB_QP_AV) {
ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
if (ret)
goto release_qp;
}
ret = ib_security_modify_qp(qp,
attr,
modify_qp_mask(qp->qp_type,
cmd->base.attr_mask),
udata);
} else {
ret = ib_security_modify_qp(qp,
attr,
modify_qp_mask(qp->qp_type,
cmd->base.attr_mask),
NULL);
}
ret = ib_modify_qp_with_udata(qp, attr,
modify_qp_mask(qp->qp_type,
cmd->base.attr_mask),
udata);

release_qp:
uobj_put_obj_read(qp);

out:
kfree(attr);

Expand Down
51 changes: 38 additions & 13 deletions drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,19 @@ int ib_get_gids_from_rdma_hdr(const union rdma_network_hdr *hdr,
}
EXPORT_SYMBOL(ib_get_gids_from_rdma_hdr);

/*
* This function creates ah from the incoming packet.
* Incoming packet has dgid of the receiver node on which this code is
* getting executed and, sgid contains the GID of the sender.
*
* When resolving mac address of destination, the arrived dgid is used
* as sgid and, sgid is used as dgid because sgid contains destinations
* GID whom to respond to.
*
* This is why when calling rdma_addr_find_l2_eth_by_grh() function, the
* position of arguments dgid and sgid do not match the order of the
* parameters.
*/
int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
const struct ib_wc *wc, const struct ib_grh *grh,
struct rdma_ah_attr *ah_attr)
Expand Down Expand Up @@ -507,11 +520,6 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
}

resolved_dev = dev_get_by_index(&init_net, if_index);
if (resolved_dev->flags & IFF_LOOPBACK) {
dev_put(resolved_dev);
resolved_dev = idev;
dev_hold(resolved_dev);
}
rcu_read_lock();
if (resolved_dev != idev && !rdma_is_upper_dev_rcu(idev,
resolved_dev))
Expand Down Expand Up @@ -887,6 +895,7 @@ static const struct {
} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
[IB_QPS_RESET] = {
[IB_QPS_RESET] = { .valid = 1 },
[IB_QPS_ERR] = { .valid = 1 },
[IB_QPS_INIT] = {
.valid = 1,
.req_param = {
Expand Down Expand Up @@ -1268,20 +1277,36 @@ int ib_resolve_eth_dmac(struct ib_device *device,
}
EXPORT_SYMBOL(ib_resolve_eth_dmac);

int ib_modify_qp(struct ib_qp *qp,
struct ib_qp_attr *qp_attr,
int qp_attr_mask)
/**
* ib_modify_qp_with_udata - Modifies the attributes for the specified QP.
* @qp: The QP to modify.
* @attr: On input, specifies the QP attributes to modify. On output,
* the current values of selected QP attributes are returned.
* @attr_mask: A bit-mask used to specify which attributes of the QP
* are being modified.
* @udata: pointer to user's input output buffer information
* are being modified.
* It returns 0 on success and returns appropriate error code on error.
*/
int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr,
int attr_mask, struct ib_udata *udata)
{
int ret;

if (qp_attr_mask & IB_QP_AV) {
int ret;

ret = ib_resolve_eth_dmac(qp->device, &qp_attr->ah_attr);
if (attr_mask & IB_QP_AV) {
ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
if (ret)
return ret;
}
return ib_security_modify_qp(qp, attr, attr_mask, udata);
}
EXPORT_SYMBOL(ib_modify_qp_with_udata);

return ib_security_modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
int ib_modify_qp(struct ib_qp *qp,
struct ib_qp_attr *qp_attr,
int qp_attr_mask)
{
return ib_modify_qp_with_udata(qp, qp_attr, qp_attr_mask, NULL);
}
EXPORT_SYMBOL(ib_modify_qp);

Expand Down
7 changes: 6 additions & 1 deletion drivers/infiniband/hw/hfi1/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -12847,7 +12847,12 @@ static void remap_intr(struct hfi1_devdata *dd, int isrc, int msix_intr)
/* clear from the handled mask of the general interrupt */
m = isrc / 64;
n = isrc % 64;
dd->gi_mask[m] &= ~((u64)1 << n);
if (likely(m < CCE_NUM_INT_CSRS)) {
dd->gi_mask[m] &= ~((u64)1 << n);
} else {
dd_dev_err(dd, "remap interrupt err\n");
return;
}

/* direct the chip source to the given MSI-X interrupt */
m = isrc / 8;
Expand Down
7 changes: 3 additions & 4 deletions drivers/infiniband/hw/hfi1/qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,18 +647,17 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter)
qp->pid);
}

void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp,
gfp_t gfp)
void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp)
{
struct hfi1_qp_priv *priv;

priv = kzalloc_node(sizeof(*priv), gfp, rdi->dparms.node);
priv = kzalloc_node(sizeof(*priv), GFP_KERNEL, rdi->dparms.node);
if (!priv)
return ERR_PTR(-ENOMEM);

priv->owner = qp;

priv->s_ahg = kzalloc_node(sizeof(*priv->s_ahg), gfp,
priv->s_ahg = kzalloc_node(sizeof(*priv->s_ahg), GFP_KERNEL,
rdi->dparms.node);
if (!priv->s_ahg) {
kfree(priv);
Expand Down
3 changes: 1 addition & 2 deletions drivers/infiniband/hw/hfi1/qp.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ void hfi1_migrate_qp(struct rvt_qp *qp);
/*
* Functions provided by hfi1 driver for rdmavt to use
*/
void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp,
gfp_t gfp);
void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp);
void qp_priv_free(struct rvt_dev_info *rdi, struct rvt_qp *qp);
unsigned free_all_qps(struct rvt_dev_info *rdi);
void notify_qp_reset(struct rvt_qp *qp);
Expand Down
Loading

0 comments on commit bef85bd

Please sign in to comment.