X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Finfiniband%2Fcore%2Fucm.c;h=9164a09b6ccd1d0aeea7153d29c8307e3c5903ca;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=c1c6fda9452cc44f6b44400e00eaa7f5e42ea43a;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index c1c6fda94..9164a09b6 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -30,7 +30,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * $Id: ucm.c 4311 2005-12-05 18:42:01Z sean.hefty $ + * $Id: ucm.c 2594 2005-06-13 19:46:02Z libor $ */ #include @@ -50,7 +50,6 @@ #include #include -#include MODULE_AUTHOR("Libor Michalek"); MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access"); @@ -64,7 +63,7 @@ struct ib_ucm_device { }; struct ib_ucm_file { - struct mutex file_mutex; + struct semaphore mutex; struct file *filp; struct ib_ucm_device *device; @@ -153,7 +152,7 @@ static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx) { struct ib_ucm_event *uevent; - mutex_lock(&ctx->file->file_mutex); + down(&ctx->file->mutex); list_del(&ctx->file_list); while (!list_empty(&ctx->events)) { @@ -168,7 +167,7 @@ static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx) kfree(uevent); } - mutex_unlock(&ctx->file->file_mutex); + up(&ctx->file->mutex); } static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) @@ -206,6 +205,36 @@ error: return NULL; } +static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath, + struct ib_sa_path_rec *kpath) +{ + if (!kpath || !upath) + return; + + memcpy(upath->dgid, kpath->dgid.raw, sizeof *upath->dgid); + memcpy(upath->sgid, kpath->sgid.raw, sizeof *upath->sgid); + + upath->dlid = kpath->dlid; + upath->slid = kpath->slid; + upath->raw_traffic = kpath->raw_traffic; + upath->flow_label = kpath->flow_label; + upath->hop_limit = kpath->hop_limit; + upath->traffic_class = kpath->traffic_class; + upath->reversible = kpath->reversible; + upath->numb_path = kpath->numb_path; + upath->pkey = kpath->pkey; + upath->sl = kpath->sl; + upath->mtu_selector = kpath->mtu_selector; + upath->mtu = kpath->mtu; + upath->rate_selector = kpath->rate_selector; + upath->rate = kpath->rate; + upath->packet_life_time = kpath->packet_life_time; + upath->preference = kpath->preference; + + upath->packet_life_time_selector = + kpath->packet_life_time_selector; +} + static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, struct ib_cm_req_event_param *kreq) { @@ -224,10 +253,8 @@ static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, ureq->srq = kreq->srq; ureq->port = kreq->port; - ib_copy_path_rec_to_user(&ureq->primary_path, kreq->primary_path); - if (kreq->alternate_path) - ib_copy_path_rec_to_user(&ureq->alternate_path, - kreq->alternate_path); + ib_ucm_event_path_get(&ureq->primary_path, kreq->primary_path); + ib_ucm_event_path_get(&ureq->alternate_path, kreq->alternate_path); } static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep, @@ -297,8 +324,8 @@ static int ib_ucm_event_process(struct ib_cm_event *evt, info = evt->param.rej_rcvd.ari; break; case IB_CM_LAP_RECEIVED: - ib_copy_path_rec_to_user(&uvt->resp.u.lap_resp.path, - evt->param.lap_rcvd.alternate_path); + ib_ucm_event_path_get(&uvt->resp.u.lap_resp.path, + evt->param.lap_rcvd.alternate_path); uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE; uvt->resp.present = IB_UCM_PRES_ALTERNATE; break; @@ -375,11 +402,11 @@ static int ib_ucm_event_handler(struct ib_cm_id *cm_id, if (result) goto err2; - mutex_lock(&ctx->file->file_mutex); + down(&ctx->file->mutex); list_add_tail(&uevent->file_list, &ctx->file->events); list_add_tail(&uevent->ctx_list, &ctx->events); wake_up_interruptible(&ctx->file->poll_wait); - mutex_unlock(&ctx->file->file_mutex); + up(&ctx->file->mutex); return 0; err2: @@ -405,7 +432,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - mutex_lock(&file->file_mutex); + down(&file->mutex); while (list_empty(&file->events)) { if (file->filp->f_flags & O_NONBLOCK) { @@ -420,9 +447,9 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, prepare_to_wait(&file->poll_wait, &wait, TASK_INTERRUPTIBLE); - mutex_unlock(&file->file_mutex); + up(&file->mutex); schedule(); - mutex_lock(&file->file_mutex); + down(&file->mutex); finish_wait(&file->poll_wait, &wait); } @@ -482,7 +509,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, kfree(uevent->info); kfree(uevent); done: - mutex_unlock(&file->file_mutex); + up(&file->mutex); return result; } @@ -501,9 +528,9 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - mutex_lock(&file->file_mutex); + down(&file->mutex); ctx = ib_ucm_ctx_alloc(file); - mutex_unlock(&file->file_mutex); + up(&file->mutex); if (!ctx) return -ENOMEM; @@ -610,11 +637,65 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, return result; } +static void ib_ucm_copy_ah_attr(struct ib_ucm_ah_attr *dest_attr, + struct ib_ah_attr *src_attr) +{ + memcpy(dest_attr->grh_dgid, src_attr->grh.dgid.raw, + sizeof src_attr->grh.dgid); + dest_attr->grh_flow_label = src_attr->grh.flow_label; + dest_attr->grh_sgid_index = src_attr->grh.sgid_index; + dest_attr->grh_hop_limit = src_attr->grh.hop_limit; + dest_attr->grh_traffic_class = src_attr->grh.traffic_class; + + dest_attr->dlid = src_attr->dlid; + dest_attr->sl = src_attr->sl; + dest_attr->src_path_bits = src_attr->src_path_bits; + dest_attr->static_rate = src_attr->static_rate; + dest_attr->is_global = (src_attr->ah_flags & IB_AH_GRH); + dest_attr->port_num = src_attr->port_num; +} + +static void ib_ucm_copy_qp_attr(struct ib_ucm_init_qp_attr_resp *dest_attr, + struct ib_qp_attr *src_attr) +{ + dest_attr->cur_qp_state = src_attr->cur_qp_state; + dest_attr->path_mtu = src_attr->path_mtu; + dest_attr->path_mig_state = src_attr->path_mig_state; + dest_attr->qkey = src_attr->qkey; + dest_attr->rq_psn = src_attr->rq_psn; + dest_attr->sq_psn = src_attr->sq_psn; + dest_attr->dest_qp_num = src_attr->dest_qp_num; + dest_attr->qp_access_flags = src_attr->qp_access_flags; + + dest_attr->max_send_wr = src_attr->cap.max_send_wr; + dest_attr->max_recv_wr = src_attr->cap.max_recv_wr; + dest_attr->max_send_sge = src_attr->cap.max_send_sge; + dest_attr->max_recv_sge = src_attr->cap.max_recv_sge; + dest_attr->max_inline_data = src_attr->cap.max_inline_data; + + ib_ucm_copy_ah_attr(&dest_attr->ah_attr, &src_attr->ah_attr); + ib_ucm_copy_ah_attr(&dest_attr->alt_ah_attr, &src_attr->alt_ah_attr); + + dest_attr->pkey_index = src_attr->pkey_index; + dest_attr->alt_pkey_index = src_attr->alt_pkey_index; + dest_attr->en_sqd_async_notify = src_attr->en_sqd_async_notify; + dest_attr->sq_draining = src_attr->sq_draining; + dest_attr->max_rd_atomic = src_attr->max_rd_atomic; + dest_attr->max_dest_rd_atomic = src_attr->max_dest_rd_atomic; + dest_attr->min_rnr_timer = src_attr->min_rnr_timer; + dest_attr->port_num = src_attr->port_num; + dest_attr->timeout = src_attr->timeout; + dest_attr->retry_cnt = src_attr->retry_cnt; + dest_attr->rnr_retry = src_attr->rnr_retry; + dest_attr->alt_port_num = src_attr->alt_port_num; + dest_attr->alt_timeout = src_attr->alt_timeout; +} + static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file, const char __user *inbuf, int in_len, int out_len) { - struct ib_uverbs_qp_attr resp; + struct ib_ucm_init_qp_attr_resp resp; struct ib_ucm_init_qp_attr cmd; struct ib_ucm_context *ctx; struct ib_qp_attr qp_attr; @@ -637,7 +718,7 @@ static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file, if (result) goto out; - ib_copy_qp_attr_to_user(&resp, &qp_attr); + ib_ucm_copy_qp_attr(&resp, &qp_attr); if (copy_to_user((void __user *)(unsigned long)cmd.response, &resp, sizeof(resp))) @@ -648,17 +729,6 @@ out: return result; } -static int ucm_validate_listen(__be64 service_id, __be64 service_mask) -{ - service_id &= service_mask; - - if (((service_id & IB_CMA_SERVICE_ID_MASK) == IB_CMA_SERVICE_ID) || - ((service_id & IB_SDP_SERVICE_ID_MASK) == IB_SDP_SERVICE_ID)) - return -EINVAL; - - return 0; -} - static ssize_t ib_ucm_listen(struct ib_ucm_file *file, const char __user *inbuf, int in_len, int out_len) @@ -674,13 +744,7 @@ static ssize_t ib_ucm_listen(struct ib_ucm_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx); - result = ucm_validate_listen(cmd.service_id, cmd.service_mask); - if (result) - goto out; - - result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask, - NULL); -out: + result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask); ib_ucm_ctx_put(ctx); return result; } @@ -729,7 +793,7 @@ static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len) static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) { - struct ib_user_path_rec upath; + struct ib_ucm_path_rec ucm_path; struct ib_sa_path_rec *sa_path; *path = NULL; @@ -741,14 +805,36 @@ static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) if (!sa_path) return -ENOMEM; - if (copy_from_user(&upath, (void __user *)(unsigned long)src, - sizeof(upath))) { + if (copy_from_user(&ucm_path, (void __user *)(unsigned long)src, + sizeof(ucm_path))) { kfree(sa_path); return -EFAULT; } - ib_copy_path_rec_from_user(sa_path, &upath); + memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof sa_path->dgid); + memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof sa_path->sgid); + + sa_path->dlid = ucm_path.dlid; + sa_path->slid = ucm_path.slid; + sa_path->raw_traffic = ucm_path.raw_traffic; + sa_path->flow_label = ucm_path.flow_label; + sa_path->hop_limit = ucm_path.hop_limit; + sa_path->traffic_class = ucm_path.traffic_class; + sa_path->reversible = ucm_path.reversible; + sa_path->numb_path = ucm_path.numb_path; + sa_path->pkey = ucm_path.pkey; + sa_path->sl = ucm_path.sl; + sa_path->mtu_selector = ucm_path.mtu_selector; + sa_path->mtu = ucm_path.mtu; + sa_path->rate_selector = ucm_path.rate_selector; + sa_path->rate = ucm_path.rate; + sa_path->packet_life_time = ucm_path.packet_life_time; + sa_path->preference = ucm_path.preference; + + sa_path->packet_life_time_selector = + ucm_path.packet_life_time_selector; + *path = sa_path; return 0; } @@ -1044,6 +1130,7 @@ static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file, param.service_id = cmd.sid; param.timeout_ms = cmd.timeout; param.max_cm_retries = cmd.max_cm_retries; + param.pkey = cmd.pkey; ctx = ib_ucm_ctx_get(file, cmd.id); if (!IS_ERR(ctx)) { @@ -1176,7 +1263,7 @@ static int ib_ucm_open(struct inode *inode, struct file *filp) INIT_LIST_HEAD(&file->ctxs); init_waitqueue_head(&file->poll_wait); - mutex_init(&file->file_mutex); + init_MUTEX(&file->mutex); filp->private_data = file; file->filp = filp; @@ -1190,11 +1277,11 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) struct ib_ucm_file *file = filp->private_data; struct ib_ucm_context *ctx; - mutex_lock(&file->file_mutex); + down(&file->mutex); while (!list_empty(&file->ctxs)) { ctx = list_entry(file->ctxs.next, struct ib_ucm_context, file_list); - mutex_unlock(&file->file_mutex); + up(&file->mutex); mutex_lock(&ctx_id_mutex); idr_remove(&ctx_id_table, ctx->id); @@ -1204,9 +1291,9 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) ib_ucm_cleanup_events(ctx); kfree(ctx); - mutex_lock(&file->file_mutex); + down(&file->mutex); } - mutex_unlock(&file->file_mutex); + up(&file->mutex); kfree(file); return 0; }