···8 any protocols you wish to use as well as drivers for your9 InfiniBand hardware.1011-config INFINIBAND_USER_VERBS12- tristate "InfiniBand userspace verbs support"13 depends on INFINIBAND14 ---help---15- Userspace InfiniBand verbs support. This is the kernel side16- of userspace verbs, which allows userspace processes to17- directly access InfiniBand hardware for fast-path18- operations. You will also need libibverbs and a hardware19- driver library from <http://www.openib.org>.000000000002021source "drivers/infiniband/hw/mthca/Kconfig"22
···8 any protocols you wish to use as well as drivers for your9 InfiniBand hardware.1011+config INFINIBAND_USER_MAD12+ tristate "InfiniBand userspace MAD support"13 depends on INFINIBAND14 ---help---15+ Userspace InfiniBand Management Datagram (MAD) support. This16+ is the kernel side of the userspace MAD support, which allows17+ userspace processes to send and receive MADs. You will also 18+ need libibumad from <http://www.openib.org>.19+20+config INFINIBAND_USER_ACCESS21+ tristate "InfiniBand userspace access (verbs and CM)"22+ depends on INFINIBAND23+ ---help---24+ Userspace InfiniBand access support. This enables the25+ kernel side of userspace verbs and the userspace26+ communication manager (CM). This allows userspace processes27+ to set up connections and directly access InfiniBand28+ hardware for fast-path operations. You will also need29+ libibverbs, libibcm and a hardware driver library from30+ <http://www.openib.org>.3132source "drivers/infiniband/hw/mthca/Kconfig"33
···7273static struct semaphore ctx_id_mutex;74static struct idr ctx_id_table;75-static int ctx_id_rover = 0;7677static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)78{···96 wake_up(&ctx->wait);97}9899-static ssize_t ib_ucm_destroy_ctx(struct ib_ucm_file *file, int id)100{101- struct ib_ucm_context *ctx;0000102 struct ib_ucm_event *uevent;103104- down(&ctx_id_mutex);105- ctx = idr_find(&ctx_id_table, id);106- if (!ctx)107- ctx = ERR_PTR(-ENOENT);108- else if (ctx->file != file)109- ctx = ERR_PTR(-EINVAL);110- else111- idr_remove(&ctx_id_table, ctx->id);112- up(&ctx_id_mutex);113-114- if (IS_ERR(ctx))115- return PTR_ERR(ctx);116-117- atomic_dec(&ctx->ref);118- wait_event(ctx->wait, !atomic_read(&ctx->ref));119-120- /* No new events will be generated after destroying the cm_id. */121- if (!IS_ERR(ctx->cm_id))122- ib_destroy_cm_id(ctx->cm_id);123-124- /* Cleanup events not yet reported to the user. */125- down(&file->mutex);126 list_del(&ctx->file_list);127 while (!list_empty(&ctx->events)) {128···115 list_del(&uevent->ctx_list);116117 /* clear incoming connections. */118- if (uevent->cm_id)119 ib_destroy_cm_id(uevent->cm_id);120121 kfree(uevent);122 }123- up(&file->mutex);124-125- kfree(ctx);126- return 0;127}128129static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)···132 if (!ctx)133 return NULL;1340135 atomic_set(&ctx->ref, 1);136 init_waitqueue_head(&ctx->wait);137 ctx->file = file;138-139 INIT_LIST_HEAD(&ctx->events);140141- list_add_tail(&ctx->file_list, &file->ctxs);000142143- ctx_id_rover = (ctx_id_rover + 1) & INT_MAX;144-retry:145- result = idr_pre_get(&ctx_id_table, GFP_KERNEL);146- if (!result)147- goto error;148149- down(&ctx_id_mutex);150- result = idr_get_new_above(&ctx_id_table, ctx, ctx_id_rover, &ctx->id);151- up(&ctx_id_mutex);152-153- if (result == -EAGAIN)154- goto retry;155 if (result)156 goto error;1570158 ucm_dbg("Allocated CM ID <%d>\n", ctx->id);159-160 return ctx;161-error:162- list_del(&ctx->file_list);163- kfree(ctx);16400165 return NULL;166}167/*···193 kpath->packet_life_time_selector;194}195196-static void ib_ucm_event_req_get(struct ib_ucm_context *ctx,197- struct ib_ucm_req_event_resp *ureq,198 struct ib_cm_req_event_param *kreq)199{200- ureq->listen_id = ctx->id;201-202 ureq->remote_ca_guid = kreq->remote_ca_guid;203 ureq->remote_qkey = kreq->remote_qkey;204 ureq->remote_qpn = kreq->remote_qpn;···230 urep->srq = krep->srq;231}232233-static void ib_ucm_event_sidr_req_get(struct ib_ucm_context *ctx,234- struct ib_ucm_sidr_req_event_resp *ureq,235- struct ib_cm_sidr_req_event_param *kreq)236-{237- ureq->listen_id = ctx->id;238- ureq->pkey = kreq->pkey;239-}240-241static void ib_ucm_event_sidr_rep_get(struct ib_ucm_sidr_rep_event_resp *urep,242 struct ib_cm_sidr_rep_event_param *krep)243{···238 urep->qpn = krep->qpn;239};240241-static int ib_ucm_event_process(struct ib_ucm_context *ctx,242- struct ib_cm_event *evt,243 struct ib_ucm_event *uvt)244{245 void *info = NULL;246247 switch (evt->event) {248 case IB_CM_REQ_RECEIVED:249- ib_ucm_event_req_get(ctx, &uvt->resp.u.req_resp,250 &evt->param.req_rcvd);251 uvt->data_len = IB_CM_REQ_PRIVATE_DATA_SIZE;252 uvt->resp.present = IB_UCM_PRES_PRIMARY;···293 info = evt->param.apr_rcvd.apr_info;294 break;295 case IB_CM_SIDR_REQ_RECEIVED:296- ib_ucm_event_sidr_req_get(ctx, &uvt->resp.u.sidr_req_resp,297- &evt->param.sidr_req_rcvd);298 uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE;299 break;300 case IB_CM_SIDR_REP_RECEIVED:···340 struct ib_ucm_event *uevent;341 struct ib_ucm_context *ctx;342 int result = 0;343- int id;344345 ctx = cm_id->context;346-347- if (event->event == IB_CM_REQ_RECEIVED ||348- event->event == IB_CM_SIDR_REQ_RECEIVED)349- id = IB_UCM_CM_ID_INVALID;350- else351- id = ctx->id;352353 uevent = kmalloc(sizeof(*uevent), GFP_KERNEL);354 if (!uevent)355 goto err1;356357 memset(uevent, 0, sizeof(*uevent));358- uevent->resp.id = id;000359 uevent->resp.event = event->event;360361- result = ib_ucm_event_process(ctx, event, uevent);362 if (result)363 goto err2;364-365- uevent->ctx = ctx;366- uevent->cm_id = (id == IB_UCM_CM_ID_INVALID) ? cm_id : NULL;367368 down(&ctx->file->mutex);369 list_add_tail(&uevent->file_list, &ctx->file->events);···369 kfree(uevent);370err1:371 /* Destroy new cm_id's */372- return (id == IB_UCM_CM_ID_INVALID);373}374375static ssize_t ib_ucm_event(struct ib_ucm_file *file,···378{379 struct ib_ucm_context *ctx;380 struct ib_ucm_event_get cmd;381- struct ib_ucm_event *uevent = NULL;382 int result = 0;383 DEFINE_WAIT(wait);384···391 * wait392 */393 down(&file->mutex);394-395 while (list_empty(&file->events)) {396397 if (file->filp->f_flags & O_NONBLOCK) {···417418 uevent = list_entry(file->events.next, struct ib_ucm_event, file_list);419420- if (!uevent->cm_id)421- goto user;0000422423- ctx = ib_ucm_ctx_alloc(file);424- if (!ctx) {425- result = -ENOMEM;426- goto done;427 }428429- ctx->cm_id = uevent->cm_id;430- ctx->cm_id->context = ctx;431-432- uevent->resp.id = ctx->id;433-434-user:435 if (copy_to_user((void __user *)(unsigned long)cmd.response,436 &uevent->resp, sizeof(uevent->resp))) {437 result = -EFAULT;···436 }437438 if (uevent->data) {439-440 if (cmd.data_len < uevent->data_len) {441 result = -ENOMEM;442 goto done;443 }444-445 if (copy_to_user((void __user *)(unsigned long)cmd.data,446 uevent->data, uevent->data_len)) {447 result = -EFAULT;···448 }449450 if (uevent->info) {451-452 if (cmd.info_len < uevent->info_len) {453 result = -ENOMEM;454 goto done;455 }456-457 if (copy_to_user((void __user *)(unsigned long)cmd.info,458 uevent->info, uevent->info_len)) {459 result = -EFAULT;···461462 list_del(&uevent->file_list);463 list_del(&uevent->ctx_list);0464465 kfree(uevent->data);466 kfree(uevent->info);···493 if (!ctx)494 return -ENOMEM;4950496 ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, ctx);497 if (IS_ERR(ctx->cm_id)) {498 result = PTR_ERR(ctx->cm_id);···510 return 0;511512err:513- ib_ucm_destroy_ctx(file, ctx->id);0000000514 return result;515}516···526 int in_len, int out_len)527{528 struct ib_ucm_destroy_id cmd;000000529530 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))531 return -EFAULT;532533- return ib_ucm_destroy_ctx(file, cmd.id);000000000000000000000000000534}535536static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,···594 &resp, sizeof(resp)))595 result = -EFAULT;59600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000597 ib_ucm_ctx_put(ctx);598 return result;599}···889890 ctx = ib_ucm_ctx_get(file, cmd.id);891 if (!IS_ERR(ctx)) {0892 result = ib_send_cm_rep(ctx->cm_id, ¶m);893 ib_ucm_ctx_put(ctx);894 } else···1168 [IB_USER_CM_CMD_SEND_SIDR_REQ] = ib_ucm_send_sidr_req,1169 [IB_USER_CM_CMD_SEND_SIDR_REP] = ib_ucm_send_sidr_rep,1170 [IB_USER_CM_CMD_EVENT] = ib_ucm_event,01171};11721173static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,···12441245 down(&file->mutex);1246 while (!list_empty(&file->ctxs)) {1247-1248 ctx = list_entry(file->ctxs.next,1249 struct ib_ucm_context, file_list);1250-1251 up(&file->mutex);1252- ib_ucm_destroy_ctx(file, ctx->id);000000001253 down(&file->mutex);1254 }1255 up(&file->mutex);
···7273static struct semaphore ctx_id_mutex;74static struct idr ctx_id_table;07576static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)77{···97 wake_up(&ctx->wait);98}99100+static inline int ib_ucm_new_cm_id(int event)101{102+ return event == IB_CM_REQ_RECEIVED || event == IB_CM_SIDR_REQ_RECEIVED;103+}104+105+static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx)106+{107 struct ib_ucm_event *uevent;108109+ down(&ctx->file->mutex);000000000000000000000110 list_del(&ctx->file_list);111 while (!list_empty(&ctx->events)) {112···133 list_del(&uevent->ctx_list);134135 /* clear incoming connections. */136+ if (ib_ucm_new_cm_id(uevent->resp.event))137 ib_destroy_cm_id(uevent->cm_id);138139 kfree(uevent);140 }141+ up(&ctx->file->mutex);000142}143144static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)···153 if (!ctx)154 return NULL;155156+ memset(ctx, 0, sizeof *ctx);157 atomic_set(&ctx->ref, 1);158 init_waitqueue_head(&ctx->wait);159 ctx->file = file;0160 INIT_LIST_HEAD(&ctx->events);161162+ do {163+ result = idr_pre_get(&ctx_id_table, GFP_KERNEL);164+ if (!result)165+ goto error;166167+ down(&ctx_id_mutex);168+ result = idr_get_new(&ctx_id_table, ctx, &ctx->id);169+ up(&ctx_id_mutex);170+ } while (result == -EAGAIN);0171000000172 if (result)173 goto error;174175+ list_add_tail(&ctx->file_list, &file->ctxs);176 ucm_dbg("Allocated CM ID <%d>\n", ctx->id);0177 return ctx;000178179+error:180+ kfree(ctx);181 return NULL;182}183/*···219 kpath->packet_life_time_selector;220}221222+static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq,0223 struct ib_cm_req_event_param *kreq)224{00225 ureq->remote_ca_guid = kreq->remote_ca_guid;226 ureq->remote_qkey = kreq->remote_qkey;227 ureq->remote_qpn = kreq->remote_qpn;···259 urep->srq = krep->srq;260}26100000000262static void ib_ucm_event_sidr_rep_get(struct ib_ucm_sidr_rep_event_resp *urep,263 struct ib_cm_sidr_rep_event_param *krep)264{···275 urep->qpn = krep->qpn;276};277278+static int ib_ucm_event_process(struct ib_cm_event *evt,0279 struct ib_ucm_event *uvt)280{281 void *info = NULL;282283 switch (evt->event) {284 case IB_CM_REQ_RECEIVED:285+ ib_ucm_event_req_get(&uvt->resp.u.req_resp,286 &evt->param.req_rcvd);287 uvt->data_len = IB_CM_REQ_PRIVATE_DATA_SIZE;288 uvt->resp.present = IB_UCM_PRES_PRIMARY;···331 info = evt->param.apr_rcvd.apr_info;332 break;333 case IB_CM_SIDR_REQ_RECEIVED:334+ uvt->resp.u.sidr_req_resp.pkey = 335+ evt->param.sidr_req_rcvd.pkey;336 uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE;337 break;338 case IB_CM_SIDR_REP_RECEIVED:···378 struct ib_ucm_event *uevent;379 struct ib_ucm_context *ctx;380 int result = 0;0381382 ctx = cm_id->context;000000383384 uevent = kmalloc(sizeof(*uevent), GFP_KERNEL);385 if (!uevent)386 goto err1;387388 memset(uevent, 0, sizeof(*uevent));389+ uevent->ctx = ctx;390+ uevent->cm_id = cm_id;391+ uevent->resp.uid = ctx->uid;392+ uevent->resp.id = ctx->id;393 uevent->resp.event = event->event;394395+ result = ib_ucm_event_process(event, uevent);396 if (result)397 goto err2;000398399 down(&ctx->file->mutex);400 list_add_tail(&uevent->file_list, &ctx->file->events);···414 kfree(uevent);415err1:416 /* Destroy new cm_id's */417+ return ib_ucm_new_cm_id(event->event);418}419420static ssize_t ib_ucm_event(struct ib_ucm_file *file,···423{424 struct ib_ucm_context *ctx;425 struct ib_ucm_event_get cmd;426+ struct ib_ucm_event *uevent;427 int result = 0;428 DEFINE_WAIT(wait);429···436 * wait437 */438 down(&file->mutex);0439 while (list_empty(&file->events)) {440441 if (file->filp->f_flags & O_NONBLOCK) {···463464 uevent = list_entry(file->events.next, struct ib_ucm_event, file_list);465466+ if (ib_ucm_new_cm_id(uevent->resp.event)) {467+ ctx = ib_ucm_ctx_alloc(file);468+ if (!ctx) {469+ result = -ENOMEM;470+ goto done;471+ }472473+ ctx->cm_id = uevent->cm_id;474+ ctx->cm_id->context = ctx;475+ uevent->resp.id = ctx->id;0476 }477000000478 if (copy_to_user((void __user *)(unsigned long)cmd.response,479 &uevent->resp, sizeof(uevent->resp))) {480 result = -EFAULT;···485 }486487 if (uevent->data) {0488 if (cmd.data_len < uevent->data_len) {489 result = -ENOMEM;490 goto done;491 }0492 if (copy_to_user((void __user *)(unsigned long)cmd.data,493 uevent->data, uevent->data_len)) {494 result = -EFAULT;···499 }500501 if (uevent->info) {0502 if (cmd.info_len < uevent->info_len) {503 result = -ENOMEM;504 goto done;505 }0506 if (copy_to_user((void __user *)(unsigned long)cmd.info,507 uevent->info, uevent->info_len)) {508 result = -EFAULT;···514515 list_del(&uevent->file_list);516 list_del(&uevent->ctx_list);517+ uevent->ctx->events_reported++;518519 kfree(uevent->data);520 kfree(uevent->info);···545 if (!ctx)546 return -ENOMEM;547548+ ctx->uid = cmd.uid;549 ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, ctx);550 if (IS_ERR(ctx->cm_id)) {551 result = PTR_ERR(ctx->cm_id);···561 return 0;562563err:564+ down(&ctx_id_mutex);565+ idr_remove(&ctx_id_table, ctx->id);566+ up(&ctx_id_mutex);567+568+ if (!IS_ERR(ctx->cm_id))569+ ib_destroy_cm_id(ctx->cm_id);570+571+ kfree(ctx);572 return result;573}574···570 int in_len, int out_len)571{572 struct ib_ucm_destroy_id cmd;573+ struct ib_ucm_destroy_id_resp resp;574+ struct ib_ucm_context *ctx;575+ int result = 0;576+577+ if (out_len < sizeof(resp))578+ return -ENOSPC;579580 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))581 return -EFAULT;582583+ down(&ctx_id_mutex);584+ ctx = idr_find(&ctx_id_table, cmd.id);585+ if (!ctx)586+ ctx = ERR_PTR(-ENOENT);587+ else if (ctx->file != file)588+ ctx = ERR_PTR(-EINVAL);589+ else590+ idr_remove(&ctx_id_table, ctx->id);591+ up(&ctx_id_mutex);592+593+ if (IS_ERR(ctx))594+ return PTR_ERR(ctx);595+596+ atomic_dec(&ctx->ref);597+ wait_event(ctx->wait, !atomic_read(&ctx->ref));598+599+ /* No new events will be generated after destroying the cm_id. */600+ ib_destroy_cm_id(ctx->cm_id);601+ /* Cleanup events not yet reported to the user. */602+ ib_ucm_cleanup_events(ctx);603+604+ resp.events_reported = ctx->events_reported;605+ if (copy_to_user((void __user *)(unsigned long)cmd.response,606+ &resp, sizeof(resp)))607+ result = -EFAULT;608+609+ kfree(ctx);610+ return result;611}612613static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,···605 &resp, sizeof(resp)))606 result = -EFAULT;607608+ ib_ucm_ctx_put(ctx);609+ return result;610+}611+612+static void ib_ucm_copy_ah_attr(struct ib_ucm_ah_attr *dest_attr,613+ struct ib_ah_attr *src_attr)614+{615+ memcpy(dest_attr->grh_dgid, src_attr->grh.dgid.raw,616+ sizeof src_attr->grh.dgid);617+ dest_attr->grh_flow_label = src_attr->grh.flow_label;618+ dest_attr->grh_sgid_index = src_attr->grh.sgid_index;619+ dest_attr->grh_hop_limit = src_attr->grh.hop_limit;620+ dest_attr->grh_traffic_class = src_attr->grh.traffic_class;621+622+ dest_attr->dlid = src_attr->dlid;623+ dest_attr->sl = src_attr->sl;624+ dest_attr->src_path_bits = src_attr->src_path_bits;625+ dest_attr->static_rate = src_attr->static_rate;626+ dest_attr->is_global = (src_attr->ah_flags & IB_AH_GRH);627+ dest_attr->port_num = src_attr->port_num;628+}629+630+static void ib_ucm_copy_qp_attr(struct ib_ucm_init_qp_attr_resp *dest_attr,631+ struct ib_qp_attr *src_attr)632+{633+ dest_attr->cur_qp_state = src_attr->cur_qp_state;634+ dest_attr->path_mtu = src_attr->path_mtu;635+ dest_attr->path_mig_state = src_attr->path_mig_state;636+ dest_attr->qkey = src_attr->qkey;637+ dest_attr->rq_psn = src_attr->rq_psn;638+ dest_attr->sq_psn = src_attr->sq_psn;639+ dest_attr->dest_qp_num = src_attr->dest_qp_num;640+ dest_attr->qp_access_flags = src_attr->qp_access_flags;641+642+ dest_attr->max_send_wr = src_attr->cap.max_send_wr;643+ dest_attr->max_recv_wr = src_attr->cap.max_recv_wr;644+ dest_attr->max_send_sge = src_attr->cap.max_send_sge;645+ dest_attr->max_recv_sge = src_attr->cap.max_recv_sge;646+ dest_attr->max_inline_data = src_attr->cap.max_inline_data;647+648+ ib_ucm_copy_ah_attr(&dest_attr->ah_attr, &src_attr->ah_attr);649+ ib_ucm_copy_ah_attr(&dest_attr->alt_ah_attr, &src_attr->alt_ah_attr);650+651+ dest_attr->pkey_index = src_attr->pkey_index;652+ dest_attr->alt_pkey_index = src_attr->alt_pkey_index;653+ dest_attr->en_sqd_async_notify = src_attr->en_sqd_async_notify;654+ dest_attr->sq_draining = src_attr->sq_draining;655+ dest_attr->max_rd_atomic = src_attr->max_rd_atomic;656+ dest_attr->max_dest_rd_atomic = src_attr->max_dest_rd_atomic;657+ dest_attr->min_rnr_timer = src_attr->min_rnr_timer;658+ dest_attr->port_num = src_attr->port_num;659+ dest_attr->timeout = src_attr->timeout;660+ dest_attr->retry_cnt = src_attr->retry_cnt;661+ dest_attr->rnr_retry = src_attr->rnr_retry;662+ dest_attr->alt_port_num = src_attr->alt_port_num;663+ dest_attr->alt_timeout = src_attr->alt_timeout;664+}665+666+static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file,667+ const char __user *inbuf,668+ int in_len, int out_len)669+{670+ struct ib_ucm_init_qp_attr_resp resp;671+ struct ib_ucm_init_qp_attr cmd;672+ struct ib_ucm_context *ctx;673+ struct ib_qp_attr qp_attr;674+ int result = 0;675+676+ if (out_len < sizeof(resp))677+ return -ENOSPC;678+679+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))680+ return -EFAULT;681+682+ ctx = ib_ucm_ctx_get(file, cmd.id);683+ if (IS_ERR(ctx))684+ return PTR_ERR(ctx);685+686+ resp.qp_attr_mask = 0;687+ memset(&qp_attr, 0, sizeof qp_attr);688+ qp_attr.qp_state = cmd.qp_state;689+ result = ib_cm_init_qp_attr(ctx->cm_id, &qp_attr, &resp.qp_attr_mask);690+ if (result)691+ goto out;692+693+ ib_ucm_copy_qp_attr(&resp, &qp_attr);694+695+ if (copy_to_user((void __user *)(unsigned long)cmd.response,696+ &resp, sizeof(resp)))697+ result = -EFAULT;698+699+out:700 ib_ucm_ctx_put(ctx);701 return result;702}···808809 ctx = ib_ucm_ctx_get(file, cmd.id);810 if (!IS_ERR(ctx)) {811+ ctx->uid = cmd.uid;812 result = ib_send_cm_rep(ctx->cm_id, ¶m);813 ib_ucm_ctx_put(ctx);814 } else···1086 [IB_USER_CM_CMD_SEND_SIDR_REQ] = ib_ucm_send_sidr_req,1087 [IB_USER_CM_CMD_SEND_SIDR_REP] = ib_ucm_send_sidr_rep,1088 [IB_USER_CM_CMD_EVENT] = ib_ucm_event,1089+ [IB_USER_CM_CMD_INIT_QP_ATTR] = ib_ucm_init_qp_attr,1090};10911092static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,···11611162 down(&file->mutex);1163 while (!list_empty(&file->ctxs)) {01164 ctx = list_entry(file->ctxs.next,1165 struct ib_ucm_context, file_list);01166 up(&file->mutex);1167+1168+ down(&ctx_id_mutex);1169+ idr_remove(&ctx_id_table, ctx->id);1170+ up(&ctx_id_mutex);1171+1172+ ib_destroy_cm_id(ctx->cm_id);1173+ ib_ucm_cleanup_events(ctx);1174+ kfree(ctx);1175+1176 down(&file->mutex);1177 }1178 up(&file->mutex);
+4-7
drivers/infiniband/core/ucm.h
···1/*2 * Copyright (c) 2005 Topspin Communications. All rights reserved.03 *4 * This software is available to you under a choice of one of two5 * licenses. You may choose to be licensed under the terms of the GNU···44#include <rdma/ib_cm.h>45#include <rdma/ib_user_cm.h>4647-#define IB_UCM_CM_ID_INVALID 0xffffffff48-49struct ib_ucm_file {50 struct semaphore mutex;51 struct file *filp;···57 int id;58 wait_queue_head_t wait;59 atomic_t ref;06061 struct ib_ucm_file *file;62 struct ib_cm_id *cm_id;06364 struct list_head events; /* list of pending events. */65 struct list_head file_list; /* member in file ctx list */···72 struct list_head file_list; /* member in file event list */73 struct list_head ctx_list; /* member in ctx event list */74075 struct ib_ucm_event_resp resp;76 void *data;77 void *info;78 int data_len;79 int info_len;80- /*81- * new connection identifiers needs to be saved until82- * userspace can get a handle on them.83- */84- struct ib_cm_id *cm_id;85};8687#endif /* UCM_H */
···1/*2 * Copyright (c) 2005 Topspin Communications. All rights reserved.3+ * Copyright (c) 2005 Intel Corporation. All rights reserved.4 *5 * This software is available to you under a choice of one of two6 * licenses. You may choose to be licensed under the terms of the GNU···43#include <rdma/ib_cm.h>44#include <rdma/ib_user_cm.h>450046struct ib_ucm_file {47 struct semaphore mutex;48 struct file *filp;···58 int id;59 wait_queue_head_t wait;60 atomic_t ref;61+ int events_reported;6263 struct ib_ucm_file *file;64 struct ib_cm_id *cm_id;65+ __u64 uid;6667 struct list_head events; /* list of pending events. */68 struct list_head file_list; /* member in file ctx list */···71 struct list_head file_list; /* member in file event list */72 struct list_head ctx_list; /* member in ctx event list */7374+ struct ib_cm_id *cm_id;75 struct ib_ucm_event_resp resp;76 void *data;77 void *info;78 int data_len;79 int info_len;0000080};8182#endif /* UCM_H */
···173 u8 data[216];174};175000000000000000000000176/**177 * ib_mad_send_buf - MAD data buffer and work request for sends.178 * @mad: References an allocated MAD data buffer. The size of the data
···173 u8 data[216];174};175176+struct ib_class_port_info177+{178+ u8 base_version;179+ u8 class_version;180+ __be16 capability_mask;181+ u8 reserved[3];182+ u8 resp_time_value;183+ u8 redirect_gid[16];184+ __be32 redirect_tcslfl;185+ __be16 redirect_lid;186+ __be16 redirect_pkey;187+ __be32 redirect_qp;188+ __be32 redirect_qkey;189+ u8 trap_gid[16];190+ __be32 trap_tcslfl;191+ __be16 trap_lid;192+ __be16 trap_pkey;193+ __be32 trap_hlqp;194+ __be32 trap_qkey;195+};196+197/**198 * ib_mad_send_buf - MAD data buffer and work request for sends.199 * @mad: References an allocated MAD data buffer. The size of the data
···1/*2 * Copyright (c) 2005 Topspin Communications. All rights reserved.03 *4 * This software is available to you under a choice of one of two5 * licenses. You may choose to be licensed under the terms of the GNU···3839#include <linux/types.h>4041-#define IB_USER_CM_ABI_VERSION 14243enum {44 IB_USER_CM_CMD_CREATE_ID,···61 IB_USER_CM_CMD_SEND_SIDR_REP,6263 IB_USER_CM_CMD_EVENT,064};65/*66 * command ABI structures.···73};7475struct ib_ucm_create_id {076 __u64 response;77};78···82};8384struct ib_ucm_destroy_id {085 __u32 id;000086};8788struct ib_ucm_attr_id {···100 __be64 service_mask;101 __be32 local_id;102 __be32 remote_id;0000000000000000000000000000000000000000000000000000000000103};104105struct ib_ucm_listen {···223};224225struct ib_ucm_rep {0226 __u64 data;227 __u32 id;228 __u32 qpn;···299};300301struct ib_ucm_req_event_resp {302- __u32 listen_id;303 /* device */304 /* port */305 struct ib_ucm_path_rec primary_path;···353};354355struct ib_ucm_sidr_req_event_resp {356- __u32 listen_id;357 /* device */358 /* port */359 __u16 pkey;···372#define IB_UCM_PRES_ALTERNATE 0x08373374struct ib_ucm_event_resp {0375 __u32 id;376 __u32 event;377 __u32 present;
···1/*2 * Copyright (c) 2005 Topspin Communications. All rights reserved.3+ * Copyright (c) 2005 Intel Corporation. All rights reserved.4 *5 * This software is available to you under a choice of one of two6 * licenses. You may choose to be licensed under the terms of the GNU···3738#include <linux/types.h>3940+#define IB_USER_CM_ABI_VERSION 24142enum {43 IB_USER_CM_CMD_CREATE_ID,···60 IB_USER_CM_CMD_SEND_SIDR_REP,6162 IB_USER_CM_CMD_EVENT,63+ IB_USER_CM_CMD_INIT_QP_ATTR,64};65/*66 * command ABI structures.···71};7273struct ib_ucm_create_id {74+ __u64 uid;75 __u64 response;76};77···79};8081struct ib_ucm_destroy_id {82+ __u64 response;83 __u32 id;84+};85+86+struct ib_ucm_destroy_id_resp {87+ __u32 events_reported;88};8990struct ib_ucm_attr_id {···92 __be64 service_mask;93 __be32 local_id;94 __be32 remote_id;95+};96+97+struct ib_ucm_init_qp_attr {98+ __u64 response;99+ __u32 id;100+ __u32 qp_state;101+};102+103+struct ib_ucm_ah_attr {104+ __u8 grh_dgid[16];105+ __u32 grh_flow_label;106+ __u16 dlid;107+ __u16 reserved;108+ __u8 grh_sgid_index;109+ __u8 grh_hop_limit;110+ __u8 grh_traffic_class;111+ __u8 sl;112+ __u8 src_path_bits;113+ __u8 static_rate;114+ __u8 is_global;115+ __u8 port_num;116+};117+118+struct ib_ucm_init_qp_attr_resp {119+ __u32 qp_attr_mask;120+ __u32 qp_state;121+ __u32 cur_qp_state;122+ __u32 path_mtu;123+ __u32 path_mig_state;124+ __u32 qkey;125+ __u32 rq_psn;126+ __u32 sq_psn;127+ __u32 dest_qp_num;128+ __u32 qp_access_flags;129+130+ struct ib_ucm_ah_attr ah_attr;131+ struct ib_ucm_ah_attr alt_ah_attr;132+133+ /* ib_qp_cap */134+ __u32 max_send_wr;135+ __u32 max_recv_wr;136+ __u32 max_send_sge;137+ __u32 max_recv_sge;138+ __u32 max_inline_data;139+140+ __u16 pkey_index;141+ __u16 alt_pkey_index;142+ __u8 en_sqd_async_notify;143+ __u8 sq_draining;144+ __u8 max_rd_atomic;145+ __u8 max_dest_rd_atomic;146+ __u8 min_rnr_timer;147+ __u8 port_num;148+ __u8 timeout;149+ __u8 retry_cnt;150+ __u8 rnr_retry;151+ __u8 alt_port_num;152+ __u8 alt_timeout;153};154155struct ib_ucm_listen {···157};158159struct ib_ucm_rep {160+ __u64 uid;161 __u64 data;162 __u32 id;163 __u32 qpn;···232};233234struct ib_ucm_req_event_resp {0235 /* device */236 /* port */237 struct ib_ucm_path_rec primary_path;···287};288289struct ib_ucm_sidr_req_event_resp {0290 /* device */291 /* port */292 __u16 pkey;···307#define IB_UCM_PRES_ALTERNATE 0x08308309struct ib_ucm_event_resp {310+ __u64 uid;311 __u32 id;312 __u32 event;313 __u32 present;
+20-1
include/rdma/ib_user_verbs.h
···42 * Increment this value if any changes that break userspace ABI43 * compatibility are made.44 */45-#define IB_USER_VERBS_ABI_VERSION 14647enum {48 IB_USER_VERBS_CMD_QUERY_PARAMS,···292};293294struct ib_uverbs_destroy_cq {0295 __u32 cq_handle;000000296};297298struct ib_uverbs_create_qp {···379};380381struct ib_uverbs_destroy_qp {0382 __u32 qp_handle;00000383};384385struct ib_uverbs_attach_mcast {···429};430431struct ib_uverbs_destroy_srq {0432 __u32 srq_handle;00000433};434435#endif /* IB_USER_VERBS_H */