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:
  IB/mthca: Fix max_srq_sge returned by ib_query_device for Tavor devices
  IB/cache: Use correct pointer to calculate size
  IPoIB: Use spin_lock_irq() instead of spin_lock_irqsave()
  IPoIB: Close race in ipoib_flush_paths()
  IB/mthca: Disable tuning PCI read burst size
  IPoIB: Make send and receive queue sizes tunable
  IPoIB: Wait for join to finish before freeing mcast struct
  IB: simplify static rate encoding
  IPoIB: Consolidate private neighbour data handling
  IB/srp: Fix memory leak in options parsing
  IB/mthca: Always build debugging code unless CONFIG_EMBEDDED=y
  IPoIB: Always build debugging code unless CONFIG_EMBEDDED=y
  IB/mad: fix oops in cancel_mads
  • Loading branch information
Linus Torvalds committed Apr 12, 2006
2 parents 646e120 + 59fef3b commit 907d91d
Show file tree
Hide file tree
Showing 25 changed files with 430 additions and 142 deletions.
2 changes: 1 addition & 1 deletion drivers/infiniband/core/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ static void ib_cache_setup_one(struct ib_device *device)
kmalloc(sizeof *device->cache.pkey_cache *
(end_port(device) - start_port(device) + 1), GFP_KERNEL);
device->cache.gid_cache =
kmalloc(sizeof *device->cache.pkey_cache *
kmalloc(sizeof *device->cache.gid_cache *
(end_port(device) - start_port(device) + 1), GFP_KERNEL);

if (!device->cache.pkey_cache || !device->cache.gid_cache) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/core/mad.c
Original file line number Diff line number Diff line change
Expand Up @@ -2311,6 +2311,7 @@ static void local_completions(void *data)
local = list_entry(mad_agent_priv->local_list.next,
struct ib_mad_local_private,
completion_list);
list_del(&local->completion_list);
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
if (local->mad_priv) {
recv_mad_agent = local->recv_mad_agent;
Expand Down Expand Up @@ -2362,7 +2363,6 @@ static void local_completions(void *data)
&mad_send_wc);

spin_lock_irqsave(&mad_agent_priv->lock, flags);
list_del(&local->completion_list);
atomic_dec(&mad_agent_priv->refcount);
if (!recv)
kmem_cache_free(ib_mad_cache, local->mad_priv);
Expand Down
34 changes: 34 additions & 0 deletions drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,40 @@
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>

int ib_rate_to_mult(enum ib_rate rate)
{
switch (rate) {
case IB_RATE_2_5_GBPS: return 1;
case IB_RATE_5_GBPS: return 2;
case IB_RATE_10_GBPS: return 4;
case IB_RATE_20_GBPS: return 8;
case IB_RATE_30_GBPS: return 12;
case IB_RATE_40_GBPS: return 16;
case IB_RATE_60_GBPS: return 24;
case IB_RATE_80_GBPS: return 32;
case IB_RATE_120_GBPS: return 48;
default: return -1;
}
}
EXPORT_SYMBOL(ib_rate_to_mult);

enum ib_rate mult_to_ib_rate(int mult)
{
switch (mult) {
case 1: return IB_RATE_2_5_GBPS;
case 2: return IB_RATE_5_GBPS;
case 4: return IB_RATE_10_GBPS;
case 8: return IB_RATE_20_GBPS;
case 12: return IB_RATE_30_GBPS;
case 16: return IB_RATE_40_GBPS;
case 24: return IB_RATE_60_GBPS;
case 32: return IB_RATE_80_GBPS;
case 48: return IB_RATE_120_GBPS;
default: return IB_RATE_PORT_CURRENT;
}
}
EXPORT_SYMBOL(mult_to_ib_rate);

/* Protection domains */

struct ib_pd *ib_alloc_pd(struct ib_device *device)
Expand Down
11 changes: 6 additions & 5 deletions drivers/infiniband/hw/mthca/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ config INFINIBAND_MTHCA
("Tavor") and the MT25208 PCI Express HCA ("Arbel").

config INFINIBAND_MTHCA_DEBUG
bool "Verbose debugging output"
bool "Verbose debugging output" if EMBEDDED
depends on INFINIBAND_MTHCA
default n
default y
---help---
This option causes the mthca driver produce a bunch of debug
messages. Select this is you are developing the driver or
trying to diagnose a problem.
This option causes debugging code to be compiled into the
mthca driver. The output can be turned on via the
debug_level module parameter (which can also be set after
the driver is loaded through sysfs).
4 changes: 0 additions & 4 deletions drivers/infiniband/hw/mthca/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
EXTRA_CFLAGS += -DDEBUG
endif

obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o

ib_mthca-y := mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \
Expand Down
100 changes: 99 additions & 1 deletion drivers/infiniband/hw/mthca/mthca_av.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@

#include "mthca_dev.h"

enum {
MTHCA_RATE_TAVOR_FULL = 0,
MTHCA_RATE_TAVOR_1X = 1,
MTHCA_RATE_TAVOR_4X = 2,
MTHCA_RATE_TAVOR_1X_DDR = 3
};

enum {
MTHCA_RATE_MEMFREE_FULL = 0,
MTHCA_RATE_MEMFREE_QUARTER = 1,
MTHCA_RATE_MEMFREE_EIGHTH = 2,
MTHCA_RATE_MEMFREE_HALF = 3
};

struct mthca_av {
__be32 port_pd;
u8 reserved1;
Expand All @@ -55,6 +69,90 @@ struct mthca_av {
__be32 dgid[4];
};

static enum ib_rate memfree_rate_to_ib(u8 mthca_rate, u8 port_rate)
{
switch (mthca_rate) {
case MTHCA_RATE_MEMFREE_EIGHTH:
return mult_to_ib_rate(port_rate >> 3);
case MTHCA_RATE_MEMFREE_QUARTER:
return mult_to_ib_rate(port_rate >> 2);
case MTHCA_RATE_MEMFREE_HALF:
return mult_to_ib_rate(port_rate >> 1);
case MTHCA_RATE_MEMFREE_FULL:
default:
return mult_to_ib_rate(port_rate);
}
}

static enum ib_rate tavor_rate_to_ib(u8 mthca_rate, u8 port_rate)
{
switch (mthca_rate) {
case MTHCA_RATE_TAVOR_1X: return IB_RATE_2_5_GBPS;
case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS;
case MTHCA_RATE_TAVOR_4X: return IB_RATE_10_GBPS;
default: return port_rate;
}
}

enum ib_rate mthca_rate_to_ib(struct mthca_dev *dev, u8 mthca_rate, u8 port)
{
if (mthca_is_memfree(dev)) {
/* Handle old Arbel FW */
if (dev->limits.stat_rate_support == 0x3 && mthca_rate)
return IB_RATE_2_5_GBPS;

return memfree_rate_to_ib(mthca_rate, dev->rate[port - 1]);
} else
return tavor_rate_to_ib(mthca_rate, dev->rate[port - 1]);
}

static u8 ib_rate_to_memfree(u8 req_rate, u8 cur_rate)
{
if (cur_rate <= req_rate)
return 0;

/*
* Inter-packet delay (IPD) to get from rate X down to a rate
* no more than Y is (X - 1) / Y.
*/
switch ((cur_rate - 1) / req_rate) {
case 0: return MTHCA_RATE_MEMFREE_FULL;
case 1: return MTHCA_RATE_MEMFREE_HALF;
case 2: /* fall through */
case 3: return MTHCA_RATE_MEMFREE_QUARTER;
default: return MTHCA_RATE_MEMFREE_EIGHTH;
}
}

static u8 ib_rate_to_tavor(u8 static_rate)
{
switch (static_rate) {
case IB_RATE_2_5_GBPS: return MTHCA_RATE_TAVOR_1X;
case IB_RATE_5_GBPS: return MTHCA_RATE_TAVOR_1X_DDR;
case IB_RATE_10_GBPS: return MTHCA_RATE_TAVOR_4X;
default: return MTHCA_RATE_TAVOR_FULL;
}
}

u8 mthca_get_rate(struct mthca_dev *dev, int static_rate, u8 port)
{
u8 rate;

if (!static_rate || ib_rate_to_mult(static_rate) >= dev->rate[port - 1])
return 0;

if (mthca_is_memfree(dev))
rate = ib_rate_to_memfree(ib_rate_to_mult(static_rate),
dev->rate[port - 1]);
else
rate = ib_rate_to_tavor(static_rate);

if (!(dev->limits.stat_rate_support & (1 << rate)))
rate = 1;

return rate;
}

int mthca_create_ah(struct mthca_dev *dev,
struct mthca_pd *pd,
struct ib_ah_attr *ah_attr,
Expand Down Expand Up @@ -107,7 +205,7 @@ int mthca_create_ah(struct mthca_dev *dev,
av->g_slid = ah_attr->src_path_bits;
av->dlid = cpu_to_be16(ah_attr->dlid);
av->msg_sr = (3 << 4) | /* 2K message */
ah_attr->static_rate;
mthca_get_rate(dev, ah_attr->static_rate, ah_attr->port_num);
av->sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
if (ah_attr->ah_flags & IB_AH_GRH) {
av->g_slid |= 0x80;
Expand Down
4 changes: 4 additions & 0 deletions drivers/infiniband/hw/mthca/mthca_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,7 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
u32 *outbox;
u8 field;
u16 size;
u16 stat_rate;
int err;

#define QUERY_DEV_LIM_OUT_SIZE 0x100
Expand Down Expand Up @@ -995,6 +996,7 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
#define QUERY_DEV_LIM_MTU_WIDTH_OFFSET 0x36
#define QUERY_DEV_LIM_VL_PORT_OFFSET 0x37
#define QUERY_DEV_LIM_MAX_GID_OFFSET 0x3b
#define QUERY_DEV_LIM_RATE_SUPPORT_OFFSET 0x3c
#define QUERY_DEV_LIM_MAX_PKEY_OFFSET 0x3f
#define QUERY_DEV_LIM_FLAGS_OFFSET 0x44
#define QUERY_DEV_LIM_RSVD_UAR_OFFSET 0x48
Expand Down Expand Up @@ -1086,6 +1088,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
dev_lim->num_ports = field & 0xf;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_GID_OFFSET);
dev_lim->max_gids = 1 << (field & 0xf);
MTHCA_GET(stat_rate, outbox, QUERY_DEV_LIM_RATE_SUPPORT_OFFSET);
dev_lim->stat_rate_support = stat_rate;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_PKEY_OFFSET);
dev_lim->max_pkeys = 1 << (field & 0xf);
MTHCA_GET(dev_lim->flags, outbox, QUERY_DEV_LIM_FLAGS_OFFSET);
Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/hw/mthca/mthca_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ struct mthca_dev_lim {
int max_vl;
int num_ports;
int max_gids;
u16 stat_rate_support;
int max_pkeys;
u32 flags;
int reserved_uars;
Expand Down
23 changes: 21 additions & 2 deletions drivers/infiniband/hw/mthca/mthca_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ struct mthca_limits {
int reserved_qps;
int num_srqs;
int max_srq_wqes;
int max_srq_sge;
int reserved_srqs;
int num_eecs;
int reserved_eecs;
Expand All @@ -172,6 +173,7 @@ struct mthca_limits {
int reserved_pds;
u32 page_size_cap;
u32 flags;
u16 stat_rate_support;
u8 port_width_cap;
};

Expand Down Expand Up @@ -353,10 +355,24 @@ struct mthca_dev {
struct ib_mad_agent *send_agent[MTHCA_MAX_PORTS][2];
struct ib_ah *sm_ah[MTHCA_MAX_PORTS];
spinlock_t sm_lock;
u8 rate[MTHCA_MAX_PORTS];
};

#define mthca_dbg(mdev, format, arg...) \
dev_dbg(&mdev->pdev->dev, format, ## arg)
#ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
extern int mthca_debug_level;

#define mthca_dbg(mdev, format, arg...) \
do { \
if (mthca_debug_level) \
dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \
} while (0)

#else /* CONFIG_INFINIBAND_MTHCA_DEBUG */

#define mthca_dbg(mdev, format, arg...) do { (void) mdev; } while (0)

#endif /* CONFIG_INFINIBAND_MTHCA_DEBUG */

#define mthca_err(mdev, format, arg...) \
dev_err(&mdev->pdev->dev, format, ## arg)
#define mthca_info(mdev, format, arg...) \
Expand Down Expand Up @@ -492,6 +508,7 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
enum ib_srq_attr_mask attr_mask);
int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
int mthca_max_srq_sge(struct mthca_dev *dev);
void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
enum ib_event_type event_type);
void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
Expand Down Expand Up @@ -542,6 +559,8 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
struct ib_ud_header *header);
int mthca_ah_query(struct ib_ah *ibah, struct ib_ah_attr *attr);
int mthca_ah_grh_present(struct mthca_ah *ah);
u8 mthca_get_rate(struct mthca_dev *dev, int static_rate, u8 port);
enum ib_rate mthca_rate_to_ib(struct mthca_dev *dev, u8 mthca_rate, u8 port);

int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
Expand Down
42 changes: 40 additions & 2 deletions drivers/infiniband/hw/mthca/mthca_mad.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,30 @@ enum {
MTHCA_VENDOR_CLASS2 = 0xa
};

int mthca_update_rate(struct mthca_dev *dev, u8 port_num)
{
struct ib_port_attr *tprops = NULL;
int ret;

tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
if (!tprops)
return -ENOMEM;

ret = ib_query_port(&dev->ib_dev, port_num, tprops);
if (ret) {
printk(KERN_WARNING "ib_query_port failed (%d) for %s port %d\n",
ret, dev->ib_dev.name, port_num);
goto out;
}

dev->rate[port_num - 1] = tprops->active_speed *
ib_width_enum_to_int(tprops->active_width);

out:
kfree(tprops);
return ret;
}

static void update_sm_ah(struct mthca_dev *dev,
u8 port_num, u16 lid, u8 sl)
{
Expand Down Expand Up @@ -90,6 +114,7 @@ static void smp_snoop(struct ib_device *ibdev,
mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
mad->mad_hdr.method == IB_MGMT_METHOD_SET) {
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
mthca_update_rate(to_mdev(ibdev), port_num);
update_sm_ah(to_mdev(ibdev), port_num,
be16_to_cpup((__be16 *) (mad->data + 58)),
(*(u8 *) (mad->data + 76)) & 0xf);
Expand Down Expand Up @@ -246,6 +271,7 @@ int mthca_create_agents(struct mthca_dev *dev)
{
struct ib_mad_agent *agent;
int p, q;
int ret;

spin_lock_init(&dev->sm_lock);

Expand All @@ -255,11 +281,23 @@ int mthca_create_agents(struct mthca_dev *dev)
q ? IB_QPT_GSI : IB_QPT_SMI,
NULL, 0, send_handler,
NULL, NULL);
if (IS_ERR(agent))
if (IS_ERR(agent)) {
ret = PTR_ERR(agent);
goto err;
}
dev->send_agent[p][q] = agent;
}


for (p = 1; p <= dev->limits.num_ports; ++p) {
ret = mthca_update_rate(dev, p);
if (ret) {
mthca_err(dev, "Failed to obtain port %d rate."
" aborting.\n", p);
goto err;
}
}

return 0;

err:
Expand All @@ -268,7 +306,7 @@ int mthca_create_agents(struct mthca_dev *dev)
if (dev->send_agent[p][q])
ib_unregister_mad_agent(dev->send_agent[p][q]);

return PTR_ERR(agent);
return ret;
}

void __devexit mthca_free_agents(struct mthca_dev *dev)
Expand Down
Loading

0 comments on commit 907d91d

Please sign in to comment.