aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/mad.c10
-rw-r--r--drivers/infiniband/core/sa_query.c2
-rw-r--r--drivers/infiniband/core/ucm.c13
-rw-r--r--drivers/infiniband/core/uverbs_main.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c51
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mcg.c20
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c36
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.h7
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c53
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c20
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h5
17 files changed, 148 insertions, 105 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index d393b504bf26..c82f47a66e48 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -665,7 +665,15 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
665 struct ib_wc mad_wc; 665 struct ib_wc mad_wc;
666 struct ib_send_wr *send_wr = &mad_send_wr->send_wr; 666 struct ib_send_wr *send_wr = &mad_send_wr->send_wr;
667 667
668 if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) { 668 /*
669 * Directed route handling starts if the initial LID routed part of
670 * a request or the ending LID routed part of a response is empty.
671 * If we are at the start of the LID routed part, don't update the
672 * hop_ptr or hop_cnt. See section 14.2.2, Vol 1 IB spec.
673 */
674 if ((ib_get_smp_direction(smp) ? smp->dr_dlid : smp->dr_slid) ==
675 IB_LID_PERMISSIVE &&
676 !smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
669 ret = -EINVAL; 677 ret = -EINVAL;
670 printk(KERN_ERR PFX "Invalid directed route\n"); 678 printk(KERN_ERR PFX "Invalid directed route\n");
671 goto out; 679 goto out;
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index acda7d63d6fe..501cc054cb3b 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -956,6 +956,8 @@ static void ib_sa_remove_one(struct ib_device *device)
956 956
957 ib_unregister_event_handler(&sa_dev->event_handler); 957 ib_unregister_event_handler(&sa_dev->event_handler);
958 958
959 flush_scheduled_work();
960
959 for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) { 961 for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
960 ib_unregister_mad_agent(sa_dev->port[i].agent); 962 ib_unregister_mad_agent(sa_dev->port[i].agent);
961 kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah); 963 kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index e95c4293a496..f6a05965a4e8 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -1319,15 +1319,6 @@ static struct class ucm_class = {
1319 .release = ib_ucm_release_class_dev 1319 .release = ib_ucm_release_class_dev
1320}; 1320};
1321 1321
1322static ssize_t show_dev(struct class_device *class_dev, char *buf)
1323{
1324 struct ib_ucm_device *dev;
1325
1326 dev = container_of(class_dev, struct ib_ucm_device, class_dev);
1327 return print_dev_t(buf, dev->dev.dev);
1328}
1329static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
1330
1331static ssize_t show_ibdev(struct class_device *class_dev, char *buf) 1322static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
1332{ 1323{
1333 struct ib_ucm_device *dev; 1324 struct ib_ucm_device *dev;
@@ -1364,15 +1355,13 @@ static void ib_ucm_add_one(struct ib_device *device)
1364 1355
1365 ucm_dev->class_dev.class = &ucm_class; 1356 ucm_dev->class_dev.class = &ucm_class;
1366 ucm_dev->class_dev.dev = device->dma_device; 1357 ucm_dev->class_dev.dev = device->dma_device;
1358 ucm_dev->class_dev.devt = ucm_dev->dev.dev;
1367 snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", 1359 snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",
1368 ucm_dev->devnum); 1360 ucm_dev->devnum);
1369 if (class_device_register(&ucm_dev->class_dev)) 1361 if (class_device_register(&ucm_dev->class_dev))
1370 goto err_cdev; 1362 goto err_cdev;
1371 1363
1372 if (class_device_create_file(&ucm_dev->class_dev, 1364 if (class_device_create_file(&ucm_dev->class_dev,
1373 &class_device_attr_dev))
1374 goto err_class;
1375 if (class_device_create_file(&ucm_dev->class_dev,
1376 &class_device_attr_ibdev)) 1365 &class_device_attr_ibdev))
1377 goto err_class; 1366 goto err_class;
1378 1367
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 96ea79b63df7..903f85a4bc0c 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -902,6 +902,7 @@ static void __exit ib_uverbs_cleanup(void)
902 unregister_filesystem(&uverbs_event_fs); 902 unregister_filesystem(&uverbs_event_fs);
903 class_destroy(uverbs_class); 903 class_destroy(uverbs_class);
904 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); 904 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
905 flush_scheduled_work();
905 idr_destroy(&ib_uverbs_pd_idr); 906 idr_destroy(&ib_uverbs_pd_idr);
906 idr_destroy(&ib_uverbs_mr_idr); 907 idr_destroy(&ib_uverbs_mr_idr);
907 idr_destroy(&ib_uverbs_mw_idr); 908 idr_destroy(&ib_uverbs_mw_idr);
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index a14eed08a0fc..a19e0ed03d7c 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -184,7 +184,7 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
184 ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff); 184 ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff);
185 ib_get_cached_gid(&dev->ib_dev, 185 ib_get_cached_gid(&dev->ib_dev,
186 be32_to_cpu(ah->av->port_pd) >> 24, 186 be32_to_cpu(ah->av->port_pd) >> 24,
187 ah->av->gid_index, 187 ah->av->gid_index % dev->limits.gid_table_len,
188 &header->grh.source_gid); 188 &header->grh.source_gid);
189 memcpy(header->grh.destination_gid.raw, 189 memcpy(header->grh.destination_gid.raw,
190 ah->av->dgid, 16); 190 ah->av->dgid, 16);
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index be1791be627b..2825615ce81c 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -199,8 +199,7 @@ static int mthca_cmd_post(struct mthca_dev *dev,
199{ 199{
200 int err = 0; 200 int err = 0;
201 201
202 if (down_interruptible(&dev->cmd.hcr_sem)) 202 mutex_lock(&dev->cmd.hcr_mutex);
203 return -EINTR;
204 203
205 if (event) { 204 if (event) {
206 unsigned long end = jiffies + GO_BIT_TIMEOUT; 205 unsigned long end = jiffies + GO_BIT_TIMEOUT;
@@ -238,7 +237,7 @@ static int mthca_cmd_post(struct mthca_dev *dev,
238 op), dev->hcr + 6 * 4); 237 op), dev->hcr + 6 * 4);
239 238
240out: 239out:
241 up(&dev->cmd.hcr_sem); 240 mutex_unlock(&dev->cmd.hcr_mutex);
242 return err; 241 return err;
243} 242}
244 243
@@ -255,8 +254,7 @@ static int mthca_cmd_poll(struct mthca_dev *dev,
255 int err = 0; 254 int err = 0;
256 unsigned long end; 255 unsigned long end;
257 256
258 if (down_interruptible(&dev->cmd.poll_sem)) 257 down(&dev->cmd.poll_sem);
259 return -EINTR;
260 258
261 err = mthca_cmd_post(dev, in_param, 259 err = mthca_cmd_post(dev, in_param,
262 out_param ? *out_param : 0, 260 out_param ? *out_param : 0,
@@ -333,8 +331,7 @@ static int mthca_cmd_wait(struct mthca_dev *dev,
333 int err = 0; 331 int err = 0;
334 struct mthca_cmd_context *context; 332 struct mthca_cmd_context *context;
335 333
336 if (down_interruptible(&dev->cmd.event_sem)) 334 down(&dev->cmd.event_sem);
337 return -EINTR;
338 335
339 spin_lock(&dev->cmd.context_lock); 336 spin_lock(&dev->cmd.context_lock);
340 BUG_ON(dev->cmd.free_head < 0); 337 BUG_ON(dev->cmd.free_head < 0);
@@ -438,7 +435,7 @@ static int mthca_cmd_imm(struct mthca_dev *dev,
438 435
439int mthca_cmd_init(struct mthca_dev *dev) 436int mthca_cmd_init(struct mthca_dev *dev)
440{ 437{
441 sema_init(&dev->cmd.hcr_sem, 1); 438 mutex_init(&dev->cmd.hcr_mutex);
442 sema_init(&dev->cmd.poll_sem, 1); 439 sema_init(&dev->cmd.poll_sem, 1);
443 dev->cmd.use_events = 0; 440 dev->cmd.use_events = 0;
444 441
@@ -1032,25 +1029,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1032 MTHCA_GET(size, outbox, QUERY_DEV_LIM_UAR_ENTRY_SZ_OFFSET); 1029 MTHCA_GET(size, outbox, QUERY_DEV_LIM_UAR_ENTRY_SZ_OFFSET);
1033 dev_lim->uar_scratch_entry_sz = size; 1030 dev_lim->uar_scratch_entry_sz = size;
1034 1031
1035 mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n",
1036 dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz);
1037 mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n",
1038 dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz);
1039 mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n",
1040 dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz);
1041 mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n",
1042 dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz);
1043 mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n",
1044 dev_lim->reserved_mrws, dev_lim->reserved_mtts);
1045 mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n",
1046 dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars);
1047 mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n",
1048 dev_lim->max_pds, dev_lim->reserved_mgms);
1049 mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n",
1050 dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz);
1051
1052 mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
1053
1054 if (mthca_is_memfree(dev)) { 1032 if (mthca_is_memfree(dev)) {
1055 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); 1033 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
1056 dev_lim->max_srq_sz = 1 << field; 1034 dev_lim->max_srq_sz = 1 << field;
@@ -1096,6 +1074,25 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1096 dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; 1074 dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE;
1097 } 1075 }
1098 1076
1077 mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n",
1078 dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz);
1079 mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n",
1080 dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz);
1081 mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n",
1082 dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz);
1083 mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n",
1084 dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz);
1085 mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n",
1086 dev_lim->reserved_mrws, dev_lim->reserved_mtts);
1087 mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n",
1088 dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars);
1089 mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n",
1090 dev_lim->max_pds, dev_lim->reserved_mgms);
1091 mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n",
1092 dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz);
1093
1094 mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
1095
1099out: 1096out:
1100 mthca_free_mailbox(dev, mailbox); 1097 mthca_free_mailbox(dev, mailbox);
1101 return err; 1098 return err;
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index a104ab041ea3..e481037288d6 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -44,6 +44,8 @@
44#include <linux/pci.h> 44#include <linux/pci.h>
45#include <linux/dma-mapping.h> 45#include <linux/dma-mapping.h>
46#include <linux/timer.h> 46#include <linux/timer.h>
47#include <linux/mutex.h>
48
47#include <asm/semaphore.h> 49#include <asm/semaphore.h>
48 50
49#include "mthca_provider.h" 51#include "mthca_provider.h"
@@ -51,8 +53,8 @@
51 53
52#define DRV_NAME "ib_mthca" 54#define DRV_NAME "ib_mthca"
53#define PFX DRV_NAME ": " 55#define PFX DRV_NAME ": "
54#define DRV_VERSION "0.06" 56#define DRV_VERSION "0.07"
55#define DRV_RELDATE "June 23, 2005" 57#define DRV_RELDATE "February 13, 2006"
56 58
57enum { 59enum {
58 MTHCA_FLAG_DDR_HIDDEN = 1 << 1, 60 MTHCA_FLAG_DDR_HIDDEN = 1 << 1,
@@ -111,7 +113,7 @@ enum {
111struct mthca_cmd { 113struct mthca_cmd {
112 struct pci_pool *pool; 114 struct pci_pool *pool;
113 int use_events; 115 int use_events;
114 struct semaphore hcr_sem; 116 struct mutex hcr_mutex;
115 struct semaphore poll_sem; 117 struct semaphore poll_sem;
116 struct semaphore event_sem; 118 struct semaphore event_sem;
117 int max_cmds; 119 int max_cmds;
@@ -256,7 +258,7 @@ struct mthca_av_table {
256}; 258};
257 259
258struct mthca_mcg_table { 260struct mthca_mcg_table {
259 struct semaphore sem; 261 struct mutex mutex;
260 struct mthca_alloc alloc; 262 struct mthca_alloc alloc;
261 struct mthca_icm_table *table; 263 struct mthca_icm_table *table;
262}; 264};
@@ -301,7 +303,7 @@ struct mthca_dev {
301 u64 ddr_end; 303 u64 ddr_end;
302 304
303 MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock) 305 MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock)
304 struct semaphore cap_mask_mutex; 306 struct mutex cap_mask_mutex;
305 307
306 void __iomem *hcr; 308 void __iomem *hcr;
307 void __iomem *kar; 309 void __iomem *kar;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 8b00d9a0f6f4..9c849d27b06e 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -155,6 +155,13 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
155 return -ENODEV; 155 return -ENODEV;
156 } 156 }
157 157
158 if (dev_lim->uar_size > pci_resource_len(mdev->pdev, 2)) {
159 mthca_err(mdev, "HCA reported UAR size of 0x%x bigger than "
160 "PCI resource 2 size of 0x%lx, aborting.\n",
161 dev_lim->uar_size, pci_resource_len(mdev->pdev, 2));
162 return -ENODEV;
163 }
164
158 mdev->limits.num_ports = dev_lim->num_ports; 165 mdev->limits.num_ports = dev_lim->num_ports;
159 mdev->limits.vl_cap = dev_lim->max_vl; 166 mdev->limits.vl_cap = dev_lim->max_vl;
160 mdev->limits.mtu_cap = dev_lim->max_mtu; 167 mdev->limits.mtu_cap = dev_lim->max_mtu;
@@ -976,8 +983,7 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
976 err = -ENODEV; 983 err = -ENODEV;
977 goto err_disable_pdev; 984 goto err_disable_pdev;
978 } 985 }
979 if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM) || 986 if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
980 pci_resource_len(pdev, 2) != 1 << 23) {
981 dev_err(&pdev->dev, "Missing UAR, aborting.\n"); 987 dev_err(&pdev->dev, "Missing UAR, aborting.\n");
982 err = -ENODEV; 988 err = -ENODEV;
983 goto err_disable_pdev; 989 goto err_disable_pdev;
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
index 77bc6c746f43..321f11e707f2 100644
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -154,10 +154,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
154 return PTR_ERR(mailbox); 154 return PTR_ERR(mailbox);
155 mgm = mailbox->buf; 155 mgm = mailbox->buf;
156 156
157 if (down_interruptible(&dev->mcg_table.sem)) { 157 mutex_lock(&dev->mcg_table.mutex);
158 err = -EINTR;
159 goto err_sem;
160 }
161 158
162 err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); 159 err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
163 if (err) 160 if (err)
@@ -241,8 +238,8 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
241 BUG_ON(index < dev->limits.num_mgms); 238 BUG_ON(index < dev->limits.num_mgms);
242 mthca_free(&dev->mcg_table.alloc, index); 239 mthca_free(&dev->mcg_table.alloc, index);
243 } 240 }
244 up(&dev->mcg_table.sem); 241 mutex_unlock(&dev->mcg_table.mutex);
245 err_sem: 242
246 mthca_free_mailbox(dev, mailbox); 243 mthca_free_mailbox(dev, mailbox);
247 return err; 244 return err;
248} 245}
@@ -263,10 +260,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
263 return PTR_ERR(mailbox); 260 return PTR_ERR(mailbox);
264 mgm = mailbox->buf; 261 mgm = mailbox->buf;
265 262
266 if (down_interruptible(&dev->mcg_table.sem)) { 263 mutex_lock(&dev->mcg_table.mutex);
267 err = -EINTR;
268 goto err_sem;
269 }
270 264
271 err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); 265 err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
272 if (err) 266 if (err)
@@ -371,8 +365,8 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
371 } 365 }
372 366
373 out: 367 out:
374 up(&dev->mcg_table.sem); 368 mutex_unlock(&dev->mcg_table.mutex);
375 err_sem: 369
376 mthca_free_mailbox(dev, mailbox); 370 mthca_free_mailbox(dev, mailbox);
377 return err; 371 return err;
378} 372}
@@ -389,7 +383,7 @@ int __devinit mthca_init_mcg_table(struct mthca_dev *dev)
389 if (err) 383 if (err)
390 return err; 384 return err;
391 385
392 init_MUTEX(&dev->mcg_table.sem); 386 mutex_init(&dev->mcg_table.mutex);
393 387
394 return 0; 388 return 0;
395} 389}
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 9fb985a016e9..d709cb162a72 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -50,7 +50,7 @@ enum {
50}; 50};
51 51
52struct mthca_user_db_table { 52struct mthca_user_db_table {
53 struct semaphore mutex; 53 struct mutex mutex;
54 struct { 54 struct {
55 u64 uvirt; 55 u64 uvirt;
56 struct scatterlist mem; 56 struct scatterlist mem;
@@ -158,7 +158,7 @@ int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int ob
158 int ret = 0; 158 int ret = 0;
159 u8 status; 159 u8 status;
160 160
161 down(&table->mutex); 161 mutex_lock(&table->mutex);
162 162
163 if (table->icm[i]) { 163 if (table->icm[i]) {
164 ++table->icm[i]->refcount; 164 ++table->icm[i]->refcount;
@@ -184,7 +184,7 @@ int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int ob
184 ++table->icm[i]->refcount; 184 ++table->icm[i]->refcount;
185 185
186out: 186out:
187 up(&table->mutex); 187 mutex_unlock(&table->mutex);
188 return ret; 188 return ret;
189} 189}
190 190
@@ -198,7 +198,7 @@ void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int o
198 198
199 i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE; 199 i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE;
200 200
201 down(&table->mutex); 201 mutex_lock(&table->mutex);
202 202
203 if (--table->icm[i]->refcount == 0) { 203 if (--table->icm[i]->refcount == 0) {
204 mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE, 204 mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE,
@@ -207,7 +207,7 @@ void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int o
207 table->icm[i] = NULL; 207 table->icm[i] = NULL;
208 } 208 }
209 209
210 up(&table->mutex); 210 mutex_unlock(&table->mutex);
211} 211}
212 212
213void *mthca_table_find(struct mthca_icm_table *table, int obj) 213void *mthca_table_find(struct mthca_icm_table *table, int obj)
@@ -220,7 +220,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj)
220 if (!table->lowmem) 220 if (!table->lowmem)
221 return NULL; 221 return NULL;
222 222
223 down(&table->mutex); 223 mutex_lock(&table->mutex);
224 224
225 idx = (obj & (table->num_obj - 1)) * table->obj_size; 225 idx = (obj & (table->num_obj - 1)) * table->obj_size;
226 icm = table->icm[idx / MTHCA_TABLE_CHUNK_SIZE]; 226 icm = table->icm[idx / MTHCA_TABLE_CHUNK_SIZE];
@@ -240,7 +240,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj)
240 } 240 }
241 241
242out: 242out:
243 up(&table->mutex); 243 mutex_unlock(&table->mutex);
244 return page ? lowmem_page_address(page) + offset : NULL; 244 return page ? lowmem_page_address(page) + offset : NULL;
245} 245}
246 246
@@ -301,7 +301,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
301 table->num_obj = nobj; 301 table->num_obj = nobj;
302 table->obj_size = obj_size; 302 table->obj_size = obj_size;
303 table->lowmem = use_lowmem; 303 table->lowmem = use_lowmem;
304 init_MUTEX(&table->mutex); 304 mutex_init(&table->mutex);
305 305
306 for (i = 0; i < num_icm; ++i) 306 for (i = 0; i < num_icm; ++i)
307 table->icm[i] = NULL; 307 table->icm[i] = NULL;
@@ -380,7 +380,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
380 if (index < 0 || index > dev->uar_table.uarc_size / 8) 380 if (index < 0 || index > dev->uar_table.uarc_size / 8)
381 return -EINVAL; 381 return -EINVAL;
382 382
383 down(&db_tab->mutex); 383 mutex_lock(&db_tab->mutex);
384 384
385 i = index / MTHCA_DB_REC_PER_PAGE; 385 i = index / MTHCA_DB_REC_PER_PAGE;
386 386
@@ -424,7 +424,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
424 db_tab->page[i].refcount = 1; 424 db_tab->page[i].refcount = 1;
425 425
426out: 426out:
427 up(&db_tab->mutex); 427 mutex_unlock(&db_tab->mutex);
428 return ret; 428 return ret;
429} 429}
430 430
@@ -439,11 +439,11 @@ void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
439 * pages until we clean up the whole db table. 439 * pages until we clean up the whole db table.
440 */ 440 */
441 441
442 down(&db_tab->mutex); 442 mutex_lock(&db_tab->mutex);
443 443
444 --db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount; 444 --db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount;
445 445
446 up(&db_tab->mutex); 446 mutex_unlock(&db_tab->mutex);
447} 447}
448 448
449struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) 449struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev)
@@ -460,7 +460,7 @@ struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev)
460 if (!db_tab) 460 if (!db_tab)
461 return ERR_PTR(-ENOMEM); 461 return ERR_PTR(-ENOMEM);
462 462
463 init_MUTEX(&db_tab->mutex); 463 mutex_init(&db_tab->mutex);
464 for (i = 0; i < npages; ++i) { 464 for (i = 0; i < npages; ++i) {
465 db_tab->page[i].refcount = 0; 465 db_tab->page[i].refcount = 0;
466 db_tab->page[i].uvirt = 0; 466 db_tab->page[i].uvirt = 0;
@@ -499,7 +499,7 @@ int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
499 int ret = 0; 499 int ret = 0;
500 u8 status; 500 u8 status;
501 501
502 down(&dev->db_tab->mutex); 502 mutex_lock(&dev->db_tab->mutex);
503 503
504 switch (type) { 504 switch (type) {
505 case MTHCA_DB_TYPE_CQ_ARM: 505 case MTHCA_DB_TYPE_CQ_ARM:
@@ -585,7 +585,7 @@ found:
585 *db = (__be32 *) &page->db_rec[j]; 585 *db = (__be32 *) &page->db_rec[j];
586 586
587out: 587out:
588 up(&dev->db_tab->mutex); 588 mutex_unlock(&dev->db_tab->mutex);
589 589
590 return ret; 590 return ret;
591} 591}
@@ -601,7 +601,7 @@ void mthca_free_db(struct mthca_dev *dev, int type, int db_index)
601 601
602 page = dev->db_tab->page + i; 602 page = dev->db_tab->page + i;
603 603
604 down(&dev->db_tab->mutex); 604 mutex_lock(&dev->db_tab->mutex);
605 605
606 page->db_rec[j] = 0; 606 page->db_rec[j] = 0;
607 if (i >= dev->db_tab->min_group2) 607 if (i >= dev->db_tab->min_group2)
@@ -624,7 +624,7 @@ void mthca_free_db(struct mthca_dev *dev, int type, int db_index)
624 ++dev->db_tab->min_group2; 624 ++dev->db_tab->min_group2;
625 } 625 }
626 626
627 up(&dev->db_tab->mutex); 627 mutex_unlock(&dev->db_tab->mutex);
628} 628}
629 629
630int mthca_init_db_tab(struct mthca_dev *dev) 630int mthca_init_db_tab(struct mthca_dev *dev)
@@ -638,7 +638,7 @@ int mthca_init_db_tab(struct mthca_dev *dev)
638 if (!dev->db_tab) 638 if (!dev->db_tab)
639 return -ENOMEM; 639 return -ENOMEM;
640 640
641 init_MUTEX(&dev->db_tab->mutex); 641 mutex_init(&dev->db_tab->mutex);
642 642
643 dev->db_tab->npages = dev->uar_table.uarc_size / 4096; 643 dev->db_tab->npages = dev->uar_table.uarc_size / 4096;
644 dev->db_tab->max_group1 = 0; 644 dev->db_tab->max_group1 = 0;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
index 4fdca26eea85..36f1141a08aa 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -39,8 +39,7 @@
39 39
40#include <linux/list.h> 40#include <linux/list.h>
41#include <linux/pci.h> 41#include <linux/pci.h>
42 42#include <linux/mutex.h>
43#include <asm/semaphore.h>
44 43
45#define MTHCA_ICM_CHUNK_LEN \ 44#define MTHCA_ICM_CHUNK_LEN \
46 ((256 - sizeof (struct list_head) - 2 * sizeof (int)) / \ 45 ((256 - sizeof (struct list_head) - 2 * sizeof (int)) / \
@@ -64,7 +63,7 @@ struct mthca_icm_table {
64 int num_obj; 63 int num_obj;
65 int obj_size; 64 int obj_size;
66 int lowmem; 65 int lowmem;
67 struct semaphore mutex; 66 struct mutex mutex;
68 struct mthca_icm *icm[0]; 67 struct mthca_icm *icm[0];
69}; 68};
70 69
@@ -147,7 +146,7 @@ struct mthca_db_table {
147 int max_group1; 146 int max_group1;
148 int min_group2; 147 int min_group2;
149 struct mthca_db_page *page; 148 struct mthca_db_page *page;
150 struct semaphore mutex; 149 struct mutex mutex;
151}; 150};
152 151
153enum mthca_db_type { 152enum mthca_db_type {
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 484a7e6b7f8c..e88e39aef85a 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -185,7 +185,7 @@ static int mthca_modify_port(struct ib_device *ibdev,
185 int err; 185 int err;
186 u8 status; 186 u8 status;
187 187
188 if (down_interruptible(&to_mdev(ibdev)->cap_mask_mutex)) 188 if (mutex_lock_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
189 return -ERESTARTSYS; 189 return -ERESTARTSYS;
190 190
191 err = mthca_query_port(ibdev, port, &attr); 191 err = mthca_query_port(ibdev, port, &attr);
@@ -207,7 +207,7 @@ static int mthca_modify_port(struct ib_device *ibdev,
207 } 207 }
208 208
209out: 209out:
210 up(&to_mdev(ibdev)->cap_mask_mutex); 210 mutex_unlock(&to_mdev(ibdev)->cap_mask_mutex);
211 return err; 211 return err;
212} 212}
213 213
@@ -1185,7 +1185,7 @@ int mthca_register_device(struct mthca_dev *dev)
1185 dev->ib_dev.post_recv = mthca_tavor_post_receive; 1185 dev->ib_dev.post_recv = mthca_tavor_post_receive;
1186 } 1186 }
1187 1187
1188 init_MUTEX(&dev->cap_mask_mutex); 1188 mutex_init(&dev->cap_mask_mutex);
1189 1189
1190 ret = ib_register_device(&dev->ib_dev); 1190 ret = ib_register_device(&dev->ib_dev);
1191 if (ret) 1191 if (ret)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index e0a5412b7e68..2f85a9a831b1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -78,6 +78,7 @@ enum {
78 IPOIB_FLAG_SUBINTERFACE = 4, 78 IPOIB_FLAG_SUBINTERFACE = 4,
79 IPOIB_MCAST_RUN = 5, 79 IPOIB_MCAST_RUN = 5,
80 IPOIB_STOP_REAPER = 6, 80 IPOIB_STOP_REAPER = 6,
81 IPOIB_MCAST_STARTED = 7,
81 82
82 IPOIB_MAX_BACKOFF_SECONDS = 16, 83 IPOIB_MAX_BACKOFF_SECONDS = 16,
83 84
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index fd3f5c862a5d..c3b5f79d1168 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -505,7 +505,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
505 505
506 list_add_tail(&neigh->list, &path->neigh_list); 506 list_add_tail(&neigh->list, &path->neigh_list);
507 507
508 if (path->pathrec.dlid) { 508 if (path->ah) {
509 kref_get(&path->ah->ref); 509 kref_get(&path->ah->ref);
510 neigh->ah = path->ah; 510 neigh->ah = path->ah;
511 511
@@ -591,7 +591,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
591 return; 591 return;
592 } 592 }
593 593
594 if (path->pathrec.dlid) { 594 if (path->ah) {
595 ipoib_dbg(priv, "Send unicast ARP to %04x\n", 595 ipoib_dbg(priv, "Send unicast ARP to %04x\n",
596 be16_to_cpu(path->pathrec.dlid)); 596 be16_to_cpu(path->pathrec.dlid));
597 597
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 98039da0caf0..a2408d7ec598 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -97,6 +97,7 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
97 struct ipoib_dev_priv *priv = netdev_priv(dev); 97 struct ipoib_dev_priv *priv = netdev_priv(dev);
98 struct ipoib_neigh *neigh, *tmp; 98 struct ipoib_neigh *neigh, *tmp;
99 unsigned long flags; 99 unsigned long flags;
100 int tx_dropped = 0;
100 101
101 ipoib_dbg_mcast(netdev_priv(dev), 102 ipoib_dbg_mcast(netdev_priv(dev),
102 "deleting multicast group " IPOIB_GID_FMT "\n", 103 "deleting multicast group " IPOIB_GID_FMT "\n",
@@ -123,8 +124,14 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
123 if (mcast->ah) 124 if (mcast->ah)
124 ipoib_put_ah(mcast->ah); 125 ipoib_put_ah(mcast->ah);
125 126
126 while (!skb_queue_empty(&mcast->pkt_queue)) 127 while (!skb_queue_empty(&mcast->pkt_queue)) {
128 ++tx_dropped;
127 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); 129 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
130 }
131
132 spin_lock_irqsave(&priv->tx_lock, flags);
133 priv->stats.tx_dropped += tx_dropped;
134 spin_unlock_irqrestore(&priv->tx_lock, flags);
128 135
129 kfree(mcast); 136 kfree(mcast);
130} 137}
@@ -276,8 +283,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
276 } 283 }
277 284
278 /* actually send any queued packets */ 285 /* actually send any queued packets */
286 spin_lock_irq(&priv->tx_lock);
279 while (!skb_queue_empty(&mcast->pkt_queue)) { 287 while (!skb_queue_empty(&mcast->pkt_queue)) {
280 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 288 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
289 spin_unlock_irq(&priv->tx_lock);
281 290
282 skb->dev = dev; 291 skb->dev = dev;
283 292
@@ -288,7 +297,9 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
288 297
289 if (dev_queue_xmit(skb)) 298 if (dev_queue_xmit(skb))
290 ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n"); 299 ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n");
300 spin_lock_irq(&priv->tx_lock);
291 } 301 }
302 spin_unlock_irq(&priv->tx_lock);
292 303
293 return 0; 304 return 0;
294} 305}
@@ -300,6 +311,7 @@ ipoib_mcast_sendonly_join_complete(int status,
300{ 311{
301 struct ipoib_mcast *mcast = mcast_ptr; 312 struct ipoib_mcast *mcast = mcast_ptr;
302 struct net_device *dev = mcast->dev; 313 struct net_device *dev = mcast->dev;
314 struct ipoib_dev_priv *priv = netdev_priv(dev);
303 315
304 if (!status) 316 if (!status)
305 ipoib_mcast_join_finish(mcast, mcmember); 317 ipoib_mcast_join_finish(mcast, mcmember);
@@ -310,8 +322,12 @@ ipoib_mcast_sendonly_join_complete(int status,
310 IPOIB_GID_ARG(mcast->mcmember.mgid), status); 322 IPOIB_GID_ARG(mcast->mcmember.mgid), status);
311 323
312 /* Flush out any queued packets */ 324 /* Flush out any queued packets */
313 while (!skb_queue_empty(&mcast->pkt_queue)) 325 spin_lock_irq(&priv->tx_lock);
326 while (!skb_queue_empty(&mcast->pkt_queue)) {
327 ++priv->stats.tx_dropped;
314 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); 328 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
329 }
330 spin_unlock_irq(&priv->tx_lock);
315 331
316 /* Clear the busy flag so we try again */ 332 /* Clear the busy flag so we try again */
317 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); 333 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
@@ -517,8 +533,10 @@ void ipoib_mcast_join_task(void *dev_ptr)
517 } 533 }
518 534
519 if (!priv->broadcast) { 535 if (!priv->broadcast) {
520 priv->broadcast = ipoib_mcast_alloc(dev, 1); 536 struct ipoib_mcast *broadcast;
521 if (!priv->broadcast) { 537
538 broadcast = ipoib_mcast_alloc(dev, 1);
539 if (!broadcast) {
522 ipoib_warn(priv, "failed to allocate broadcast group\n"); 540 ipoib_warn(priv, "failed to allocate broadcast group\n");
523 mutex_lock(&mcast_mutex); 541 mutex_lock(&mcast_mutex);
524 if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) 542 if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
@@ -528,10 +546,11 @@ void ipoib_mcast_join_task(void *dev_ptr)
528 return; 546 return;
529 } 547 }
530 548
531 memcpy(priv->broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, 549 spin_lock_irq(&priv->lock);
550 memcpy(broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4,
532 sizeof (union ib_gid)); 551 sizeof (union ib_gid));
552 priv->broadcast = broadcast;
533 553
534 spin_lock_irq(&priv->lock);
535 __ipoib_mcast_add(dev, priv->broadcast); 554 __ipoib_mcast_add(dev, priv->broadcast);
536 spin_unlock_irq(&priv->lock); 555 spin_unlock_irq(&priv->lock);
537 } 556 }
@@ -585,6 +604,10 @@ int ipoib_mcast_start_thread(struct net_device *dev)
585 queue_work(ipoib_workqueue, &priv->mcast_task); 604 queue_work(ipoib_workqueue, &priv->mcast_task);
586 mutex_unlock(&mcast_mutex); 605 mutex_unlock(&mcast_mutex);
587 606
607 spin_lock_irq(&priv->lock);
608 set_bit(IPOIB_MCAST_STARTED, &priv->flags);
609 spin_unlock_irq(&priv->lock);
610
588 return 0; 611 return 0;
589} 612}
590 613
@@ -595,6 +618,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
595 618
596 ipoib_dbg_mcast(priv, "stopping multicast thread\n"); 619 ipoib_dbg_mcast(priv, "stopping multicast thread\n");
597 620
621 spin_lock_irq(&priv->lock);
622 clear_bit(IPOIB_MCAST_STARTED, &priv->flags);
623 spin_unlock_irq(&priv->lock);
624
598 mutex_lock(&mcast_mutex); 625 mutex_lock(&mcast_mutex);
599 clear_bit(IPOIB_MCAST_RUN, &priv->flags); 626 clear_bit(IPOIB_MCAST_RUN, &priv->flags);
600 cancel_delayed_work(&priv->mcast_task); 627 cancel_delayed_work(&priv->mcast_task);
@@ -677,6 +704,14 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
677 */ 704 */
678 spin_lock(&priv->lock); 705 spin_lock(&priv->lock);
679 706
707 if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) ||
708 !priv->broadcast ||
709 !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
710 ++priv->stats.tx_dropped;
711 dev_kfree_skb_any(skb);
712 goto unlock;
713 }
714
680 mcast = __ipoib_mcast_find(dev, mgid); 715 mcast = __ipoib_mcast_find(dev, mgid);
681 if (!mcast) { 716 if (!mcast) {
682 /* Let's create a new send only group now */ 717 /* Let's create a new send only group now */
@@ -687,6 +722,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
687 if (!mcast) { 722 if (!mcast) {
688 ipoib_warn(priv, "unable to allocate memory for " 723 ipoib_warn(priv, "unable to allocate memory for "
689 "multicast structure\n"); 724 "multicast structure\n");
725 ++priv->stats.tx_dropped;
690 dev_kfree_skb_any(skb); 726 dev_kfree_skb_any(skb);
691 goto out; 727 goto out;
692 } 728 }
@@ -700,8 +736,10 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
700 if (!mcast->ah) { 736 if (!mcast->ah) {
701 if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE) 737 if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE)
702 skb_queue_tail(&mcast->pkt_queue, skb); 738 skb_queue_tail(&mcast->pkt_queue, skb);
703 else 739 else {
740 ++priv->stats.tx_dropped;
704 dev_kfree_skb_any(skb); 741 dev_kfree_skb_any(skb);
742 }
705 743
706 if (mcast->query) 744 if (mcast->query)
707 ipoib_dbg_mcast(priv, "no address vector, " 745 ipoib_dbg_mcast(priv, "no address vector, "
@@ -735,6 +773,7 @@ out:
735 ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); 773 ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
736 } 774 }
737 775
776unlock:
738 spin_unlock(&priv->lock); 777 spin_unlock(&priv->lock);
739} 778}
740 779
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 31207e664148..960dae5c87d1 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -357,9 +357,9 @@ static void srp_remove_work(void *target_ptr)
357 target->state = SRP_TARGET_REMOVED; 357 target->state = SRP_TARGET_REMOVED;
358 spin_unlock_irq(target->scsi_host->host_lock); 358 spin_unlock_irq(target->scsi_host->host_lock);
359 359
360 down(&target->srp_host->target_mutex); 360 mutex_lock(&target->srp_host->target_mutex);
361 list_del(&target->list); 361 list_del(&target->list);
362 up(&target->srp_host->target_mutex); 362 mutex_unlock(&target->srp_host->target_mutex);
363 363
364 scsi_remove_host(target->scsi_host); 364 scsi_remove_host(target->scsi_host);
365 ib_destroy_cm_id(target->cm_id); 365 ib_destroy_cm_id(target->cm_id);
@@ -1155,6 +1155,12 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
1155 1155
1156 spin_lock_irq(target->scsi_host->host_lock); 1156 spin_lock_irq(target->scsi_host->host_lock);
1157 1157
1158 if (target->state == SRP_TARGET_DEAD ||
1159 target->state == SRP_TARGET_REMOVED) {
1160 scmnd->result = DID_BAD_TARGET << 16;
1161 goto out;
1162 }
1163
1158 if (scmnd->host_scribble == (void *) -1L) 1164 if (scmnd->host_scribble == (void *) -1L)
1159 goto out; 1165 goto out;
1160 1166
@@ -1254,9 +1260,9 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
1254 if (scsi_add_host(target->scsi_host, host->dev->dma_device)) 1260 if (scsi_add_host(target->scsi_host, host->dev->dma_device))
1255 return -ENODEV; 1261 return -ENODEV;
1256 1262
1257 down(&host->target_mutex); 1263 mutex_lock(&host->target_mutex);
1258 list_add_tail(&target->list, &host->target_list); 1264 list_add_tail(&target->list, &host->target_list);
1259 up(&host->target_mutex); 1265 mutex_unlock(&host->target_mutex);
1260 1266
1261 target->state = SRP_TARGET_LIVE; 1267 target->state = SRP_TARGET_LIVE;
1262 1268
@@ -1525,7 +1531,7 @@ static struct srp_host *srp_add_port(struct ib_device *device, u8 port)
1525 return NULL; 1531 return NULL;
1526 1532
1527 INIT_LIST_HEAD(&host->target_list); 1533 INIT_LIST_HEAD(&host->target_list);
1528 init_MUTEX(&host->target_mutex); 1534 mutex_init(&host->target_mutex);
1529 init_completion(&host->released); 1535 init_completion(&host->released);
1530 host->dev = device; 1536 host->dev = device;
1531 host->port = port; 1537 host->port = port;
@@ -1626,7 +1632,7 @@ static void srp_remove_one(struct ib_device *device)
1626 * Mark all target ports as removed, so we stop queueing 1632 * Mark all target ports as removed, so we stop queueing
1627 * commands and don't try to reconnect. 1633 * commands and don't try to reconnect.
1628 */ 1634 */
1629 down(&host->target_mutex); 1635 mutex_lock(&host->target_mutex);
1630 list_for_each_entry_safe(target, tmp_target, 1636 list_for_each_entry_safe(target, tmp_target,
1631 &host->target_list, list) { 1637 &host->target_list, list) {
1632 spin_lock_irqsave(target->scsi_host->host_lock, flags); 1638 spin_lock_irqsave(target->scsi_host->host_lock, flags);
@@ -1634,7 +1640,7 @@ static void srp_remove_one(struct ib_device *device)
1634 target->state = SRP_TARGET_REMOVED; 1640 target->state = SRP_TARGET_REMOVED;
1635 spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 1641 spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
1636 } 1642 }
1637 up(&host->target_mutex); 1643 mutex_unlock(&host->target_mutex);
1638 1644
1639 /* 1645 /*
1640 * Wait for any reconnection tasks that may have 1646 * Wait for any reconnection tasks that may have
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index b564f18caf78..4e7727df32f1 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -37,8 +37,7 @@
37 37
38#include <linux/types.h> 38#include <linux/types.h>
39#include <linux/list.h> 39#include <linux/list.h>
40 40#include <linux/mutex.h>
41#include <asm/semaphore.h>
42 41
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
44#include <scsi/scsi_cmnd.h> 43#include <scsi/scsi_cmnd.h>
@@ -85,7 +84,7 @@ struct srp_host {
85 struct ib_mr *mr; 84 struct ib_mr *mr;
86 struct class_device class_dev; 85 struct class_device class_dev;
87 struct list_head target_list; 86 struct list_head target_list;
88 struct semaphore target_mutex; 87 struct mutex target_mutex;
89 struct completion released; 88 struct completion released;
90 struct list_head list; 89 struct list_head list;
91}; 90};