diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/mad.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/core/sa_query.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/core/ucm.c | 13 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_av.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.c | 51 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_dev.h | 12 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_mcg.c | 20 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_memfree.c | 36 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_memfree.h | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_provider.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 53 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 20 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 5 |
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 | ||
1322 | static 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 | } | ||
1329 | static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); | ||
1330 | |||
1331 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) | 1322 | static 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 | ||
240 | out: | 239 | out: |
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 | ||
439 | int mthca_cmd_init(struct mthca_dev *dev) | 436 | int 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 | |||
1099 | out: | 1096 | out: |
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 | ||
57 | enum { | 59 | enum { |
58 | MTHCA_FLAG_DDR_HIDDEN = 1 << 1, | 60 | MTHCA_FLAG_DDR_HIDDEN = 1 << 1, |
@@ -111,7 +113,7 @@ enum { | |||
111 | struct mthca_cmd { | 113 | struct 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 | ||
258 | struct mthca_mcg_table { | 260 | struct 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 | ||
52 | struct mthca_user_db_table { | 52 | struct 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 | ||
186 | out: | 186 | out: |
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 | ||
213 | void *mthca_table_find(struct mthca_icm_table *table, int obj) | 213 | void *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 | ||
242 | out: | 242 | out: |
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 | ||
426 | out: | 426 | out: |
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 | ||
449 | struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) | 449 | struct 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 | ||
587 | out: | 587 | out: |
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 | ||
630 | int mthca_init_db_tab(struct mthca_dev *dev) | 630 | int 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 | ||
153 | enum mthca_db_type { | 152 | enum 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 | ||
209 | out: | 209 | out: |
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 | ||
776 | unlock: | ||
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 | }; |