2005-11-08 06:30:29

by Roland Dreier

[permalink] [raw]
Subject: [git patch review 1/6] [IB] mthca: report page size capability

Report the device's real page size capability in mthca_query_device().

Signed-off-by: Jack Morgenstein <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>

---

drivers/infiniband/hw/mthca/mthca_dev.h | 1 +
drivers/infiniband/hw/mthca/mthca_main.c | 1 +
drivers/infiniband/hw/mthca/mthca_provider.c | 1 +
3 files changed, 3 insertions(+), 0 deletions(-)

applies-to: c403b29783de27e290b5d12f12054d03f96ce8b2
0f69ce1e4474e5d5e266457e8a1f4166cf71f6c7
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index e7e5d3b..808037f 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -154,6 +154,7 @@ struct mthca_limits {
int reserved_mcgs;
int num_pds;
int reserved_pds;
+ u32 page_size_cap;
u32 flags;
u8 port_width_cap;
};
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 45c6328..16594d1 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -181,6 +181,7 @@ static int __devinit mthca_dev_lim(struc
mdev->limits.reserved_uars = dev_lim->reserved_uars;
mdev->limits.reserved_pds = dev_lim->reserved_pds;
mdev->limits.port_width_cap = dev_lim->max_port_width;
+ mdev->limits.page_size_cap = ~(u32) (dev_lim->min_page_sz - 1);
mdev->limits.flags = dev_lim->flags;

/* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 6b01666..e78259b 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -90,6 +90,7 @@ static int mthca_query_device(struct ib_
memcpy(&props->node_guid, out_mad->data + 12, 8);

props->max_mr_size = ~0ull;
+ props->page_size_cap = mdev->limits.page_size_cap;
props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps;
props->max_qp_wr = mdev->limits.max_wqes;
props->max_sge = mdev->limits.max_sg;
---
0.99.9e


2005-11-08 06:30:28

by Roland Dreier

[permalink] [raw]
Subject: [git patch review 6/6] [IB] mthca: fix typo in catastrophic error polling

Fix a typo in the rearming of the catastrophic error polling timer: we
should rearm the timer as long as the stop flag is _not_ set.

Signed-off-by: Roland Dreier <[email protected]>

---

drivers/infiniband/hw/mthca/mthca_catas.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 35085d3edccfc4f18930f45c4a1c896d041e7856
b523cfbb7bab356f66525e518f5b8c25cf0357d7
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index 7ac52af..3447cd7 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -94,7 +94,7 @@ static void poll_catas(unsigned long dev
}

spin_lock_irqsave(&catas_lock, flags);
- if (dev->catas_err.stop)
+ if (!dev->catas_err.stop)
mod_timer(&dev->catas_err.timer,
jiffies + MTHCA_CATAS_POLL_INTERVAL);
spin_unlock_irqrestore(&catas_lock, flags);
---
0.99.9e

2005-11-08 06:30:53

by Roland Dreier

[permalink] [raw]
Subject: [git patch review 5/6] [IPoIB] no need to set skb->dev right before freeing skb

For cut-and-paste reasons, the IPoIB driver was setting skb->dev right
before calling dev_kfree_skb_any(). Get rid of this.

Signed-off-by: Roland Dreier <[email protected]>

---

drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 17 ++++-------------
1 files changed, 4 insertions(+), 13 deletions(-)

applies-to: 8b16a6a547ff0459044c3698ff9ac1d33c84eaf4
6277da1d7c70d2fcaeeb74c3b20fc1645da0f1fe
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 8709693..c33ed87 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -120,12 +120,8 @@ static void ipoib_mcast_free(struct ipoi
if (mcast->ah)
ipoib_put_ah(mcast->ah);

- while (!skb_queue_empty(&mcast->pkt_queue)) {
- struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
-
- skb->dev = dev;
- dev_kfree_skb_any(skb);
- }
+ while (!skb_queue_empty(&mcast->pkt_queue))
+ dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));

kfree(mcast);
}
@@ -317,13 +313,8 @@ ipoib_mcast_sendonly_join_complete(int s
IPOIB_GID_ARG(mcast->mcmember.mgid), status);

/* Flush out any queued packets */
- while (!skb_queue_empty(&mcast->pkt_queue)) {
- struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
-
- skb->dev = dev;
-
- dev_kfree_skb_any(skb);
- }
+ while (!skb_queue_empty(&mcast->pkt_queue))
+ dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));

/* Clear the busy flag so we try again */
clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
---
0.99.9e

2005-11-08 06:30:54

by Roland Dreier

[permalink] [raw]
Subject: [git patch review 2/6] [IB] umad: two small fixes

Two small fixes for the umad module:
- set kobject name for issm device properly
- in ib_umad_add_one(), s is subtracted from the index i when
initializing ports, so s should be subtracted from the index when
freeing ports in the error path as well.

Signed-off-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>

---

drivers/infiniband/core/user_mad.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

applies-to: ea857a2670e77bd8e8e8538f42504bcaa1a515d5
8b37b94721533f2729c79bcb6fa0bb3e2bc2f400
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index aed5ca2..6aefeed 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -801,7 +801,7 @@ static int ib_umad_init_port(struct ib_d
goto err_class;
port->sm_dev->owner = THIS_MODULE;
port->sm_dev->ops = &umad_sm_fops;
- kobject_set_name(&port->dev->kobj, "issm%d", port->dev_num);
+ kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num);
if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
goto err_sm_cdev;

@@ -913,7 +913,7 @@ static void ib_umad_add_one(struct ib_de

err:
while (--i >= s)
- ib_umad_kill_port(&umad_dev->port[i]);
+ ib_umad_kill_port(&umad_dev->port[i - s]);

kref_put(&umad_dev->ref, ib_umad_release_dev);
}
---
0.99.9e

2005-11-08 06:31:53

by Roland Dreier

[permalink] [raw]
Subject: [git patch review 4/6] [IB] umad: avoid potential deadlock when unregistering MAD agents

ib_unregister_mad_agent() completes all pending MAD sends and waits
for the agent's send_handler routine to return. umad's send_handler()
calls queue_packet(), which does down_read() on the port mutex to look
up the agent ID. This means that the port mutex cannot be held for
writing while calling ib_unregister_mad_agent(), or else it will
deadlock. This patch fixes all the calls to ib_unregister_mad_agent()
in the umad module to avoid this deadlock.

Signed-off-by: Roland Dreier <[email protected]>

---

drivers/infiniband/core/user_mad.c | 29 +++++++++++++++++------------
1 files changed, 17 insertions(+), 12 deletions(-)

applies-to: 69df1437f2ab467ff8bdd28a9282a3af19daa119
85e28883ef956d40b4aac3fc81ff39ac19713541
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 6aefeed..f5ed36c 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -505,8 +505,6 @@ found:
goto out;
}

- file->agent[agent_id] = agent;
-
file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(file->mr[agent_id])) {
ret = -ENOMEM;
@@ -519,14 +517,15 @@ found:
goto err_mr;
}

+ file->agent[agent_id] = agent;
ret = 0;
+
goto out;

err_mr:
ib_dereg_mr(file->mr[agent_id]);

err:
- file->agent[agent_id] = NULL;
ib_unregister_mad_agent(agent);

out:
@@ -536,27 +535,33 @@ out:

static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg)
{
+ struct ib_mad_agent *agent = NULL;
+ struct ib_mr *mr = NULL;
u32 id;
int ret = 0;

- down_write(&file->port->mutex);
+ if (get_user(id, (u32 __user *) arg))
+ return -EFAULT;

- if (get_user(id, (u32 __user *) arg)) {
- ret = -EFAULT;
- goto out;
- }
+ down_write(&file->port->mutex);

if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) {
ret = -EINVAL;
goto out;
}

- ib_dereg_mr(file->mr[id]);
- ib_unregister_mad_agent(file->agent[id]);
+ agent = file->agent[id];
+ mr = file->mr[id];
file->agent[id] = NULL;

out:
up_write(&file->port->mutex);
+
+ if (agent) {
+ ib_unregister_mad_agent(agent);
+ ib_dereg_mr(mr);
+ }
+
return ret;
}

@@ -623,16 +628,16 @@ static int ib_umad_close(struct inode *i
struct ib_umad_packet *packet, *tmp;
int i;

- down_write(&file->port->mutex);
for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
if (file->agent[i]) {
- ib_dereg_mr(file->mr[i]);
ib_unregister_mad_agent(file->agent[i]);
+ ib_dereg_mr(file->mr[i]);
}

list_for_each_entry_safe(packet, tmp, &file->recv_list, list)
kfree(packet);

+ down_write(&file->port->mutex);
list_del(&file->port_list);
up_write(&file->port->mutex);

---
0.99.9e

2005-11-08 06:30:58

by Roland Dreier

[permalink] [raw]
Subject: [git patch review 3/6] [IPoIB] add path record information in debugfs

Add ibX_path files to debugfs that contain information about the IPoIB
path cache. IPoIB ARP only gives GIDs, which the IPoIB driver must
resolve to real IB paths through the ib_sa module. For debugging,
when the ARP table looks OK but traffic isn't flowing, it's useful to
be able to see if the resolution from GID to path worked.

Also clean up the formatting of the existing _mcg debugfs files.

Signed-off-by: Roland Dreier <[email protected]>

---

drivers/infiniband/ulp/ipoib/ipoib.h | 15 +-
drivers/infiniband/ulp/ipoib/ipoib_fs.c | 179 +++++++++++++++++++++---
drivers/infiniband/ulp/ipoib/ipoib_main.c | 72 +++++++++-
drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 9 -
drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 7 -
5 files changed, 233 insertions(+), 49 deletions(-)

applies-to: f681c9c9ea858c5b14f593077e7cadf9e93ad255
3924a6898a88a805d6297029f0705743cbfff587
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 0095acc..9923a15 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -179,6 +179,7 @@ struct ipoib_dev_priv {
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
struct list_head fs_list;
struct dentry *mcg_dentry;
+ struct dentry *path_dentry;
#endif
};

@@ -270,7 +271,6 @@ void ipoib_mcast_dev_flush(struct net_de

#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
-void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter);
int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
union ib_gid *gid,
@@ -278,6 +278,11 @@ void ipoib_mcast_iter_read(struct ipoib_
unsigned int *queuelen,
unsigned int *complete,
unsigned int *send_only);
+
+struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev);
+int ipoib_path_iter_next(struct ipoib_path_iter *iter);
+void ipoib_path_iter_read(struct ipoib_path_iter *iter,
+ struct ipoib_path *path);
#endif

int ipoib_mcast_attach(struct net_device *dev, u16 mlid,
@@ -299,13 +304,13 @@ void ipoib_pkey_poll(void *dev);
int ipoib_pkey_dev_delay_open(struct net_device *dev);

#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
-int ipoib_create_debug_file(struct net_device *dev);
-void ipoib_delete_debug_file(struct net_device *dev);
+void ipoib_create_debug_files(struct net_device *dev);
+void ipoib_delete_debug_files(struct net_device *dev);
int ipoib_register_debugfs(void);
void ipoib_unregister_debugfs(void);
#else
-static inline int ipoib_create_debug_file(struct net_device *dev) { return 0; }
-static inline void ipoib_delete_debug_file(struct net_device *dev) { }
+static inline void ipoib_create_debug_files(struct net_device *dev) { }
+static inline void ipoib_delete_debug_files(struct net_device *dev) { }
static inline int ipoib_register_debugfs(void) { return 0; }
static inline void ipoib_unregister_debugfs(void) { }
#endif
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index 38b150f..a5b8bb4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -43,6 +43,18 @@ struct file_operations;

static struct dentry *ipoib_root;

+static void format_gid(union ib_gid *gid, char *buf)
+{
+ int i, n;
+
+ for (n = 0, i = 0; i < 8; ++i) {
+ n += sprintf(buf + n, "%x",
+ be16_to_cpu(((__be16 *) gid->raw)[i]));
+ if (i < 7)
+ buf[n++] = ':';
+ }
+}
+
static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
{
struct ipoib_mcast_iter *iter;
@@ -54,7 +66,7 @@ static void *ipoib_mcg_seq_start(struct

while (n--) {
if (ipoib_mcast_iter_next(iter)) {
- ipoib_mcast_iter_free(iter);
+ kfree(iter);
return NULL;
}
}
@@ -70,7 +82,7 @@ static void *ipoib_mcg_seq_next(struct s
(*pos)++;

if (ipoib_mcast_iter_next(iter)) {
- ipoib_mcast_iter_free(iter);
+ kfree(iter);
return NULL;
}

@@ -91,28 +103,29 @@ static int ipoib_mcg_seq_show(struct seq
unsigned long created;
unsigned int queuelen, complete, send_only;

- if (iter) {
- ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
- &complete, &send_only);
-
- for (n = 0, i = 0; i < sizeof mgid / 2; ++i) {
- n += sprintf(gid_buf + n, "%x",
- be16_to_cpu(((__be16 *) mgid.raw)[i]));
- if (i < sizeof mgid / 2 - 1)
- gid_buf[n++] = ':';
- }
- }
+ if (!iter)
+ return 0;
+
+ ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
+ &complete, &send_only);

- seq_printf(file, "GID: %*s", -(1 + (int) sizeof gid_buf), gid_buf);
+ format_git(&mgid, gid_buf);

seq_printf(file,
- " created: %10ld queuelen: %4d complete: %d send_only: %d\n",
- created, queuelen, complete, send_only);
+ "GID: %s\n"
+ " created: %10ld\n"
+ " queuelen: %9d\n"
+ " complete: %9s\n"
+ " send_only: %8s\n"
+ "\n",
+ gid_buf, created, queuelen,
+ complete ? "yes" : "no",
+ send_only ? "yes" : "no");

return 0;
}

-static struct seq_operations ipoib_seq_ops = {
+static struct seq_operations ipoib_mcg_seq_ops = {
.start = ipoib_mcg_seq_start,
.next = ipoib_mcg_seq_next,
.stop = ipoib_mcg_seq_stop,
@@ -124,7 +137,7 @@ static int ipoib_mcg_open(struct inode *
struct seq_file *seq;
int ret;

- ret = seq_open(file, &ipoib_seq_ops);
+ ret = seq_open(file, &ipoib_mcg_seq_ops);
if (ret)
return ret;

@@ -134,7 +147,7 @@ static int ipoib_mcg_open(struct inode *
return 0;
}

-static struct file_operations ipoib_fops = {
+static struct file_operations ipoib_mcg_fops = {
.owner = THIS_MODULE,
.open = ipoib_mcg_open,
.read = seq_read,
@@ -142,25 +155,139 @@ static struct file_operations ipoib_fops
.release = seq_release
};

-int ipoib_create_debug_file(struct net_device *dev)
+static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
+{
+ struct ipoib_path_iter *iter;
+ loff_t n = *pos;
+
+ iter = ipoib_path_iter_init(file->private);
+ if (!iter)
+ return NULL;
+
+ while (n--) {
+ if (ipoib_path_iter_next(iter)) {
+ kfree(iter);
+ return NULL;
+ }
+ }
+
+ return iter;
+}
+
+static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
+ loff_t *pos)
+{
+ struct ipoib_path_iter *iter = iter_ptr;
+
+ (*pos)++;
+
+ if (ipoib_path_iter_next(iter)) {
+ kfree(iter);
+ return NULL;
+ }
+
+ return iter;
+}
+
+static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
+{
+ /* nothing for now */
+}
+
+static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
+{
+ struct ipoib_path_iter *iter = iter_ptr;
+ char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+ struct ipoib_path path;
+ int i, n;
+ int rate;
+
+ if (!iter)
+ return 0;
+
+ ipoib_path_iter_read(iter, &path);
+
+ format_git(&path.pathrec.dgid, gid_buf);
+
+ seq_printf(file,
+ "GID: %s\n"
+ " complete: %6s\n",
+ gid_buf, path.pathrec.dlid ? "yes" : "no");
+
+ if (path.pathrec.dlid) {
+ rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25;
+
+ seq_printf(file,
+ " DLID: 0x%04x\n"
+ " SL: %12d\n"
+ " rate: %*d%s Gb/sec\n",
+ be16_to_cpu(path.pathrec.dlid),
+ path.pathrec.sl,
+ 10 - ((rate % 10) ? 2 : 0),
+ rate / 10, rate % 10 ? ".5" : "");
+ }
+
+ seq_putc(file, '\n');
+
+ return 0;
+}
+
+static struct seq_operations ipoib_path_seq_ops = {
+ .start = ipoib_path_seq_start,
+ .next = ipoib_path_seq_next,
+ .stop = ipoib_path_seq_stop,
+ .show = ipoib_path_seq_show,
+};
+
+static int ipoib_path_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int ret;
+
+ ret = seq_open(file, &ipoib_path_seq_ops);
+ if (ret)
+ return ret;
+
+ seq = file->private_data;
+ seq->private = inode->u.generic_ip;
+
+ return 0;
+}
+
+static struct file_operations ipoib_path_fops = {
+ .owner = THIS_MODULE,
+ .open = ipoib_path_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+void ipoib_create_debug_files(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
- char name[IFNAMSIZ + sizeof "_mcg"];
+ char name[IFNAMSIZ + sizeof "_path"];

snprintf(name, sizeof name, "%s_mcg", dev->name);
-
priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
- ipoib_root, dev, &ipoib_fops);
-
- return priv->mcg_dentry ? 0 : -ENOMEM;
+ ipoib_root, dev, &ipoib_mcg_fops);
+ if (!priv->mcg_dentry)
+ ipoib_warn(priv, "failed to create mcg debug file\n");
+
+ snprintf(name, sizeof name, "%s_path", dev->name);
+ priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+ ipoib_root, dev, &ipoib_path_fops);
+ if (!priv->path_dentry)
+ ipoib_warn(priv, "failed to create path debug file\n");
}

-void ipoib_delete_debug_file(struct net_device *dev)
+void ipoib_delete_debug_files(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);

if (priv->mcg_dentry)
debugfs_remove(priv->mcg_dentry);
+ if (priv->path_dentry)
+ debugfs_remove(priv->path_dentry);
}

int ipoib_register_debugfs(void)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ce02962..2fa3075 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -58,6 +58,11 @@ module_param_named(debug_level, ipoib_de
MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
#endif

+struct ipoib_path_iter {
+ struct net_device *dev;
+ struct ipoib_path path;
+};
+
static const u8 ipv4_bcast_addr[] = {
0x00, 0xff, 0xff, 0xff,
0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
@@ -250,6 +255,64 @@ static void path_free(struct net_device
kfree(path);
}

+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+
+struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev)
+{
+ struct ipoib_path_iter *iter;
+
+ iter = kmalloc(sizeof *iter, GFP_KERNEL);
+ if (!iter)
+ return NULL;
+
+ iter->dev = dev;
+ memset(iter->path.pathrec.dgid.raw, 0, 16);
+
+ if (ipoib_path_iter_next(iter)) {
+ kfree(iter);
+ return NULL;
+ }
+
+ return iter;
+}
+
+int ipoib_path_iter_next(struct ipoib_path_iter *iter)
+{
+ struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
+ struct rb_node *n;
+ struct ipoib_path *path;
+ int ret = 1;
+
+ spin_lock_irq(&priv->lock);
+
+ n = rb_first(&priv->path_tree);
+
+ while (n) {
+ path = rb_entry(n, struct ipoib_path, rb_node);
+
+ if (memcmp(iter->path.pathrec.dgid.raw, path->pathrec.dgid.raw,
+ sizeof (union ib_gid)) < 0) {
+ iter->path = *path;
+ ret = 0;
+ break;
+ }
+
+ n = rb_next(n);
+ }
+
+ spin_unlock_irq(&priv->lock);
+
+ return ret;
+}
+
+void ipoib_path_iter_read(struct ipoib_path_iter *iter,
+ struct ipoib_path *path)
+{
+ *path = iter->path;
+}
+
+#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
+
void ipoib_flush_paths(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -763,7 +826,7 @@ void ipoib_dev_cleanup(struct net_device
{
struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv;

- ipoib_delete_debug_file(dev);
+ ipoib_delete_debug_files(dev);

/* Delete any child interfaces first */
list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
@@ -972,8 +1035,7 @@ static struct net_device *ipoib_add_port
goto register_failed;
}

- if (ipoib_create_debug_file(priv->dev))
- goto debug_failed;
+ ipoib_create_debug_files(priv->dev);

if (ipoib_add_pkey_attr(priv->dev))
goto sysfs_failed;
@@ -987,9 +1049,7 @@ static struct net_device *ipoib_add_port
return priv->dev;

sysfs_failed:
- ipoib_delete_debug_file(priv->dev);
-
-debug_failed:
+ ipoib_delete_debug_files(priv->dev);
unregister_netdev(priv->dev);

register_failed:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 3ecf78a..8709693 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -928,21 +928,16 @@ struct ipoib_mcast_iter *ipoib_mcast_ite
return NULL;

iter->dev = dev;
- memset(iter->mgid.raw, 0, sizeof iter->mgid);
+ memset(iter->mgid.raw, 0, 16);

if (ipoib_mcast_iter_next(iter)) {
- ipoib_mcast_iter_free(iter);
+ kfree(iter);
return NULL;
}

return iter;
}

-void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter)
-{
- kfree(iter);
-}
-
int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter)
{
struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 332d730..d280b34 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -113,8 +113,7 @@ int ipoib_vlan_add(struct net_device *pd

priv->parent = ppriv->dev;

- if (ipoib_create_debug_file(priv->dev))
- goto debug_failed;
+ ipoib_create_debug_files(priv->dev);

if (ipoib_add_pkey_attr(priv->dev))
goto sysfs_failed;
@@ -130,9 +129,7 @@ int ipoib_vlan_add(struct net_device *pd
return 0;

sysfs_failed:
- ipoib_delete_debug_file(priv->dev);
-
-debug_failed:
+ ipoib_delete_debug_files(priv->dev);
unregister_netdev(priv->dev);

register_failed:
---
0.99.9e