From 6627fa662e86c400284b64c13661fdf6bff05983 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 9 Jan 2006 13:50:57 -0800 Subject: [PATCH 01/14] IB/mthca: fix page shift calculation in mthca_reg_phys_mr() For all pages except possibly the last one, the byte beyond the buffer end must be page aligned. Therefore, when computing the page shift to use, OR the end addresses of the buffers as well as the start addresses into the mask we check. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_provider.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 4cc7e2846df1..30b67c200267 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -783,24 +783,20 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd *pd, if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) return ERR_PTR(-EINVAL); - if (num_phys_buf > 1 && - ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK)) - return ERR_PTR(-EINVAL); - mask = 0; total_size = 0; for (i = 0; i < num_phys_buf; ++i) { - if (i != 0 && buffer_list[i].addr & ~PAGE_MASK) - return ERR_PTR(-EINVAL); - if (i != 0 && i != num_phys_buf - 1 && - (buffer_list[i].size & ~PAGE_MASK)) - return ERR_PTR(-EINVAL); + if (i != 0) + mask |= buffer_list[i].addr; + if (i != num_phys_buf - 1) + mask |= buffer_list[i].addr + buffer_list[i].size; total_size += buffer_list[i].size; - if (i > 0) - mask |= buffer_list[i].addr; } + if (mask & ~PAGE_MASK) + return ERR_PTR(-EINVAL); + /* Find largest page shift we can use to cover buffers */ for (shift = PAGE_SHIFT; shift < 31; ++shift) if (num_phys_buf > 1) { From 92898522e3ee1a0ba54140aad1974d9e868f74ae Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 9 Jan 2006 14:04:40 -0800 Subject: [PATCH 02/14] IB/mthca: prevent event queue overrun I am seeing EQ overruns in SDP stress tests: if the CQ completion handler arms a CQ, this could generate more EQEs, so that EQ will never get empty and consumer index will never get updated. This is similiar to what we have with command interface: /* * cmd_event() may add more commands. * The card will think the queue has overflowed if * we don't tell it we've been processing events. */ However, for completion events, we *don't* want to update the consumer index on each event. So, perform EQ doorbell coalescing: allocate EQs with some spare EQEs, and update once we run out of them. The value 0x80 was selected to avoid any performance impact. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_eq.c | 28 ++++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index e8a948f087c0..2eabb27804cd 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -45,6 +45,7 @@ enum { MTHCA_NUM_ASYNC_EQE = 0x80, MTHCA_NUM_CMD_EQE = 0x80, + MTHCA_NUM_SPARE_EQE = 0x80, MTHCA_EQ_ENTRY_SIZE = 0x20 }; @@ -277,11 +278,10 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) { struct mthca_eqe *eqe; int disarm_cqn; - int eqes_found = 0; + int eqes_found = 0; + int set_ci = 0; while ((eqe = next_eqe_sw(eq))) { - int set_ci = 0; - /* * Make sure we read EQ entry contents after we've * checked the ownership bit. @@ -345,12 +345,6 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) be16_to_cpu(eqe->event.cmd.token), eqe->event.cmd.status, be64_to_cpu(eqe->event.cmd.out_param)); - /* - * cmd_event() may add more commands. - * The card will think the queue has overflowed if - * we don't tell it we've been processing events. - */ - set_ci = 1; break; case MTHCA_EVENT_TYPE_PORT_CHANGE: @@ -385,8 +379,16 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) set_eqe_hw(eqe); ++eq->cons_index; eqes_found = 1; + ++set_ci; - if (unlikely(set_ci)) { + /* + * The HCA will think the queue has overflowed if we + * don't tell it we've been processing events. We + * create our EQs with MTHCA_NUM_SPARE_EQE extra + * entries, so we must update our consumer index at + * least that often. + */ + if (unlikely(set_ci >= MTHCA_NUM_SPARE_EQE)) { /* * Conditional on hca_type is OK here because * this is a rare case, not the fast path. @@ -862,19 +864,19 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev) intr = (dev->mthca_flags & MTHCA_FLAG_MSI) ? 128 : dev->eq_table.inta_pin; - err = mthca_create_eq(dev, dev->limits.num_cqs, + err = mthca_create_eq(dev, dev->limits.num_cqs + MTHCA_NUM_SPARE_EQE, (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr, &dev->eq_table.eq[MTHCA_EQ_COMP]); if (err) goto err_out_unmap; - err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE, + err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE + MTHCA_NUM_SPARE_EQE, (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 129 : intr, &dev->eq_table.eq[MTHCA_EQ_ASYNC]); if (err) goto err_out_comp; - err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE, + err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE + MTHCA_NUM_SPARE_EQE, (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 130 : intr, &dev->eq_table.eq[MTHCA_EQ_CMD]); if (err) From 105e50a5e8f184af31daffce4d7bfd7771fe213f Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 9 Jan 2006 15:21:21 -0800 Subject: [PATCH 03/14] IB/mthca: kzalloc conversions Convert kmalloc()/memset(,0,) pairs to kzalloc(). Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_provider.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 30b67c200267..0ae27fa26c7a 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -55,7 +55,7 @@ static int mthca_query_device(struct ib_device *ibdev, u8 status; - in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); + in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); if (!in_mad || !out_mad) goto out; @@ -64,7 +64,6 @@ static int mthca_query_device(struct ib_device *ibdev, props->fw_ver = mdev->fw_ver; - memset(in_mad, 0, sizeof *in_mad); in_mad->base_version = 1; in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; in_mad->class_version = 1; @@ -128,14 +127,13 @@ static int mthca_query_port(struct ib_device *ibdev, int err = -ENOMEM; u8 status; - in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); + in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); if (!in_mad || !out_mad) goto out; memset(props, 0, sizeof *props); - memset(in_mad, 0, sizeof *in_mad); in_mad->base_version = 1; in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; in_mad->class_version = 1; @@ -220,12 +218,11 @@ static int mthca_query_pkey(struct ib_device *ibdev, int err = -ENOMEM; u8 status; - in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); + in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); if (!in_mad || !out_mad) goto out; - memset(in_mad, 0, sizeof *in_mad); in_mad->base_version = 1; in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; in_mad->class_version = 1; @@ -259,12 +256,11 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port, int err = -ENOMEM; u8 status; - in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); + in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); if (!in_mad || !out_mad) goto out; - memset(in_mad, 0, sizeof *in_mad); in_mad->base_version = 1; in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; in_mad->class_version = 1; From 87635b71b544563f29050a9cecaa12b5d2a3e34a Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 9 Jan 2006 15:29:53 -0800 Subject: [PATCH 04/14] IB/mthca: Factor common MAD initialization code Factor out common code for initializing MAD packets, which is shared by many query routines in mthca_provider.c, into init_query_mad(). add/remove: 1/0 grow/shrink: 0/4 up/down: 16/-44 (-28) function old new delta init_query_mad - 16 +16 mthca_query_port 521 518 -3 mthca_query_pkey 301 294 -7 mthca_query_device 648 641 -7 mthca_query_gid 453 426 -27 Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_provider.c | 52 +++++++++----------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 0ae27fa26c7a..488757766a5d 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -45,6 +45,14 @@ #include "mthca_user.h" #include "mthca_memfree.h" +static void init_query_mad(struct ib_smp *mad) +{ + mad->base_version = 1; + mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; + mad->class_version = 1; + mad->method = IB_MGMT_METHOD_GET; +} + static int mthca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) { @@ -64,11 +72,8 @@ static int mthca_query_device(struct ib_device *ibdev, props->fw_ver = mdev->fw_ver; - in_mad->base_version = 1; - in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - in_mad->class_version = 1; - in_mad->method = IB_MGMT_METHOD_GET; - in_mad->attr_id = IB_SMP_ATTR_NODE_INFO; + init_query_mad(in_mad); + in_mad->attr_id = IB_SMP_ATTR_NODE_INFO; err = mthca_MAD_IFC(mdev, 1, 1, 1, NULL, NULL, in_mad, out_mad, @@ -134,12 +139,9 @@ static int mthca_query_port(struct ib_device *ibdev, memset(props, 0, sizeof *props); - in_mad->base_version = 1; - in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - in_mad->class_version = 1; - in_mad->method = IB_MGMT_METHOD_GET; - in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; - in_mad->attr_mod = cpu_to_be32(port); + init_query_mad(in_mad); + in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; + in_mad->attr_mod = cpu_to_be32(port); err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad, @@ -223,12 +225,9 @@ static int mthca_query_pkey(struct ib_device *ibdev, if (!in_mad || !out_mad) goto out; - in_mad->base_version = 1; - in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - in_mad->class_version = 1; - in_mad->method = IB_MGMT_METHOD_GET; - in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE; - in_mad->attr_mod = cpu_to_be32(index / 32); + init_query_mad(in_mad); + in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE; + in_mad->attr_mod = cpu_to_be32(index / 32); err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad, @@ -261,12 +260,9 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port, if (!in_mad || !out_mad) goto out; - in_mad->base_version = 1; - in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - in_mad->class_version = 1; - in_mad->method = IB_MGMT_METHOD_GET; - in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; - in_mad->attr_mod = cpu_to_be32(port); + init_query_mad(in_mad); + in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; + in_mad->attr_mod = cpu_to_be32(port); err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad, @@ -280,13 +276,9 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port, memcpy(gid->raw, out_mad->data + 8, 8); - memset(in_mad, 0, sizeof *in_mad); - in_mad->base_version = 1; - in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - in_mad->class_version = 1; - in_mad->method = IB_MGMT_METHOD_GET; - in_mad->attr_id = IB_SMP_ATTR_GUID_INFO; - in_mad->attr_mod = cpu_to_be32(index / 8); + init_query_mad(in_mad); + in_mad->attr_id = IB_SMP_ATTR_GUID_INFO; + in_mad->attr_mod = cpu_to_be32(index / 8); err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad, From cf311cd49a78f1e431787068cc31d29d06a415e6 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Tue, 10 Jan 2006 07:39:34 -0800 Subject: [PATCH 05/14] IB: Add node_guid to struct ib_device Add a node_guid field to struct ib_device. It is the responsibility of the low-level driver to initialize this field before registering a device with the midlayer. Convert everyone to looking at this field instead of calling ib_query_device() when all they want is the node GUID, and remove the node_guid field from struct ib_device_attr. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/cm.c | 29 +++----------- drivers/infiniband/core/sysfs.c | 22 +++-------- drivers/infiniband/core/uverbs_cmd.c | 2 +- drivers/infiniband/hw/mthca/mthca_provider.c | 40 +++++++++++++++++++- drivers/infiniband/ulp/srp/ib_srp.c | 23 ++--------- include/rdma/ib_verbs.h | 2 +- 6 files changed, 54 insertions(+), 64 deletions(-) diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 3a611fe5497e..c06b18102b6a 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -3163,22 +3163,6 @@ int ib_cm_init_qp_attr(struct ib_cm_id *cm_id, } EXPORT_SYMBOL(ib_cm_init_qp_attr); -static __be64 cm_get_ca_guid(struct ib_device *device) -{ - struct ib_device_attr *device_attr; - __be64 guid; - int ret; - - device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL); - if (!device_attr) - return 0; - - ret = ib_query_device(device, device_attr); - guid = ret ? 0 : device_attr->node_guid; - kfree(device_attr); - return guid; -} - static void cm_add_one(struct ib_device *device) { struct cm_device *cm_dev; @@ -3200,9 +3184,7 @@ static void cm_add_one(struct ib_device *device) return; cm_dev->device = device; - cm_dev->ca_guid = cm_get_ca_guid(device); - if (!cm_dev->ca_guid) - goto error1; + cm_dev->ca_guid = device->node_guid; set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask); for (i = 1; i <= device->phys_port_cnt; i++) { @@ -3217,11 +3199,11 @@ static void cm_add_one(struct ib_device *device) cm_recv_handler, port); if (IS_ERR(port->mad_agent)) - goto error2; + goto error1; ret = ib_modify_port(device, i, 0, &port_modify); if (ret) - goto error3; + goto error2; } ib_set_client_data(device, &cm_client, cm_dev); @@ -3230,9 +3212,9 @@ static void cm_add_one(struct ib_device *device) write_unlock_irqrestore(&cm.device_lock, flags); return; -error3: - ib_unregister_mad_agent(port->mad_agent); error2: + ib_unregister_mad_agent(port->mad_agent); +error1: port_modify.set_port_cap_mask = 0; port_modify.clr_port_cap_mask = IB_PORT_CM_SUP; while (--i) { @@ -3240,7 +3222,6 @@ static void cm_add_one(struct ib_device *device) ib_modify_port(device, port->port_num, 0, &port_modify); ib_unregister_mad_agent(port->mad_agent); } -error1: kfree(cm_dev); } diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 1f1743c5c9a3..5982d687a000 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -445,13 +445,7 @@ static int ib_device_uevent(struct class_device *cdev, char **envp, return -ENOMEM; /* - * It might be nice to pass the node GUID with the event, but - * right now the only way to get it is to query the device - * provider, and this can crash during device removal because - * we are will be running after driver removal has started. - * We could add a node_guid field to struct ib_device, or we - * could just let userspace read the node GUID from sysfs when - * devices are added. + * It would be nice to pass the node GUID with the event... */ envp[i] = NULL; @@ -623,21 +617,15 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf) static ssize_t show_node_guid(struct class_device *cdev, char *buf) { struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); - struct ib_device_attr attr; - ssize_t ret; if (!ibdev_is_alive(dev)) return -ENODEV; - ret = ib_query_device(dev, &attr); - if (ret) - return ret; - return sprintf(buf, "%04x:%04x:%04x:%04x\n", - be16_to_cpu(((__be16 *) &attr.node_guid)[0]), - be16_to_cpu(((__be16 *) &attr.node_guid)[1]), - be16_to_cpu(((__be16 *) &attr.node_guid)[2]), - be16_to_cpu(((__be16 *) &attr.node_guid)[3])); + be16_to_cpu(((__be16 *) &dev->node_guid)[0]), + be16_to_cpu(((__be16 *) &dev->node_guid)[1]), + be16_to_cpu(((__be16 *) &dev->node_guid)[2]), + be16_to_cpu(((__be16 *) &dev->node_guid)[3])); } static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index a02c5a05c984..554c2057b7c1 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -157,7 +157,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, memset(&resp, 0, sizeof resp); resp.fw_ver = attr.fw_ver; - resp.node_guid = attr.node_guid; + resp.node_guid = file->device->ib_dev->node_guid; resp.sys_image_guid = attr.sys_image_guid; resp.max_mr_size = attr.max_mr_size; resp.page_size_cap = attr.page_size_cap; diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 488757766a5d..db35690c91de 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -33,7 +33,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * $Id: mthca_provider.c 1397 2004-12-28 05:09:00Z roland $ + * $Id: mthca_provider.c 4859 2006-01-09 21:55:10Z roland $ */ #include @@ -91,7 +91,6 @@ static int mthca_query_device(struct ib_device *ibdev, props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30)); props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32)); memcpy(&props->sys_image_guid, out_mad->data + 4, 8); - memcpy(&props->node_guid, out_mad->data + 12, 8); props->max_mr_size = ~0ull; props->page_size_cap = mdev->limits.page_size_cap; @@ -1054,11 +1053,48 @@ static struct class_device_attribute *mthca_class_attributes[] = { &class_device_attr_board_id }; +static int mthca_init_node_data(struct mthca_dev *dev) +{ + struct ib_smp *in_mad = NULL; + struct ib_smp *out_mad = NULL; + int err = -ENOMEM; + u8 status; + + in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); + out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + if (!in_mad || !out_mad) + goto out; + + init_query_mad(in_mad); + in_mad->attr_id = IB_SMP_ATTR_NODE_INFO; + + err = mthca_MAD_IFC(dev, 1, 1, + 1, NULL, NULL, in_mad, out_mad, + &status); + if (err) + goto out; + if (status) { + err = -EINVAL; + goto out; + } + + memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8); + +out: + kfree(in_mad); + kfree(out_mad); + return err; +} + int mthca_register_device(struct mthca_dev *dev) { int ret; int i; + ret = mthca_init_node_data(dev); + if (ret) + return ret; + strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX); dev->ib_dev.owner = THIS_MODULE; diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index dd488d3cffa9..31207e664148 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1516,8 +1516,7 @@ static ssize_t show_port(struct class_device *class_dev, char *buf) static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); -static struct srp_host *srp_add_port(struct ib_device *device, - __be64 node_guid, u8 port) +static struct srp_host *srp_add_port(struct ib_device *device, u8 port) { struct srp_host *host; @@ -1532,7 +1531,7 @@ static struct srp_host *srp_add_port(struct ib_device *device, host->port = port; host->initiator_port_id[7] = port; - memcpy(host->initiator_port_id + 8, &node_guid, 8); + memcpy(host->initiator_port_id + 8, &device->node_guid, 8); host->pd = ib_alloc_pd(device); if (IS_ERR(host->pd)) @@ -1580,22 +1579,11 @@ static void srp_add_one(struct ib_device *device) { struct list_head *dev_list; struct srp_host *host; - struct ib_device_attr *dev_attr; int s, e, p; - dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); - if (!dev_attr) - return; - - if (ib_query_device(device, dev_attr)) { - printk(KERN_WARNING PFX "Couldn't query node GUID for %s.\n", - device->name); - goto out; - } - dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); if (!dev_list) - goto out; + return; INIT_LIST_HEAD(dev_list); @@ -1608,15 +1596,12 @@ static void srp_add_one(struct ib_device *device) } for (p = s; p <= e; ++p) { - host = srp_add_port(device, dev_attr->node_guid, p); + host = srp_add_port(device, p); if (host) list_add_tail(&host->list, dev_list); } ib_set_client_data(device, &srp_client, dev_list); - -out: - kfree(dev_attr); } static void srp_remove_one(struct ib_device *device) diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index a7f4c355a91f..22fc886b9695 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -88,7 +88,6 @@ enum ib_atomic_cap { struct ib_device_attr { u64 fw_ver; - __be64 node_guid; __be64 sys_image_guid; u64 max_mr_size; u64 page_size_cap; @@ -951,6 +950,7 @@ struct ib_device { u64 uverbs_cmd_mask; int uverbs_abi_ver; + __be64 node_guid; u8 node_type; u8 phys_port_cnt; }; From 70b4c8cdc168bb5d18e23fd205c4ede1b756a8b2 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Tue, 10 Jan 2006 07:42:14 -0800 Subject: [PATCH 06/14] IPoIB: Fix error path in ipoib_mcast_dev_flush() Don't leak memory on allocation failure for broadcast mcast group. Also, print a warning to match handling for other mcast groups. Signed-off-by: Eli Cohen Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ed0c2ead8bc1..6c6db759e79e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -780,9 +780,11 @@ void ipoib_mcast_dev_flush(struct net_device *dev) &priv->multicast_tree); list_add_tail(&priv->broadcast->list, &remove_list); - } - - priv->broadcast = nmcast; + priv->broadcast = nmcast; + } else + ipoib_warn(priv, "could not reallocate broadcast group " + IPOIB_GID_FMT "\n", + IPOIB_GID_ARG(priv->broadcast->mcmember.mgid)); } spin_unlock_irqrestore(&priv->lock, flags); From 97460df37ea3335ca11562568932c9f9facfecdb Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Tue, 10 Jan 2006 07:43:02 -0800 Subject: [PATCH 07/14] IPoIB: Fix address handle refcounting for multicast groups Multiple ipoib_neigh structures on mcast->neigh_list may point to the same ah. This means that ipoib_mcast_free() can't just make a list of ah structs to free, since this might end up trying to add the same ah to the list more than once. Handle this in ipoib_multicast.c in the same way as it is handled in ipoib_main.c for struct ipoib_path. Signed-off-by: Eli Cohen Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 6c6db759e79e..03b2ca64a40c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -97,8 +97,6 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_neigh *neigh, *tmp; unsigned long flags; - LIST_HEAD(ah_list); - struct ipoib_ah *ah, *tah; ipoib_dbg_mcast(netdev_priv(dev), "deleting multicast group " IPOIB_GID_FMT "\n", @@ -107,8 +105,14 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) spin_lock_irqsave(&priv->lock, flags); list_for_each_entry_safe(neigh, tmp, &mcast->neigh_list, list) { + /* + * It's safe to call ipoib_put_ah() inside priv->lock + * here, because we know that mcast->ah will always + * hold one more reference, so ipoib_put_ah() will + * never do more than decrement the ref count. + */ if (neigh->ah) - list_add_tail(&neigh->ah->list, &ah_list); + ipoib_put_ah(neigh->ah); *to_ipoib_neigh(neigh->neighbour) = NULL; neigh->neighbour->ops->destructor = NULL; kfree(neigh); @@ -116,9 +120,6 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) spin_unlock_irqrestore(&priv->lock, flags); - list_for_each_entry_safe(ah, tah, &ah_list, list) - ipoib_put_ah(ah); - if (mcast->ah) ipoib_put_ah(mcast->ah); From 78bfe0b5b67fe126ed98608e42e42fb6ed9aabd4 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 11 Jan 2006 11:47:34 -0800 Subject: [PATCH 08/14] IPoIB: Take dev->xmit_lock around mc_list accesses dev->mc_list accesses must be protected by dev->xmit_lock. Found by Eli Cohen . Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 03b2ca64a40c..bf1c08cca8cb 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -827,7 +827,8 @@ void ipoib_mcast_restart_task(void *dev_ptr) ipoib_mcast_stop_thread(dev, 0); - spin_lock_irqsave(&priv->lock, flags); + spin_lock_irqsave(&dev->xmit_lock, flags); + spin_lock(&priv->lock); /* * Unfortunately, the networking core only gives us a list of all of @@ -899,7 +900,9 @@ void ipoib_mcast_restart_task(void *dev_ptr) list_add_tail(&mcast->list, &remove_list); } } - spin_unlock_irqrestore(&priv->lock, flags); + + spin_unlock(&priv->lock); + spin_unlock_irqrestore(&dev->xmit_lock, flags); /* We have to cancel outside of the spinlock */ list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { From 988bd50300ef2e2d5cb8563e2ac99453dd9acd86 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Thu, 12 Jan 2006 14:32:20 -0800 Subject: [PATCH 09/14] IPoIB: Fix memory leak of multicast group structures The current handling of multicast groups in IPoIB ends up never freeing send-only multicast groups. It turns out the logic was much more complicated than it needed to be; we can fix this bug and completely kill ipoib_mcast_dev_down() at the same time. Signed-off-by: Eli Cohen Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 13 +--- .../infiniband/ulp/ipoib/ipoib_multicast.c | 61 +++---------------- 2 files changed, 9 insertions(+), 65 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 23885801b6d2..f7e848970794 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -453,17 +453,8 @@ int ipoib_ib_dev_down(struct net_device *dev) } ipoib_mcast_stop_thread(dev, 1); - - /* - * Flush the multicast groups first so we stop any multicast joins. The - * completion thread may have already died and we may deadlock waiting - * for the completion thread to finish some multicast joins. - */ ipoib_mcast_dev_flush(dev); - /* Delete broadcast and local addresses since they will be recreated */ - ipoib_mcast_dev_down(dev); - ipoib_flush_paths(dev); return 0; @@ -624,9 +615,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) ipoib_dbg(priv, "cleaning up ib_dev\n"); ipoib_mcast_stop_thread(dev, 1); - - /* Delete the broadcast address and the local address */ - ipoib_mcast_dev_down(dev); + ipoib_mcast_dev_flush(dev); ipoib_transport_dev_cleanup(dev); } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index bf1c08cca8cb..7403bac1977b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -742,50 +742,23 @@ void ipoib_mcast_dev_flush(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); LIST_HEAD(remove_list); - struct ipoib_mcast *mcast, *tmcast, *nmcast; + struct ipoib_mcast *mcast, *tmcast; unsigned long flags; ipoib_dbg_mcast(priv, "flushing multicast list\n"); spin_lock_irqsave(&priv->lock, flags); + list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) { - nmcast = ipoib_mcast_alloc(dev, 0); - if (nmcast) { - nmcast->flags = - mcast->flags & (1 << IPOIB_MCAST_FLAG_SENDONLY); - - nmcast->mcmember.mgid = mcast->mcmember.mgid; - - /* Add the new group in before the to-be-destroyed group */ - list_add_tail(&nmcast->list, &mcast->list); - list_del_init(&mcast->list); - - rb_replace_node(&mcast->rb_node, &nmcast->rb_node, - &priv->multicast_tree); - - list_add_tail(&mcast->list, &remove_list); - } else { - ipoib_warn(priv, "could not reallocate multicast group " - IPOIB_GID_FMT "\n", - IPOIB_GID_ARG(mcast->mcmember.mgid)); - } + list_del(&mcast->list); + rb_erase(&mcast->rb_node, &priv->multicast_tree); + list_add_tail(&mcast->list, &remove_list); } if (priv->broadcast) { - nmcast = ipoib_mcast_alloc(dev, 0); - if (nmcast) { - nmcast->mcmember.mgid = priv->broadcast->mcmember.mgid; - - rb_replace_node(&priv->broadcast->rb_node, - &nmcast->rb_node, - &priv->multicast_tree); - - list_add_tail(&priv->broadcast->list, &remove_list); - priv->broadcast = nmcast; - } else - ipoib_warn(priv, "could not reallocate broadcast group " - IPOIB_GID_FMT "\n", - IPOIB_GID_ARG(priv->broadcast->mcmember.mgid)); + rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree); + list_add_tail(&priv->broadcast->list, &remove_list); + priv->broadcast = NULL; } spin_unlock_irqrestore(&priv->lock, flags); @@ -796,24 +769,6 @@ void ipoib_mcast_dev_flush(struct net_device *dev) } } -void ipoib_mcast_dev_down(struct net_device *dev) -{ - struct ipoib_dev_priv *priv = netdev_priv(dev); - unsigned long flags; - - /* Delete broadcast since it will be recreated */ - if (priv->broadcast) { - ipoib_dbg_mcast(priv, "deleting broadcast group\n"); - - spin_lock_irqsave(&priv->lock, flags); - rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree); - spin_unlock_irqrestore(&priv->lock, flags); - ipoib_mcast_leave(dev, priv->broadcast); - ipoib_mcast_free(priv->broadcast); - priv->broadcast = NULL; - } -} - void ipoib_mcast_restart_task(void *dev_ptr) { struct net_device *dev = dev_ptr; From 59f174faffd5dfee709fa0ead320cc6daf827e93 Mon Sep 17 00:00:00 2001 From: Ishai Rabinovitz Date: Thu, 12 Jan 2006 15:24:51 -0800 Subject: [PATCH 10/14] IB/mthca: Fix memory leak of multicast group structures Convert "/ (1 << lg)" to ">> lg" for a slight code size reduction. add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-24 (-24) function old new delta mthca_map_cmd 613 589 -24 Signed-off-by: Ishai Rabinovitz Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 22ac72bc20c3..f69e4896eff0 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -606,7 +606,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, err = -EINVAL; goto out; } - for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) { + for (i = 0; i < mthca_icm_size(&iter) >> lg; ++i) { if (virt != -1) { pages[nent * 2] = cpu_to_be64(virt); virt += 1 << lg; From 17e2e819517d75f2f3407e59c5f7f6f0ef305d14 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Thu, 12 Jan 2006 15:35:15 -0800 Subject: [PATCH 11/14] IB/mthca: Fix memory leaks in error handling Fix memory leaks in mthca_create_qp() and mthca_create_srq() error handling. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_provider.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index db35690c91de..484a7e6b7f8c 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -445,8 +445,10 @@ static struct ib_srq *mthca_create_srq(struct ib_pd *pd, if (pd->uobject) { context = to_mucontext(pd->uobject->context); - if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) - return ERR_PTR(-EFAULT); + if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) { + err = -EFAULT; + goto err_free; + } err = mthca_map_user_db(to_mdev(pd->device), &context->uar, context->db_tab, ucmd.db_index, @@ -522,8 +524,10 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, if (pd->uobject) { context = to_mucontext(pd->uobject->context); - if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) + if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) { + kfree(qp); return ERR_PTR(-EFAULT); + } err = mthca_map_user_db(to_mdev(pd->device), &context->uar, context->db_tab, From c063a06835d3ccfa6c039d3a3869fcf22249c862 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 12 Jan 2006 15:43:58 -0800 Subject: [PATCH 12/14] IB/mthca: Cosmetic: use the ALIGN macro Use the ALIGN macro to simplify some rounding code. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_cmd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index f69e4896eff0..be1791be627b 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -727,8 +727,8 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) * system pages needed. */ dev->fw.arbel.fw_pages = - (dev->fw.arbel.fw_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> - (PAGE_SHIFT - 12); + ALIGN(dev->fw.arbel.fw_pages, PAGE_SIZE >> 12) >> + (PAGE_SHIFT - 12); mthca_dbg(dev, "Clear int @ %llx, EQ arm @ %llx, EQ set CI @ %llx\n", (unsigned long long) dev->fw.arbel.clr_int_base, @@ -1445,6 +1445,7 @@ int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages, * pages needed. */ *aux_pages = (*aux_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> (PAGE_SHIFT - 12); + *aux_pages = ALIGN(*aux_pages, PAGE_SIZE >> 12) >> (PAGE_SHIFT - 12); return 0; } From 9eacee2ac624bfa9740d49355dbe6ee88d0cba0a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 12 Jan 2006 15:55:41 -0800 Subject: [PATCH 13/14] IB/mthca: Initialize grh_present before using it build_mlx_header() was using sqp->ud_header.grh_present before it was initialized by mthca_read_ah(). Furthermore, header->grh_present is set by ib_ud_header_init, so there's no need to set it again in mthca_read_ah(). Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_av.c | 10 ++++++---- drivers/infiniband/hw/mthca/mthca_dev.h | 1 + drivers/infiniband/hw/mthca/mthca_qp.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c index 22fdc446f25c..a14eed08a0fc 100644 --- a/drivers/infiniband/hw/mthca/mthca_av.c +++ b/drivers/infiniband/hw/mthca/mthca_av.c @@ -163,6 +163,11 @@ int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah) return 0; } +int mthca_ah_grh_present(struct mthca_ah *ah) +{ + return !!(ah->av->g_slid & 0x80); +} + int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, struct ib_ud_header *header) { @@ -172,8 +177,7 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, header->lrh.service_level = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28; header->lrh.destination_lid = ah->av->dlid; header->lrh.source_lid = cpu_to_be16(ah->av->g_slid & 0x7f); - if (ah->av->g_slid & 0x80) { - header->grh_present = 1; + if (mthca_ah_grh_present(ah)) { header->grh.traffic_class = (be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff; header->grh.flow_label = @@ -184,8 +188,6 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, &header->grh.source_gid); memcpy(header->grh.destination_gid.raw, ah->av->dgid, 16); - } else { - header->grh_present = 0; } return 0; diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 795b379260bf..a104ab041ea3 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -520,6 +520,7 @@ int mthca_create_ah(struct mthca_dev *dev, int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah); int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, struct ib_ud_header *header); +int mthca_ah_grh_present(struct mthca_ah *ah); int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 564b6d51c394..fba608ed7df2 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -1434,7 +1434,7 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp, u16 pkey; ib_ud_header_init(256, /* assume a MAD */ - sqp->ud_header.grh_present, + mthca_ah_grh_present(to_mah(wr->wr.ud.ah)), &sqp->ud_header); err = mthca_read_ah(dev, to_mah(wr->wr.ud.ah), &sqp->ud_header); From 95ed644fd12f53c6fc778f3f246974e5fe3a9468 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 13 Jan 2006 14:51:39 -0800 Subject: [PATCH 14/14] IB: convert from semaphores to mutexes semaphore to mutex conversion by Ingo and Arjan's script. Signed-off-by: Ingo Molnar [ Sanity-checked on real IB hardware ] Signed-off-by: Roland Dreier --- drivers/infiniband/core/device.c | 23 ++- drivers/infiniband/core/ucm.c | 23 +-- drivers/infiniband/core/uverbs.h | 5 +- drivers/infiniband/core/uverbs_cmd.c | 150 +++++++++--------- drivers/infiniband/core/uverbs_main.c | 8 +- drivers/infiniband/ulp/ipoib/ipoib.h | 6 +- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 18 +-- drivers/infiniband/ulp/ipoib/ipoib_main.c | 12 +- .../infiniband/ulp/ipoib/ipoib_multicast.c | 26 +-- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 8 +- drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 10 +- 11 files changed, 145 insertions(+), 144 deletions(-) diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index e169e798354b..b2f3cb91d9bc 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -38,8 +38,7 @@ #include #include #include - -#include +#include #include "core_priv.h" @@ -57,13 +56,13 @@ static LIST_HEAD(device_list); static LIST_HEAD(client_list); /* - * device_sem protects access to both device_list and client_list. + * device_mutex protects access to both device_list and client_list. * There's no real point to using multiple locks or something fancier * like an rwsem: we always access both lists, and we're always * modifying one list or the other list. In any case this is not a * hot path so there's no point in trying to optimize. */ -static DECLARE_MUTEX(device_sem); +static DEFINE_MUTEX(device_mutex); static int ib_device_check_mandatory(struct ib_device *device) { @@ -221,7 +220,7 @@ int ib_register_device(struct ib_device *device) { int ret; - down(&device_sem); + mutex_lock(&device_mutex); if (strchr(device->name, '%')) { ret = alloc_name(device->name); @@ -259,7 +258,7 @@ int ib_register_device(struct ib_device *device) } out: - up(&device_sem); + mutex_unlock(&device_mutex); return ret; } EXPORT_SYMBOL(ib_register_device); @@ -276,7 +275,7 @@ void ib_unregister_device(struct ib_device *device) struct ib_client_data *context, *tmp; unsigned long flags; - down(&device_sem); + mutex_lock(&device_mutex); list_for_each_entry_reverse(client, &client_list, list) if (client->remove) @@ -284,7 +283,7 @@ void ib_unregister_device(struct ib_device *device) list_del(&device->core_list); - up(&device_sem); + mutex_unlock(&device_mutex); spin_lock_irqsave(&device->client_data_lock, flags); list_for_each_entry_safe(context, tmp, &device->client_data_list, list) @@ -312,14 +311,14 @@ int ib_register_client(struct ib_client *client) { struct ib_device *device; - down(&device_sem); + mutex_lock(&device_mutex); list_add_tail(&client->list, &client_list); list_for_each_entry(device, &device_list, core_list) if (client->add && !add_client_context(device, client)) client->add(device); - up(&device_sem); + mutex_unlock(&device_mutex); return 0; } @@ -339,7 +338,7 @@ void ib_unregister_client(struct ib_client *client) struct ib_device *device; unsigned long flags; - down(&device_sem); + mutex_lock(&device_mutex); list_for_each_entry(device, &device_list, core_list) { if (client->remove) @@ -355,7 +354,7 @@ void ib_unregister_client(struct ib_client *client) } list_del(&client->list); - up(&device_sem); + mutex_unlock(&device_mutex); } EXPORT_SYMBOL(ib_unregister_client); diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 6e15787d1de1..e95c4293a496 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -113,7 +114,7 @@ static struct ib_client ucm_client = { .remove = ib_ucm_remove_one }; -static DECLARE_MUTEX(ctx_id_mutex); +static DEFINE_MUTEX(ctx_id_mutex); static DEFINE_IDR(ctx_id_table); static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES); @@ -121,7 +122,7 @@ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) { struct ib_ucm_context *ctx; - down(&ctx_id_mutex); + mutex_lock(&ctx_id_mutex); ctx = idr_find(&ctx_id_table, id); if (!ctx) ctx = ERR_PTR(-ENOENT); @@ -129,7 +130,7 @@ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) ctx = ERR_PTR(-EINVAL); else atomic_inc(&ctx->ref); - up(&ctx_id_mutex); + mutex_unlock(&ctx_id_mutex); return ctx; } @@ -186,9 +187,9 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) if (!result) goto error; - down(&ctx_id_mutex); + mutex_lock(&ctx_id_mutex); result = idr_get_new(&ctx_id_table, ctx, &ctx->id); - up(&ctx_id_mutex); + mutex_unlock(&ctx_id_mutex); } while (result == -EAGAIN); if (result) @@ -550,9 +551,9 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file, err2: ib_destroy_cm_id(ctx->cm_id); err1: - down(&ctx_id_mutex); + mutex_lock(&ctx_id_mutex); idr_remove(&ctx_id_table, ctx->id); - up(&ctx_id_mutex); + mutex_unlock(&ctx_id_mutex); kfree(ctx); return result; } @@ -572,7 +573,7 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - down(&ctx_id_mutex); + mutex_lock(&ctx_id_mutex); ctx = idr_find(&ctx_id_table, cmd.id); if (!ctx) ctx = ERR_PTR(-ENOENT); @@ -580,7 +581,7 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file, ctx = ERR_PTR(-EINVAL); else idr_remove(&ctx_id_table, ctx->id); - up(&ctx_id_mutex); + mutex_unlock(&ctx_id_mutex); if (IS_ERR(ctx)) return PTR_ERR(ctx); @@ -1280,9 +1281,9 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) struct ib_ucm_context, file_list); up(&file->mutex); - down(&ctx_id_mutex); + mutex_lock(&ctx_id_mutex); idr_remove(&ctx_id_table, ctx->id); - up(&ctx_id_mutex); + mutex_unlock(&ctx_id_mutex); ib_destroy_cm_id(ctx->cm_id); ib_ucm_cleanup_events(ctx); diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 7114e3fbab00..f7eecbc6af6c 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -88,7 +89,7 @@ struct ib_uverbs_event_file { struct ib_uverbs_file { struct kref ref; - struct semaphore mutex; + struct mutex mutex; struct ib_uverbs_device *device; struct ib_ucontext *ucontext; struct ib_event_handler event_handler; @@ -131,7 +132,7 @@ struct ib_ucq_object { u32 async_events_reported; }; -extern struct semaphore ib_uverbs_idr_mutex; +extern struct mutex ib_uverbs_idr_mutex; extern struct idr ib_uverbs_pd_idr; extern struct idr ib_uverbs_mr_idr; extern struct idr ib_uverbs_mw_idr; diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 554c2057b7c1..407b6284d7d5 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -67,7 +67,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&file->mutex); + mutex_lock(&file->mutex); if (file->ucontext) { ret = -EINVAL; @@ -119,7 +119,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, fd_install(resp.async_fd, filp); - up(&file->mutex); + mutex_unlock(&file->mutex); return in_len; @@ -131,7 +131,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, ibdev->dealloc_ucontext(ucontext); err: - up(&file->mutex); + mutex_unlock(&file->mutex); return ret; } @@ -290,7 +290,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, pd->uobject = uobj; atomic_set(&pd->usecnt, 0); - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); retry: if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) { @@ -314,11 +314,11 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, goto err_idr; } - down(&file->mutex); + mutex_lock(&file->mutex); list_add_tail(&uobj->list, &file->ucontext->pd_list); - up(&file->mutex); + mutex_unlock(&file->mutex); - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return in_len; @@ -326,7 +326,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_pd_idr, uobj->id); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); ib_dealloc_pd(pd); err: @@ -346,7 +346,7 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); if (!pd || pd->uobject->context != file->ucontext) @@ -360,14 +360,14 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); - down(&file->mutex); + mutex_lock(&file->mutex); list_del(&uobj->list); - up(&file->mutex); + mutex_unlock(&file->mutex); kfree(uobj); out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -426,7 +426,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, obj->umem.virt_base = cmd.hca_va; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); if (!pd || pd->uobject->context != file->ucontext) { @@ -476,11 +476,11 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, goto err_idr; } - down(&file->mutex); + mutex_lock(&file->mutex); list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); - up(&file->mutex); + mutex_unlock(&file->mutex); - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return in_len; @@ -492,7 +492,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, atomic_dec(&pd->usecnt); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); ib_umem_release(file->device->ib_dev, &obj->umem); @@ -513,7 +513,7 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle); if (!mr || mr->uobject->context != file->ucontext) @@ -527,15 +527,15 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); - down(&file->mutex); + mutex_lock(&file->mutex); list_del(&memobj->uobject.list); - up(&file->mutex); + mutex_unlock(&file->mutex); ib_umem_release(file->device->ib_dev, &memobj->umem); kfree(memobj); out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -628,7 +628,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, cq->cq_context = ev_file; atomic_set(&cq->usecnt, 0); - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); retry: if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) { @@ -653,11 +653,11 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, goto err_idr; } - down(&file->mutex); + mutex_lock(&file->mutex); list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); - up(&file->mutex); + mutex_unlock(&file->mutex); - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return in_len; @@ -665,7 +665,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); ib_destroy_cq(cq); err: @@ -701,7 +701,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, goto out_wc; } - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); if (!cq || cq->uobject->context != file->ucontext) { ret = -EINVAL; @@ -731,7 +731,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, ret = -EFAULT; out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); kfree(resp); out_wc: @@ -750,14 +750,14 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); if (cq && cq->uobject->context == file->ucontext) { ib_req_notify_cq(cq, cmd.solicited_only ? IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); ret = in_len; } - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret; } @@ -779,7 +779,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, memset(&resp, 0, sizeof resp); - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); if (!cq || cq->uobject->context != file->ucontext) @@ -795,9 +795,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); - down(&file->mutex); + mutex_lock(&file->mutex); list_del(&uobj->uobject.list); - up(&file->mutex); + mutex_unlock(&file->mutex); ib_uverbs_release_ucq(file, ev_file, uobj); @@ -811,7 +811,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, ret = -EFAULT; out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -845,7 +845,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle); @@ -930,11 +930,11 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, goto err_idr; } - down(&file->mutex); + mutex_lock(&file->mutex); list_add_tail(&uobj->uevent.uobject.list, &file->ucontext->qp_list); - up(&file->mutex); + mutex_unlock(&file->mutex); - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return in_len; @@ -950,7 +950,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, atomic_dec(&attr.srq->usecnt); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -972,7 +972,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, if (!attr) return -ENOMEM; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) { @@ -1033,7 +1033,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, ret = in_len; out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); kfree(attr); return ret; @@ -1054,7 +1054,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, memset(&resp, 0, sizeof resp); - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1073,9 +1073,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); - down(&file->mutex); + mutex_lock(&file->mutex); list_del(&uobj->uevent.uobject.list); - up(&file->mutex); + mutex_unlock(&file->mutex); ib_uverbs_release_uevent(file, &uobj->uevent); @@ -1088,7 +1088,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, ret = -EFAULT; out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1119,7 +1119,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, if (!user_wr) return -ENOMEM; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1224,7 +1224,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, ret = -EFAULT; out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); while (wr) { next = wr->next; @@ -1341,7 +1341,7 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, if (IS_ERR(wr)) return PTR_ERR(wr); - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1362,7 +1362,7 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, ret = -EFAULT; out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); while (wr) { next = wr->next; @@ -1392,7 +1392,7 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file, if (IS_ERR(wr)) return PTR_ERR(wr); - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); if (!srq || srq->uobject->context != file->ucontext) @@ -1413,7 +1413,7 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file, ret = -EFAULT; out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); while (wr) { next = wr->next; @@ -1446,7 +1446,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); if (!pd || pd->uobject->context != file->ucontext) { @@ -1498,11 +1498,11 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, goto err_idr; } - down(&file->mutex); + mutex_lock(&file->mutex); list_add_tail(&uobj->list, &file->ucontext->ah_list); - up(&file->mutex); + mutex_unlock(&file->mutex); - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return in_len; @@ -1513,7 +1513,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, ib_destroy_ah(ah); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -1530,7 +1530,7 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle); if (!ah || ah->uobject->context != file->ucontext) @@ -1544,14 +1544,14 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle); - down(&file->mutex); + mutex_lock(&file->mutex); list_del(&uobj->list); - up(&file->mutex); + mutex_unlock(&file->mutex); kfree(uobj); out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1569,7 +1569,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1602,7 +1602,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, kfree(mcast); out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1620,7 +1620,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1641,7 +1641,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, } out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1673,7 +1673,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); @@ -1730,11 +1730,11 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, goto err_idr; } - down(&file->mutex); + mutex_lock(&file->mutex); list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); - up(&file->mutex); + mutex_unlock(&file->mutex); - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return in_len; @@ -1746,7 +1746,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, atomic_dec(&pd->usecnt); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -1764,7 +1764,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); if (!srq || srq->uobject->context != file->ucontext) { @@ -1778,7 +1778,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, ret = ib_modify_srq(srq, &attr, cmd.attr_mask); out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1796,7 +1796,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); memset(&resp, 0, sizeof resp); @@ -1812,9 +1812,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); - down(&file->mutex); + mutex_lock(&file->mutex); list_del(&uobj->uobject.list); - up(&file->mutex); + mutex_unlock(&file->mutex); ib_uverbs_release_uevent(file, uobj); @@ -1827,7 +1827,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, ret = -EFAULT; out: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 81737bd6faea..96ea79b63df7 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -66,7 +66,7 @@ enum { static struct class *uverbs_class; -DECLARE_MUTEX(ib_uverbs_idr_mutex); +DEFINE_MUTEX(ib_uverbs_idr_mutex); DEFINE_IDR(ib_uverbs_pd_idr); DEFINE_IDR(ib_uverbs_mr_idr); DEFINE_IDR(ib_uverbs_mw_idr); @@ -180,7 +180,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, if (!context) return 0; - down(&ib_uverbs_idr_mutex); + mutex_lock(&ib_uverbs_idr_mutex); list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id); @@ -250,7 +250,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, kfree(uobj); } - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return context->device->dealloc_ucontext(context); } @@ -653,7 +653,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) file->ucontext = NULL; file->async_file = NULL; kref_init(&file->ref); - init_MUTEX(&file->mutex); + mutex_init(&file->mutex); filp->private_data = file; diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 9923a15a9996..e0a5412b7e68 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -45,11 +45,11 @@ #include #include #include +#include #include #include -#include #include #include @@ -123,8 +123,8 @@ struct ipoib_dev_priv { unsigned long flags; - struct semaphore mcast_mutex; - struct semaphore vlan_mutex; + struct mutex mcast_mutex; + struct mutex vlan_mutex; struct rb_root path_tree; struct list_head path_list; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f7e848970794..86bcdd72a107 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -52,7 +52,7 @@ MODULE_PARM_DESC(data_debug_level, #define IPOIB_OP_RECV (1ul << 31) -static DECLARE_MUTEX(pkey_sem); +static DEFINE_MUTEX(pkey_mutex); struct ipoib_ah *ipoib_create_ah(struct net_device *dev, struct ib_pd *pd, struct ib_ah_attr *attr) @@ -445,10 +445,10 @@ int ipoib_ib_dev_down(struct net_device *dev) /* Shutdown the P_Key thread if still active */ if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { - down(&pkey_sem); + mutex_lock(&pkey_mutex); set_bit(IPOIB_PKEY_STOP, &priv->flags); cancel_delayed_work(&priv->pkey_task); - up(&pkey_sem); + mutex_unlock(&pkey_mutex); flush_workqueue(ipoib_workqueue); } @@ -599,13 +599,13 @@ void ipoib_ib_dev_flush(void *_dev) if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) ipoib_ib_dev_up(dev); - down(&priv->vlan_mutex); + mutex_lock(&priv->vlan_mutex); /* Flush any child interfaces too */ list_for_each_entry(cpriv, &priv->child_intfs, list) ipoib_ib_dev_flush(&cpriv->dev); - up(&priv->vlan_mutex); + mutex_unlock(&priv->vlan_mutex); } void ipoib_ib_dev_cleanup(struct net_device *dev) @@ -651,12 +651,12 @@ void ipoib_pkey_poll(void *dev_ptr) if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) ipoib_open(dev); else { - down(&pkey_sem); + mutex_lock(&pkey_mutex); if (!test_bit(IPOIB_PKEY_STOP, &priv->flags)) queue_delayed_work(ipoib_workqueue, &priv->pkey_task, HZ); - up(&pkey_sem); + mutex_unlock(&pkey_mutex); } } @@ -670,12 +670,12 @@ int ipoib_pkey_dev_delay_open(struct net_device *dev) /* P_Key value not assigned yet - start polling */ if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { - down(&pkey_sem); + mutex_lock(&pkey_mutex); clear_bit(IPOIB_PKEY_STOP, &priv->flags); queue_delayed_work(ipoib_workqueue, &priv->pkey_task, HZ); - up(&pkey_sem); + mutex_unlock(&pkey_mutex); return 1; } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 780009c7eaa6..fd3f5c862a5d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -105,7 +105,7 @@ int ipoib_open(struct net_device *dev) struct ipoib_dev_priv *cpriv; /* Bring up any child interfaces too */ - down(&priv->vlan_mutex); + mutex_lock(&priv->vlan_mutex); list_for_each_entry(cpriv, &priv->child_intfs, list) { int flags; @@ -115,7 +115,7 @@ int ipoib_open(struct net_device *dev) dev_change_flags(cpriv->dev, flags | IFF_UP); } - up(&priv->vlan_mutex); + mutex_unlock(&priv->vlan_mutex); } netif_start_queue(dev); @@ -140,7 +140,7 @@ static int ipoib_stop(struct net_device *dev) struct ipoib_dev_priv *cpriv; /* Bring down any child interfaces too */ - down(&priv->vlan_mutex); + mutex_lock(&priv->vlan_mutex); list_for_each_entry(cpriv, &priv->child_intfs, list) { int flags; @@ -150,7 +150,7 @@ static int ipoib_stop(struct net_device *dev) dev_change_flags(cpriv->dev, flags & ~IFF_UP); } - up(&priv->vlan_mutex); + mutex_unlock(&priv->vlan_mutex); } return 0; @@ -892,8 +892,8 @@ static void ipoib_setup(struct net_device *dev) spin_lock_init(&priv->lock); spin_lock_init(&priv->tx_lock); - init_MUTEX(&priv->mcast_mutex); - init_MUTEX(&priv->vlan_mutex); + mutex_init(&priv->mcast_mutex); + mutex_init(&priv->vlan_mutex); INIT_LIST_HEAD(&priv->path_list); INIT_LIST_HEAD(&priv->child_intfs); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 7403bac1977b..98039da0caf0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -55,7 +55,7 @@ MODULE_PARM_DESC(mcast_debug_level, "Enable multicast debug tracing if > 0"); #endif -static DECLARE_MUTEX(mcast_mutex); +static DEFINE_MUTEX(mcast_mutex); /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ struct ipoib_mcast { @@ -385,10 +385,10 @@ static void ipoib_mcast_join_complete(int status, if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) { mcast->backoff = 1; - down(&mcast_mutex); + mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) queue_work(ipoib_workqueue, &priv->mcast_task); - up(&mcast_mutex); + mutex_unlock(&mcast_mutex); complete(&mcast->done); return; } @@ -418,7 +418,7 @@ static void ipoib_mcast_join_complete(int status, mcast->query = NULL; - down(&mcast_mutex); + mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) { if (status == -ETIMEDOUT) queue_work(ipoib_workqueue, &priv->mcast_task); @@ -427,7 +427,7 @@ static void ipoib_mcast_join_complete(int status, mcast->backoff * HZ); } else complete(&mcast->done); - up(&mcast_mutex); + mutex_unlock(&mcast_mutex); return; } @@ -482,12 +482,12 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS) mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS; - down(&mcast_mutex); + mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) queue_delayed_work(ipoib_workqueue, &priv->mcast_task, mcast->backoff * HZ); - up(&mcast_mutex); + mutex_unlock(&mcast_mutex); } else mcast->query_id = ret; } @@ -520,11 +520,11 @@ void ipoib_mcast_join_task(void *dev_ptr) priv->broadcast = ipoib_mcast_alloc(dev, 1); if (!priv->broadcast) { ipoib_warn(priv, "failed to allocate broadcast group\n"); - down(&mcast_mutex); + mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) queue_delayed_work(ipoib_workqueue, &priv->mcast_task, HZ); - up(&mcast_mutex); + mutex_unlock(&mcast_mutex); return; } @@ -580,10 +580,10 @@ int ipoib_mcast_start_thread(struct net_device *dev) ipoib_dbg_mcast(priv, "starting multicast thread\n"); - down(&mcast_mutex); + mutex_lock(&mcast_mutex); if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags)) queue_work(ipoib_workqueue, &priv->mcast_task); - up(&mcast_mutex); + mutex_unlock(&mcast_mutex); return 0; } @@ -595,10 +595,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) ipoib_dbg_mcast(priv, "stopping multicast thread\n"); - down(&mcast_mutex); + mutex_lock(&mcast_mutex); clear_bit(IPOIB_MCAST_RUN, &priv->flags); cancel_delayed_work(&priv->mcast_task); - up(&mcast_mutex); + mutex_unlock(&mcast_mutex); if (flush) flush_workqueue(ipoib_workqueue); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index e829e10400e3..faaf10e5fc7b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -65,9 +65,9 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid) } /* attach QP to multicast group */ - down(&priv->mcast_mutex); + mutex_lock(&priv->mcast_mutex); ret = ib_attach_mcast(priv->qp, mgid, mlid); - up(&priv->mcast_mutex); + mutex_unlock(&priv->mcast_mutex); if (ret) ipoib_warn(priv, "failed to attach to multicast group, ret = %d\n", ret); @@ -81,9 +81,9 @@ int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid) struct ipoib_dev_priv *priv = netdev_priv(dev); int ret; - down(&priv->mcast_mutex); + mutex_lock(&priv->mcast_mutex); ret = ib_detach_mcast(priv->qp, mgid, mlid); - up(&priv->mcast_mutex); + mutex_unlock(&priv->mcast_mutex); if (ret) ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index d280b341a37f..4ca175553f9f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -63,7 +63,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) ppriv = netdev_priv(pdev); - down(&ppriv->vlan_mutex); + mutex_lock(&ppriv->vlan_mutex); /* * First ensure this isn't a duplicate. We check the parent device and @@ -124,7 +124,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) list_add_tail(&priv->list, &ppriv->child_intfs); - up(&ppriv->vlan_mutex); + mutex_unlock(&ppriv->vlan_mutex); return 0; @@ -139,7 +139,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) free_netdev(priv->dev); err: - up(&ppriv->vlan_mutex); + mutex_unlock(&ppriv->vlan_mutex); return result; } @@ -153,7 +153,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) ppriv = netdev_priv(pdev); - down(&ppriv->vlan_mutex); + mutex_lock(&ppriv->vlan_mutex); list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) { if (priv->pkey == pkey) { unregister_netdev(priv->dev); @@ -167,7 +167,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) break; } } - up(&ppriv->vlan_mutex); + mutex_unlock(&ppriv->vlan_mutex); return ret; }