diff options
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r-- | drivers/infiniband/core/cm.c | 49 | ||||
-rw-r--r-- | drivers/infiniband/core/device.c | 23 | ||||
-rw-r--r-- | drivers/infiniband/core/sysfs.c | 32 | ||||
-rw-r--r-- | drivers/infiniband/core/ucm.c | 23 | ||||
-rw-r--r-- | drivers/infiniband/core/user_mad.c | 45 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 16 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 263 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 29 | ||||
-rw-r--r-- | drivers/infiniband/core/verbs.c | 4 |
9 files changed, 277 insertions, 207 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 02110e00d145..2514de3480d8 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -308,10 +308,11 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv) { unsigned long flags; int ret; + static int next_id; do { spin_lock_irqsave(&cm.lock, flags); - ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1, + ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, next_id++, (__force int *) &cm_id_priv->id.local_id); spin_unlock_irqrestore(&cm.lock, flags); } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); @@ -684,6 +685,13 @@ retest: cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT); break; case IB_CM_REQ_SENT: + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); + spin_unlock_irqrestore(&cm_id_priv->lock, flags); + ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, + &cm_id_priv->av.port->cm_dev->ca_guid, + sizeof cm_id_priv->av.port->cm_dev->ca_guid, + NULL, 0); + break; case IB_CM_MRA_REQ_RCVD: case IB_CM_REP_SENT: case IB_CM_MRA_REP_RCVD: @@ -694,10 +702,8 @@ retest: case IB_CM_REP_RCVD: case IB_CM_MRA_REP_SENT: spin_unlock_irqrestore(&cm_id_priv->lock, flags); - ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, - &cm_id_priv->av.port->cm_dev->ca_guid, - sizeof cm_id_priv->av.port->cm_dev->ca_guid, - NULL, 0); + ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, + NULL, 0, NULL, 0); break; case IB_CM_ESTABLISHED: spin_unlock_irqrestore(&cm_id_priv->lock, flags); @@ -850,7 +856,7 @@ static void cm_format_req(struct cm_req_msg *req_msg, param->private_data_len); } -static inline int cm_validate_req_param(struct ib_cm_req_param *param) +static int cm_validate_req_param(struct ib_cm_req_param *param) { /* peer-to-peer not supported */ if (param->peer_to_peer) @@ -999,7 +1005,7 @@ static inline int cm_is_active_peer(__be64 local_ca_guid, __be64 remote_ca_guid, (be32_to_cpu(local_qpn) > be32_to_cpu(remote_qpn)))); } -static inline void cm_format_paths_from_req(struct cm_req_msg *req_msg, +static void cm_format_paths_from_req(struct cm_req_msg *req_msg, struct ib_sa_path_rec *primary_path, struct ib_sa_path_rec *alt_path) { @@ -3157,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; @@ -3194,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++) { @@ -3211,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); @@ -3224,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) { @@ -3234,7 +3222,6 @@ error2: 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/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 <linux/errno.h> #include <linux/slab.h> #include <linux/init.h> - -#include <asm/semaphore.h> +#include <linux/mutex.h> #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/sysfs.c b/drivers/infiniband/core/sysfs.c index 08648b1a387e..5982d687a000 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -434,24 +434,18 @@ static void ib_device_release(struct class_device *cdev) kfree(dev); } -static int ib_device_hotplug(struct class_device *cdev, char **envp, - int num_envp, char *buf, int size) +static int ib_device_uevent(struct class_device *cdev, char **envp, + int num_envp, char *buf, int size) { struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); int i = 0, len = 0; - if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len, - "NAME=%s", dev->name)) + if (add_uevent_var(envp, num_envp, &i, buf, size, &len, + "NAME=%s", dev->name)) return -ENOMEM; /* - * It might be nice to pass the node GUID to hotplug, 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 the hotplug script 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); @@ -653,7 +641,7 @@ static struct class_device_attribute *ib_class_attributes[] = { static struct class ib_class = { .name = "infiniband", .release = ib_device_release, - .hotplug = ib_device_hotplug, + .uevent = ib_device_uevent, }; int ib_device_register_sysfs(struct ib_device *device) 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 <linux/mount.h> #include <linux/cdev.h> #include <linux/idr.h> +#include <linux/mutex.h> #include <asm/uaccess.h> @@ -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/user_mad.c b/drivers/infiniband/core/user_mad.c index e73f81c22381..c908de8db5a9 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -197,8 +197,8 @@ static void send_handler(struct ib_mad_agent *agent, memcpy(timeout->mad.data, packet->mad.data, sizeof (struct ib_mad_hdr)); - if (!queue_packet(file, agent, timeout)) - return; + if (queue_packet(file, agent, timeout)) + kfree(timeout); } out: kfree(packet); @@ -310,7 +310,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, u8 method; __be64 *tid; int ret, length, hdr_len, copy_offset; - int rmpp_active = 0; + int rmpp_active, has_rmpp_header; if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR) return -EINVAL; @@ -360,28 +360,31 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, } rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; - if (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE) { - /* RMPP active */ - if (!agent->rmpp_version) { - ret = -EINVAL; - goto err_ah; - } - - /* Validate that the management class can support RMPP */ - if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { - hdr_len = IB_MGMT_SA_HDR; - } else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && - (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) { - hdr_len = IB_MGMT_VENDOR_HDR; - } else { - ret = -EINVAL; - goto err_ah; - } - rmpp_active = 1; + if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { + hdr_len = IB_MGMT_SA_HDR; copy_offset = IB_MGMT_RMPP_HDR; + has_rmpp_header = 1; + } else if (rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START && + rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END) { + hdr_len = IB_MGMT_VENDOR_HDR; + copy_offset = IB_MGMT_RMPP_HDR; + has_rmpp_header = 1; } else { hdr_len = IB_MGMT_MAD_HDR; copy_offset = IB_MGMT_MAD_HDR; + has_rmpp_header = 0; + } + + if (has_rmpp_header) + rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & + IB_MGMT_RMPP_FLAG_ACTIVE; + else + rmpp_active = 0; + + /* Validate that the management class can support RMPP */ + if (rmpp_active && !agent->rmpp_version) { + ret = -EINVAL; + goto err_ah; } packet->msg = ib_create_send_mad(agent, diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index ecb830127865..f7eecbc6af6c 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -41,6 +41,7 @@ #include <linux/kref.h> #include <linux/idr.h> +#include <linux/mutex.h> #include <rdma/ib_verbs.h> #include <rdma/ib_user_verbs.h> @@ -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; @@ -105,12 +106,23 @@ struct ib_uverbs_event { u32 *counter; }; +struct ib_uverbs_mcast_entry { + struct list_head list; + union ib_gid gid; + u16 lid; +}; + struct ib_uevent_object { struct ib_uobject uobject; struct list_head event_list; u32 events_reported; }; +struct ib_uqp_object { + struct ib_uevent_object uevent; + struct list_head mcast_list; +}; + struct ib_ucq_object { struct ib_uobject uobject; struct ib_uverbs_file *uverbs_file; @@ -120,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 ed45da892b1c..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 @@ err_free: ibdev->dealloc_ucontext(ucontext); err: - up(&file->mutex); + mutex_unlock(&file->mutex); return ret; } @@ -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; @@ -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 @@ retry: 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 @@ err_idr: 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 @@ retry: 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; @@ -489,9 +489,10 @@ err_idr: err_unreg: ib_dereg_mr(mr); + 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); @@ -512,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) @@ -526,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; } @@ -593,13 +594,18 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, if (cmd.comp_vector >= file->device->num_comp_vectors) return -EINVAL; - if (cmd.comp_channel >= 0) - ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); - uobj = kmalloc(sizeof *uobj, GFP_KERNEL); if (!uobj) return -ENOMEM; + if (cmd.comp_channel >= 0) { + ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); + if (!ev_file) { + ret = -EINVAL; + goto err; + } + } + uobj->uobject.user_handle = cmd.user_handle; uobj->uobject.context = file->ucontext; uobj->uverbs_file = file; @@ -622,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)) { @@ -647,11 +653,11 @@ retry: 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; @@ -659,10 +665,12 @@ err_idr: 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: + if (ev_file) + ib_uverbs_release_ucq(file, ev_file, uobj); kfree(uobj); return ret; } @@ -693,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; @@ -723,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: @@ -742,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; } @@ -771,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) @@ -787,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); @@ -803,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; } @@ -815,7 +823,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, struct ib_uverbs_create_qp cmd; struct ib_uverbs_create_qp_resp resp; struct ib_udata udata; - struct ib_uevent_object *uobj; + struct ib_uqp_object *uobj; struct ib_pd *pd; struct ib_cq *scq, *rcq; struct ib_srq *srq; @@ -837,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); @@ -866,10 +874,11 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, attr.cap.max_recv_sge = cmd.max_recv_sge; attr.cap.max_inline_data = cmd.max_inline_data; - uobj->uobject.user_handle = cmd.user_handle; - uobj->uobject.context = file->ucontext; - uobj->events_reported = 0; - INIT_LIST_HEAD(&uobj->event_list); + uobj->uevent.uobject.user_handle = cmd.user_handle; + uobj->uevent.uobject.context = file->ucontext; + uobj->uevent.events_reported = 0; + INIT_LIST_HEAD(&uobj->uevent.event_list); + INIT_LIST_HEAD(&uobj->mcast_list); qp = pd->device->create_qp(pd, &attr, &udata); if (IS_ERR(qp)) { @@ -882,7 +891,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, qp->send_cq = attr.send_cq; qp->recv_cq = attr.recv_cq; qp->srq = attr.srq; - qp->uobject = &uobj->uobject; + qp->uobject = &uobj->uevent.uobject; qp->event_handler = attr.event_handler; qp->qp_context = attr.qp_context; qp->qp_type = attr.qp_type; @@ -901,14 +910,14 @@ retry: goto err_destroy; } - ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->uobject.id); + ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->uevent.uobject.id); if (ret == -EAGAIN) goto retry; if (ret) goto err_destroy; - resp.qp_handle = uobj->uobject.id; + resp.qp_handle = uobj->uevent.uobject.id; resp.max_recv_sge = attr.cap.max_recv_sge; resp.max_send_sge = attr.cap.max_send_sge; resp.max_recv_wr = attr.cap.max_recv_wr; @@ -921,22 +930,27 @@ retry: goto err_idr; } - down(&file->mutex); - list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); - up(&file->mutex); + mutex_lock(&file->mutex); + list_add_tail(&uobj->uevent.uobject.list, &file->ucontext->qp_list); + mutex_unlock(&file->mutex); - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); return in_len; err_idr: - idr_remove(&ib_uverbs_qp_idr, uobj->uobject.id); + idr_remove(&ib_uverbs_qp_idr, uobj->uevent.uobject.id); err_destroy: ib_destroy_qp(qp); + atomic_dec(&pd->usecnt); + atomic_dec(&attr.send_cq->usecnt); + atomic_dec(&attr.recv_cq->usecnt); + if (attr.srq) + atomic_dec(&attr.srq->usecnt); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -958,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) { @@ -1019,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; @@ -1032,7 +1046,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, struct ib_uverbs_destroy_qp cmd; struct ib_uverbs_destroy_qp_resp resp; struct ib_qp *qp; - struct ib_uevent_object *uobj; + struct ib_uqp_object *uobj; int ret = -EINVAL; if (copy_from_user(&cmd, buf, sizeof cmd)) @@ -1040,13 +1054,18 @@ 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) goto out; - uobj = container_of(qp->uobject, struct ib_uevent_object, uobject); + uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); + + if (!list_empty(&uobj->mcast_list)) { + ret = -EBUSY; + goto out; + } ret = ib_destroy_qp(qp); if (ret) @@ -1054,13 +1073,13 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); - down(&file->mutex); - list_del(&uobj->uobject.list); - up(&file->mutex); + mutex_lock(&file->mutex); + list_del(&uobj->uevent.uobject.list); + mutex_unlock(&file->mutex); - ib_uverbs_release_uevent(file, uobj); + ib_uverbs_release_uevent(file, &uobj->uevent); - resp.events_reported = uobj->events_reported; + resp.events_reported = uobj->uevent.events_reported; kfree(uobj); @@ -1069,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; } @@ -1100,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) @@ -1205,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; @@ -1322,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) @@ -1343,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; @@ -1373,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) @@ -1394,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; @@ -1427,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) { @@ -1442,6 +1461,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, attr.sl = cmd.attr.sl; attr.src_path_bits = cmd.attr.src_path_bits; attr.static_rate = cmd.attr.static_rate; + attr.ah_flags = cmd.attr.is_global ? IB_AH_GRH : 0; attr.port_num = cmd.attr.port_num; attr.grh.flow_label = cmd.attr.grh.flow_label; attr.grh.sgid_index = cmd.attr.grh.sgid_index; @@ -1478,11 +1498,11 @@ retry: 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; @@ -1493,7 +1513,7 @@ err_destroy: ib_destroy_ah(ah); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -1510,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) @@ -1524,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; } @@ -1542,18 +1562,47 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, { struct ib_uverbs_attach_mcast cmd; struct ib_qp *qp; + struct ib_uqp_object *uobj; + struct ib_uverbs_mcast_entry *mcast; int ret = -EINVAL; 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) - ret = ib_attach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid); + if (!qp || qp->uobject->context != file->ucontext) + goto out; - up(&ib_uverbs_idr_mutex); + uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); + + list_for_each_entry(mcast, &uobj->mcast_list, list) + if (cmd.mlid == mcast->lid && + !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) { + ret = 0; + goto out; + } + + mcast = kmalloc(sizeof *mcast, GFP_KERNEL); + if (!mcast) { + ret = -ENOMEM; + goto out; + } + + mcast->lid = cmd.mlid; + memcpy(mcast->gid.raw, cmd.gid, sizeof mcast->gid.raw); + + ret = ib_attach_mcast(qp, &mcast->gid, cmd.mlid); + if (!ret) { + uobj = container_of(qp->uobject, struct ib_uqp_object, + uevent.uobject); + list_add_tail(&mcast->list, &uobj->mcast_list); + } else + kfree(mcast); + +out: + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1563,19 +1612,36 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, int out_len) { struct ib_uverbs_detach_mcast cmd; + struct ib_uqp_object *uobj; struct ib_qp *qp; + struct ib_uverbs_mcast_entry *mcast; int ret = -EINVAL; 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) - ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid); + if (!qp || qp->uobject->context != file->ucontext) + goto out; + + ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid); + if (ret) + goto out; + + uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); - up(&ib_uverbs_idr_mutex); + list_for_each_entry(mcast, &uobj->mcast_list, list) + if (cmd.mlid == mcast->lid && + !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) { + list_del(&mcast->list); + kfree(mcast); + break; + } + +out: + mutex_unlock(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1607,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); @@ -1664,11 +1730,11 @@ retry: 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; @@ -1677,9 +1743,10 @@ err_idr: err_destroy: ib_destroy_srq(srq); + atomic_dec(&pd->usecnt); err_up: - up(&ib_uverbs_idr_mutex); + mutex_unlock(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -1697,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) { @@ -1711,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; } @@ -1729,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); @@ -1745,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); @@ -1760,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 de6581d7cb8d..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); @@ -160,6 +160,18 @@ void ib_uverbs_release_uevent(struct ib_uverbs_file *file, spin_unlock_irq(&file->async_file->lock); } +static void ib_uverbs_detach_umcast(struct ib_qp *qp, + struct ib_uqp_object *uobj) +{ + struct ib_uverbs_mcast_entry *mcast, *tmp; + + list_for_each_entry_safe(mcast, tmp, &uobj->mcast_list, list) { + ib_detach_mcast(qp, &mcast->gid, mcast->lid); + list_del(&mcast->list); + kfree(mcast); + } +} + static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, struct ib_ucontext *context) { @@ -168,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); @@ -180,13 +192,14 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id); - struct ib_uevent_object *uevent = - container_of(uobj, struct ib_uevent_object, uobject); + struct ib_uqp_object *uqp = + container_of(uobj, struct ib_uqp_object, uevent.uobject); idr_remove(&ib_uverbs_qp_idr, uobj->id); + ib_uverbs_detach_umcast(qp, uqp); ib_destroy_qp(qp); list_del(&uobj->list); - ib_uverbs_release_uevent(file, uevent); - kfree(uevent); + ib_uverbs_release_uevent(file, &uqp->uevent); + kfree(uqp); } list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) { @@ -237,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); } @@ -640,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/core/verbs.c b/drivers/infiniband/core/verbs.c index 4c15e112736c..c857361be449 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -107,9 +107,9 @@ struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, if (wc->wc_flags & IB_WC_GRH) { ah_attr.ah_flags = IB_AH_GRH; - ah_attr.grh.dgid = grh->dgid; + ah_attr.grh.dgid = grh->sgid; - ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num, + ret = ib_find_cached_gid(pd->device, &grh->dgid, &port_num, &gid_index); if (ret) return ERR_PTR(ret); |