Skip to content

Commit

Permalink
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/roland/infiniband

* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband: (49 commits)
  IB: Set class_dev->dev in core for nice device symlink
  IB/ehca: Implement modify_port
  IB/umad: Clarify documentation of transaction ID
  IPoIB/cm: spin_lock_irqsave() -> spin_lock_irq() replacements
  IB/mad: Change SMI to use enums rather than magic return codes
  IB/umad: Implement GRH handling for sent/received MADs
  IB/ipoib: Use ib_init_ah_from_path to initialize ah_attr
  IB/sa: Set src_path_bits correctly in ib_init_ah_from_path()
  IB/ucm: Simplify ib_ucm_event()
  RDMA/ucma: Simplify ucma_get_event()
  IB/mthca: Simplify CQ cleaning in mthca_free_qp()
  IB/mthca: Fix mthca_write_mtt() on HCAs with hidden memory
  IB/mthca: Update HCA firmware revisions
  IB/ipath: Fix WC format drift between user and kernel space
  IB/ipath: Check that a UD work request's address handle is valid
  IB/ipath: Remove duplicate stuff from ipath_verbs.h
  IB/ipath: Check reserved memory keys
  IB/ipath: Fix unit selection when all CPU affinity bits set
  IB/ipath: Don't allow QPs 0 and 1 to be opened multiple times
  IB/ipath: Disable IB link earlier in shutdown sequence
  ...
  • Loading branch information
Linus Torvalds committed Apr 27, 2007
2 parents 0278ef8 + 1912ffb commit afc2e82
Show file tree
Hide file tree
Showing 47 changed files with 1,620 additions and 1,002 deletions.
8 changes: 8 additions & 0 deletions Documentation/infiniband/user_mad.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ Sending MADs
if (ret != sizeof *mad + mad_length)
perror("write");

Transaction IDs

Users of the umad devices can use the lower 32 bits of the
transaction ID field (that is, the least significant half of the
field in network byte order) in MADs being sent to match
request/response pairs. The upper 32 bits are reserved for use by
the kernel and will be overwritten before a MAD is sent.

Setting IsSM Capability Bit

To set the IsSM capability bit for a port, simply open the
Expand Down
1 change: 0 additions & 1 deletion drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_MMC) += mmc/
obj-$(CONFIG_NEW_LEDS) += leds/
obj-$(CONFIG_INFINIBAND) += infiniband/
obj-$(CONFIG_IPATH_CORE) += infiniband/
obj-$(CONFIG_SGI_SN) += sn/
obj-y += firmware/
obj-$(CONFIG_CRYPTO) += crypto/
Expand Down
34 changes: 19 additions & 15 deletions drivers/infiniband/core/mad.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
* Copyright (c) 2004-2007 Voltaire, Inc. All rights reserved.
* Copyright (c) 2005 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
*
Expand Down Expand Up @@ -31,7 +31,6 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* $Id: mad.c 5596 2006-03-03 01:00:07Z sean.hefty $
*/
#include <linux/dma-mapping.h>
#include <rdma/ib_cache.h>
Expand Down Expand Up @@ -668,7 +667,7 @@ static void build_smp_wc(struct ib_qp *qp,
static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
struct ib_mad_send_wr_private *mad_send_wr)
{
int ret;
int ret = 0;
struct ib_smp *smp = mad_send_wr->send_buf.mad;
unsigned long flags;
struct ib_mad_local_private *local;
Expand All @@ -688,14 +687,15 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
*/
if ((ib_get_smp_direction(smp) ? smp->dr_dlid : smp->dr_slid) ==
IB_LID_PERMISSIVE &&
!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
smi_handle_dr_smp_send(smp, device->node_type, port_num) ==
IB_SMI_DISCARD) {
ret = -EINVAL;
printk(KERN_ERR PFX "Invalid directed route\n");
goto out;
}

/* Check to post send on QP or process locally */
ret = smi_check_local_smp(smp, device);
if (!ret)
if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD)
goto out;

local = kmalloc(sizeof *local, GFP_ATOMIC);
Expand Down Expand Up @@ -1874,18 +1874,22 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,

if (recv->mad.mad.mad_hdr.mgmt_class ==
IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
if (!smi_handle_dr_smp_recv(&recv->mad.smp,
port_priv->device->node_type,
port_priv->port_num,
port_priv->device->phys_port_cnt))
if (smi_handle_dr_smp_recv(&recv->mad.smp,
port_priv->device->node_type,
port_priv->port_num,
port_priv->device->phys_port_cnt) ==
IB_SMI_DISCARD)
goto out;
if (!smi_check_forward_dr_smp(&recv->mad.smp))

if (smi_check_forward_dr_smp(&recv->mad.smp) == IB_SMI_LOCAL)
goto local;
if (!smi_handle_dr_smp_send(&recv->mad.smp,
port_priv->device->node_type,
port_priv->port_num))

if (smi_handle_dr_smp_send(&recv->mad.smp,
port_priv->device->node_type,
port_priv->port_num) == IB_SMI_DISCARD)
goto out;
if (!smi_check_local_smp(&recv->mad.smp, port_priv->device))

if (smi_check_local_smp(&recv->mad.smp, port_priv->device) == IB_SMI_DISCARD)
goto out;
}

Expand Down
24 changes: 23 additions & 1 deletion drivers/infiniband/core/sa_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ MODULE_LICENSE("Dual BSD/GPL");
struct ib_sa_sm_ah {
struct ib_ah *ah;
struct kref ref;
u8 src_path_mask;
};

struct ib_sa_port {
Expand Down Expand Up @@ -380,6 +381,7 @@ static void update_sm_ah(struct work_struct *work)
}

kref_init(&new_ah->ref);
new_ah->src_path_mask = (1 << port_attr.lmc) - 1;

memset(&ah_attr, 0, sizeof ah_attr);
ah_attr.dlid = port_attr.sm_lid;
Expand Down Expand Up @@ -460,6 +462,25 @@ void ib_sa_cancel_query(int id, struct ib_sa_query *query)
}
EXPORT_SYMBOL(ib_sa_cancel_query);

static u8 get_src_path_mask(struct ib_device *device, u8 port_num)
{
struct ib_sa_device *sa_dev;
struct ib_sa_port *port;
unsigned long flags;
u8 src_path_mask;

sa_dev = ib_get_client_data(device, &sa_client);
if (!sa_dev)
return 0x7f;

port = &sa_dev->port[port_num - sa_dev->start_port];
spin_lock_irqsave(&port->ah_lock, flags);
src_path_mask = port->sm_ah ? port->sm_ah->src_path_mask : 0x7f;
spin_unlock_irqrestore(&port->ah_lock, flags);

return src_path_mask;
}

int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
struct ib_sa_path_rec *rec, struct ib_ah_attr *ah_attr)
{
Expand All @@ -469,7 +490,8 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
memset(ah_attr, 0, sizeof *ah_attr);
ah_attr->dlid = be16_to_cpu(rec->dlid);
ah_attr->sl = rec->sl;
ah_attr->src_path_bits = be16_to_cpu(rec->slid) & 0x7f;
ah_attr->src_path_bits = be16_to_cpu(rec->slid) &
get_src_path_mask(device, port_num);
ah_attr->port_num = port_num;
ah_attr->static_rate = rec->rate;

Expand Down
86 changes: 43 additions & 43 deletions drivers/infiniband/core/smi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
* Copyright (c) 2004-2007 Voltaire Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
Expand Down Expand Up @@ -34,7 +34,6 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* $Id: smi.c 1389 2004-12-27 22:56:47Z roland $
*/

#include <rdma/ib_smi.h>
Expand All @@ -44,9 +43,8 @@
* Fixup a directed route SMP for sending
* Return 0 if the SMP should be discarded
*/
int smi_handle_dr_smp_send(struct ib_smp *smp,
u8 node_type,
int port_num)
enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
u8 node_type, int port_num)
{
u8 hop_ptr, hop_cnt;

Expand All @@ -59,75 +57,75 @@ int smi_handle_dr_smp_send(struct ib_smp *smp,
if (hop_cnt && hop_ptr == 0) {
smp->hop_ptr++;
return (smp->initial_path[smp->hop_ptr] ==
port_num);
port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-9:2 */
if (hop_ptr && hop_ptr < hop_cnt) {
if (node_type != RDMA_NODE_IB_SWITCH)
return 0;
return IB_SMI_DISCARD;

/* smp->return_path set when received */
smp->hop_ptr++;
return (smp->initial_path[smp->hop_ptr] ==
port_num);
port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-9:3 -- We're at the end of the DR segment of path */
if (hop_ptr == hop_cnt) {
/* smp->return_path set when received */
smp->hop_ptr++;
return (node_type == RDMA_NODE_IB_SWITCH ||
smp->dr_dlid == IB_LID_PERMISSIVE);
smp->dr_dlid == IB_LID_PERMISSIVE ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
/* C14-9:5 -- Fail unreasonable hop pointer */
return (hop_ptr == hop_cnt + 1);
return (hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD);

} else {
/* C14-13:1 */
if (hop_cnt && hop_ptr == hop_cnt + 1) {
smp->hop_ptr--;
return (smp->return_path[smp->hop_ptr] ==
port_num);
port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-13:2 */
if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
if (node_type != RDMA_NODE_IB_SWITCH)
return 0;
return IB_SMI_DISCARD;

smp->hop_ptr--;
return (smp->return_path[smp->hop_ptr] ==
port_num);
port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-13:3 -- at the end of the DR segment of path */
if (hop_ptr == 1) {
smp->hop_ptr--;
/* C14-13:3 -- SMPs destined for SM shouldn't be here */
return (node_type == RDMA_NODE_IB_SWITCH ||
smp->dr_slid == IB_LID_PERMISSIVE);
smp->dr_slid == IB_LID_PERMISSIVE ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-13:4 -- hop_ptr = 0 -> should have gone to SM */
if (hop_ptr == 0)
return 1;
return IB_SMI_HANDLE;

/* C14-13:5 -- Check for unreasonable hop pointer */
return 0;
return IB_SMI_DISCARD;
}
}

/*
* Adjust information for a received SMP
* Return 0 if the SMP should be dropped
*/
int smi_handle_dr_smp_recv(struct ib_smp *smp,
u8 node_type,
int port_num,
int phys_port_cnt)
enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type,
int port_num, int phys_port_cnt)
{
u8 hop_ptr, hop_cnt;

Expand All @@ -138,16 +136,17 @@ int smi_handle_dr_smp_recv(struct ib_smp *smp,
if (!ib_get_smp_direction(smp)) {
/* C14-9:1 -- sender should have incremented hop_ptr */
if (hop_cnt && hop_ptr == 0)
return 0;
return IB_SMI_DISCARD;

/* C14-9:2 -- intermediate hop */
if (hop_ptr && hop_ptr < hop_cnt) {
if (node_type != RDMA_NODE_IB_SWITCH)
return 0;
return IB_SMI_DISCARD;

smp->return_path[hop_ptr] = port_num;
/* smp->hop_ptr updated when sending */
return (smp->initial_path[hop_ptr+1] <= phys_port_cnt);
return (smp->initial_path[hop_ptr+1] <= phys_port_cnt ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-9:3 -- We're at the end of the DR segment of path */
Expand All @@ -157,53 +156,52 @@ int smi_handle_dr_smp_recv(struct ib_smp *smp,
/* smp->hop_ptr updated when sending */

return (node_type == RDMA_NODE_IB_SWITCH ||
smp->dr_dlid == IB_LID_PERMISSIVE);
smp->dr_dlid == IB_LID_PERMISSIVE ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
/* C14-9:5 -- fail unreasonable hop pointer */
return (hop_ptr == hop_cnt + 1);
return (hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD);

} else {

/* C14-13:1 */
if (hop_cnt && hop_ptr == hop_cnt + 1) {
smp->hop_ptr--;
return (smp->return_path[smp->hop_ptr] ==
port_num);
port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-13:2 */
if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
if (node_type != RDMA_NODE_IB_SWITCH)
return 0;
return IB_SMI_DISCARD;

/* smp->hop_ptr updated when sending */
return (smp->return_path[hop_ptr-1] <= phys_port_cnt);
return (smp->return_path[hop_ptr-1] <= phys_port_cnt ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}

/* C14-13:3 -- We're at the end of the DR segment of path */
if (hop_ptr == 1) {
if (smp->dr_slid == IB_LID_PERMISSIVE) {
/* giving SMP to SM - update hop_ptr */
smp->hop_ptr--;
return 1;
return IB_SMI_HANDLE;
}
/* smp->hop_ptr updated when sending */
return (node_type == RDMA_NODE_IB_SWITCH);
return (node_type == RDMA_NODE_IB_SWITCH ?
IB_SMI_HANDLE: IB_SMI_DISCARD);
}

/* C14-13:4 -- hop_ptr = 0 -> give to SM */
/* C14-13:5 -- Check for unreasonable hop pointer */
return (hop_ptr == 0);
return (hop_ptr == 0 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}
}

/*
* Return 1 if the received DR SMP should be forwarded to the send queue
* Return 0 if the SMP should be completed up the stack
*/
int smi_check_forward_dr_smp(struct ib_smp *smp)
enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp)
{
u8 hop_ptr, hop_cnt;

Expand All @@ -213,23 +211,25 @@ int smi_check_forward_dr_smp(struct ib_smp *smp)
if (!ib_get_smp_direction(smp)) {
/* C14-9:2 -- intermediate hop */
if (hop_ptr && hop_ptr < hop_cnt)
return 1;
return IB_SMI_SEND;

/* C14-9:3 -- at the end of the DR segment of path */
if (hop_ptr == hop_cnt)
return (smp->dr_dlid == IB_LID_PERMISSIVE);
return (smp->dr_dlid == IB_LID_PERMISSIVE ?
IB_SMI_SEND : IB_SMI_LOCAL);

/* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
if (hop_ptr == hop_cnt + 1)
return 1;
return IB_SMI_SEND;
} else {
/* C14-13:2 */
/* C14-13:2 -- intermediate hop */
if (2 <= hop_ptr && hop_ptr <= hop_cnt)
return 1;
return IB_SMI_SEND;

/* C14-13:3 -- at the end of the DR segment of path */
if (hop_ptr == 1)
return (smp->dr_slid != IB_LID_PERMISSIVE);
return (smp->dr_slid != IB_LID_PERMISSIVE ?
IB_SMI_SEND : IB_SMI_LOCAL);
}
return 0;
return IB_SMI_LOCAL;
}
Loading

0 comments on commit afc2e82

Please sign in to comment.