Skip to content

Commit

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

Pull infiniband updates from Roland Dreier:
 "Main batch of InfiniBand/RDMA changes for 3.14:
   - Flow steering for InfiniBand UD traffic
   - IP-based addressing for IBoE aka RoCE
   - Pass SRP submaintainership from Dave to Bart
   - SRP transport fixes from Bart
   - Add the new Cisco usNIC low-level device driver
   - Various other fixes"

* tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (75 commits)
  IB/mlx5: Verify reserved fields are cleared
  IB/mlx5: Remove old field for create mkey mailbox
  IB/mlx5: Abort driver cleanup if teardown hca fails
  IB/mlx5: Allow creation of QPs with zero-length work queues
  mlx5_core: Fix PowerPC support
  mlx5_core: Improve debugfs readability
  IB/mlx5: Add support for resize CQ
  IB/mlx5: Implement modify CQ
  IB/mlx5: Make sure doorbell record is visible before doorbell
  mlx5_core: Use mlx5 core style warning
  IB/mlx5: Clear out struct before create QP command
  mlx5_core: Fix out arg size in access_register command
  RDMA/nes: Slight optimization of Ethernet address compare
  IB/qib: Fix QP check when looping back to/from QP1
  RDMA/cxgb4: Fix gcc warning on 32-bit arch
  IB/usnic: Remove unused includes of <linux/version.h>
  RDMA/amso1100: Add check if cache memory was allocated before freeing it
  IPoIB: Report operstate consistently when brought up without a link
  IB/core: Fix unused variable warning
  RDMA/cma: Handle global/non-linklocal IPv6 addresses in cma_check_linklocal()
  ...
  • Loading branch information
torvalds committed Jan 25, 2014
2 parents 1b59bab + fb1b503 commit 8e585a6
Show file tree
Hide file tree
Showing 100 changed files with 7,663 additions and 567 deletions.
7 changes: 7 additions & 0 deletions Documentation/scsi/scsi_transport_srp/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
all: rport_state_diagram.svg rport_state_diagram.png

rport_state_diagram.svg: rport_state_diagram.dot
dot -Tsvg -o $@ $<

rport_state_diagram.png: rport_state_diagram.dot
dot -Tpng -o $@ $<
26 changes: 26 additions & 0 deletions Documentation/scsi/scsi_transport_srp/rport_state_diagram.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
digraph srp_initiator {
node [shape = doublecircle]; running lost;
node [shape = circle];

{
rank = min;
running_rta [ label = "running;\nreconnect\ntimer\nactive" ];
};
running [ label = "running;\nreconnect\ntimer\nstopped" ];
blocked;
failfast [ label = "fail I/O\nfast" ];
lost;

running -> running_rta [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nsrp_start_tl_fail_timers()" ];
running_rta -> running [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nreconnecting succeeded" ];
running -> blocked [ label = "fast_io_fail_tmo >= 0 or\ndev_loss_tmo >= 0;\nsrp_start_tl_fail_timers()" ];
running -> failfast [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nreconnecting failed\n" ];
blocked -> failfast [ label = "fast_io_fail_tmo\nexpired or\nreconnecting\nfailed" ];
blocked -> lost [ label = "dev_loss_tmo\nexpired or\nsrp_stop_rport_timers()" ];
failfast -> lost [ label = "dev_loss_tmo\nexpired or\nsrp_stop_rport_timers()" ];
blocked -> running [ label = "reconnecting\nsucceeded" ];
failfast -> failfast [ label = "reconnecting\nfailed" ];
failfast -> running [ label = "reconnecting\nsucceeded" ];
running -> lost [ label = "srp_stop_rport_timers()" ];
running_rta -> lost [ label = "srp_stop_rport_timers()" ];
}
7 changes: 6 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2195,6 +2195,11 @@ M: Nishank Trivedi <[email protected]>
S: Supported
F: drivers/net/ethernet/cisco/enic/

CISCO VIC LOW LATENCY NIC DRIVER
M: Upinder Malhi <[email protected]>
S: Supported
F: drivers/infiniband/hw/usnic

CIRRUS LOGIC EP93XX ETHERNET DRIVER
M: Hartley Sweeten <[email protected]>
L: [email protected]
Expand Down Expand Up @@ -7528,7 +7533,7 @@ S: Maintained
F: drivers/scsi/sr*

SCSI RDMA PROTOCOL (SRP) INITIATOR
M: David Dillow <[email protected]>
M: Bart Van Assche <[email protected]>
L: [email protected]
S: Supported
W: http://www.openfabrics.org
Expand Down
6 changes: 4 additions & 2 deletions drivers/infiniband/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ menuconfig INFINIBAND
depends on PCI || BROKEN
depends on HAS_IOMEM
depends on NET
depends on INET
depends on m || IPV6 != m
---help---
Core support for InfiniBand (IB). Make sure to also select
any protocols you wish to use as well as drivers for your
Expand Down Expand Up @@ -38,8 +40,7 @@ config INFINIBAND_USER_MEM

config INFINIBAND_ADDR_TRANS
bool
depends on INET
depends on !(INFINIBAND = y && IPV6 = m)
depends on INFINIBAND
default y

source "drivers/infiniband/hw/mthca/Kconfig"
Expand All @@ -53,6 +54,7 @@ source "drivers/infiniband/hw/mlx4/Kconfig"
source "drivers/infiniband/hw/mlx5/Kconfig"
source "drivers/infiniband/hw/nes/Kconfig"
source "drivers/infiniband/hw/ocrdma/Kconfig"
source "drivers/infiniband/hw/usnic/Kconfig"

source "drivers/infiniband/ulp/ipoib/Kconfig"

Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/
obj-$(CONFIG_MLX5_INFINIBAND) += hw/mlx5/
obj-$(CONFIG_INFINIBAND_NES) += hw/nes/
obj-$(CONFIG_INFINIBAND_OCRDMA) += hw/ocrdma/
obj-$(CONFIG_INFINIBAND_USNIC) += hw/usnic/
obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/
obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/
obj-$(CONFIG_INFINIBAND_SRPT) += ulp/srpt/
Expand Down
5 changes: 3 additions & 2 deletions drivers/infiniband/core/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS) := ib_addr.o rdma_cm.o
infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS) := rdma_cm.o
user_access-$(CONFIG_INFINIBAND_ADDR_TRANS) := rdma_ucm.o

obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \
ib_cm.o iw_cm.o $(infiniband-y)
ib_cm.o iw_cm.o ib_addr.o \
$(infiniband-y)
obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o
obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \
$(user_access-y)
Expand Down
97 changes: 94 additions & 3 deletions drivers/infiniband/core/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ int rdma_addr_size(struct sockaddr *addr)
}
EXPORT_SYMBOL(rdma_addr_size);

static struct rdma_addr_client self;

void rdma_addr_register_client(struct rdma_addr_client *client)
{
atomic_set(&client->refcount, 1);
Expand Down Expand Up @@ -119,7 +121,8 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
}
EXPORT_SYMBOL(rdma_copy_addr);

int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
u16 *vlan_id)
{
struct net_device *dev;
int ret = -EADDRNOTAVAIL;
Expand All @@ -142,6 +145,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
return ret;

ret = rdma_copy_addr(dev_addr, dev, NULL);
if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(dev);
dev_put(dev);
break;

Expand All @@ -153,6 +158,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
&((struct sockaddr_in6 *) addr)->sin6_addr,
dev, 1)) {
ret = rdma_copy_addr(dev_addr, dev, NULL);
if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(dev);
break;
}
}
Expand Down Expand Up @@ -238,7 +245,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
src_in->sin_addr.s_addr = fl4.saddr;

if (rt->dst.dev->flags & IFF_LOOPBACK) {
ret = rdma_translate_ip((struct sockaddr *) dst_in, addr);
ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
if (!ret)
memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
goto put;
Expand Down Expand Up @@ -286,7 +293,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
}

if (dst->dev->flags & IFF_LOOPBACK) {
ret = rdma_translate_ip((struct sockaddr *) dst_in, addr);
ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
if (!ret)
memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
goto put;
Expand Down Expand Up @@ -437,6 +444,88 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr)
}
EXPORT_SYMBOL(rdma_addr_cancel);

struct resolve_cb_context {
struct rdma_dev_addr *addr;
struct completion comp;
};

static void resolve_cb(int status, struct sockaddr *src_addr,
struct rdma_dev_addr *addr, void *context)
{
memcpy(((struct resolve_cb_context *)context)->addr, addr, sizeof(struct
rdma_dev_addr));
complete(&((struct resolve_cb_context *)context)->comp);
}

int rdma_addr_find_dmac_by_grh(union ib_gid *sgid, union ib_gid *dgid, u8 *dmac,
u16 *vlan_id)
{
int ret = 0;
struct rdma_dev_addr dev_addr;
struct resolve_cb_context ctx;
struct net_device *dev;

union {
struct sockaddr _sockaddr;
struct sockaddr_in _sockaddr_in;
struct sockaddr_in6 _sockaddr_in6;
} sgid_addr, dgid_addr;


ret = rdma_gid2ip(&sgid_addr._sockaddr, sgid);
if (ret)
return ret;

ret = rdma_gid2ip(&dgid_addr._sockaddr, dgid);
if (ret)
return ret;

memset(&dev_addr, 0, sizeof(dev_addr));

ctx.addr = &dev_addr;
init_completion(&ctx.comp);
ret = rdma_resolve_ip(&self, &sgid_addr._sockaddr, &dgid_addr._sockaddr,
&dev_addr, 1000, resolve_cb, &ctx);
if (ret)
return ret;

wait_for_completion(&ctx.comp);

memcpy(dmac, dev_addr.dst_dev_addr, ETH_ALEN);
dev = dev_get_by_index(&init_net, dev_addr.bound_dev_if);
if (!dev)
return -ENODEV;
if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(dev);
dev_put(dev);
return ret;
}
EXPORT_SYMBOL(rdma_addr_find_dmac_by_grh);

int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id)
{
int ret = 0;
struct rdma_dev_addr dev_addr;
union {
struct sockaddr _sockaddr;
struct sockaddr_in _sockaddr_in;
struct sockaddr_in6 _sockaddr_in6;
} gid_addr;

ret = rdma_gid2ip(&gid_addr._sockaddr, sgid);

if (ret)
return ret;
memset(&dev_addr, 0, sizeof(dev_addr));
ret = rdma_translate_ip(&gid_addr._sockaddr, &dev_addr, vlan_id);
if (ret)
return ret;

memcpy(smac, dev_addr.src_dev_addr, ETH_ALEN);
return ret;
}
EXPORT_SYMBOL(rdma_addr_find_smac_by_sgid);

static int netevent_callback(struct notifier_block *self, unsigned long event,
void *ctx)
{
Expand All @@ -461,11 +550,13 @@ static int __init addr_init(void)
return -ENOMEM;

register_netevent_notifier(&nb);
rdma_addr_register_client(&self);
return 0;
}

static void __exit addr_cleanup(void)
{
rdma_addr_unregister_client(&self);
unregister_netevent_notifier(&nb);
destroy_workqueue(addr_wq);
}
Expand Down
52 changes: 52 additions & 0 deletions drivers/infiniband/core/cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <linux/sysfs.h>
#include <linux/workqueue.h>
#include <linux/kdev_t.h>
#include <linux/etherdevice.h>

#include <rdma/ib_cache.h>
#include <rdma/ib_cm.h>
Expand Down Expand Up @@ -177,6 +178,8 @@ struct cm_av {
struct ib_ah_attr ah_attr;
u16 pkey_index;
u8 timeout;
u8 valid;
u8 smac[ETH_ALEN];
};

struct cm_work {
Expand Down Expand Up @@ -346,6 +349,23 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
grh, &av->ah_attr);
}

int ib_update_cm_av(struct ib_cm_id *id, const u8 *smac, const u8 *alt_smac)
{
struct cm_id_private *cm_id_priv;

cm_id_priv = container_of(id, struct cm_id_private, id);

if (smac != NULL)
memcpy(cm_id_priv->av.smac, smac, sizeof(cm_id_priv->av.smac));

if (alt_smac != NULL)
memcpy(cm_id_priv->alt_av.smac, alt_smac,
sizeof(cm_id_priv->alt_av.smac));

return 0;
}
EXPORT_SYMBOL(ib_update_cm_av);

static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
{
struct cm_device *cm_dev;
Expand Down Expand Up @@ -376,6 +396,9 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
ib_init_ah_from_path(cm_dev->ib_device, port->port_num, path,
&av->ah_attr);
av->timeout = path->packet_life_time + 1;
memcpy(av->smac, path->smac, sizeof(av->smac));

av->valid = 1;
return 0;
}

Expand Down Expand Up @@ -1554,6 +1577,9 @@ static int cm_req_handler(struct cm_work *work)

cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);

memcpy(work->path[0].dmac, cm_id_priv->av.ah_attr.dmac, ETH_ALEN);
work->path[0].vlan_id = cm_id_priv->av.ah_attr.vlan_id;
ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
if (ret) {
ib_get_cached_gid(work->port->cm_dev->ib_device,
Expand Down Expand Up @@ -3500,6 +3526,32 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv,
*qp_attr_mask = IB_QP_STATE | IB_QP_AV | IB_QP_PATH_MTU |
IB_QP_DEST_QPN | IB_QP_RQ_PSN;
qp_attr->ah_attr = cm_id_priv->av.ah_attr;
if (!cm_id_priv->av.valid) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
return -EINVAL;
}
if (cm_id_priv->av.ah_attr.vlan_id != 0xffff) {
qp_attr->vlan_id = cm_id_priv->av.ah_attr.vlan_id;
*qp_attr_mask |= IB_QP_VID;
}
if (!is_zero_ether_addr(cm_id_priv->av.smac)) {
memcpy(qp_attr->smac, cm_id_priv->av.smac,
sizeof(qp_attr->smac));
*qp_attr_mask |= IB_QP_SMAC;
}
if (cm_id_priv->alt_av.valid) {
if (cm_id_priv->alt_av.ah_attr.vlan_id != 0xffff) {
qp_attr->alt_vlan_id =
cm_id_priv->alt_av.ah_attr.vlan_id;
*qp_attr_mask |= IB_QP_ALT_VID;
}
if (!is_zero_ether_addr(cm_id_priv->alt_av.smac)) {
memcpy(qp_attr->alt_smac,
cm_id_priv->alt_av.smac,
sizeof(qp_attr->alt_smac));
*qp_attr_mask |= IB_QP_ALT_SMAC;
}
}
qp_attr->path_mtu = cm_id_priv->path_mtu;
qp_attr->dest_qp_num = be32_to_cpu(cm_id_priv->remote_qpn);
qp_attr->rq_psn = be32_to_cpu(cm_id_priv->rq_psn);
Expand Down
Loading

0 comments on commit 8e585a6

Please sign in to comment.