linux/drivers/infiniband/core/ucma.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2005-2006 Intel Corporation.  All rights reserved.
   3 *
   4 * This software is available to you under a choice of one of two
   5 * licenses.  You may choose to be licensed under the terms of the GNU
   6 * General Public License (GPL) Version 2, available from the file
   7 * COPYING in the main directory of this source tree, or the
   8 * OpenIB.org BSD license below:
   9 *
  10 *     Redistribution and use in source and binary forms, with or
  11 *     without modification, are permitted provided that the following
  12 *     conditions are met:
  13 *
  14 *      - Redistributions of source code must retain the above
  15 *      copyright notice, this list of conditions and the following
  16 *      disclaimer.
  17 *
  18 *      - Redistributions in binary form must reproduce the above
  19 *      copyright notice, this list of conditions and the following
  20 *      disclaimer in the documentation and/or other materials
  21 *      provided with the distribution.
  22 *
  23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30 * SOFTWARE.
  31 */
  32
  33#include <linux/completion.h>
  34#include <linux/file.h>
  35#include <linux/mutex.h>
  36#include <linux/poll.h>
  37#include <linux/sched.h>
  38#include <linux/idr.h>
  39#include <linux/in.h>
  40#include <linux/in6.h>
  41#include <linux/miscdevice.h>
  42#include <linux/slab.h>
  43#include <linux/sysctl.h>
  44#include <linux/module.h>
  45
  46#include <rdma/rdma_user_cm.h>
  47#include <rdma/ib_marshall.h>
  48#include <rdma/rdma_cm.h>
  49#include <rdma/rdma_cm_ib.h>
  50
  51MODULE_AUTHOR("Sean Hefty");
  52MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
  53MODULE_LICENSE("Dual BSD/GPL");
  54
  55static unsigned int max_backlog = 1024;
  56
  57static struct ctl_table_header *ucma_ctl_table_hdr;
  58static ctl_table ucma_ctl_table[] = {
  59        {
  60                .procname       = "max_backlog",
  61                .data           = &max_backlog,
  62                .maxlen         = sizeof max_backlog,
  63                .mode           = 0644,
  64                .proc_handler   = proc_dointvec,
  65        },
  66        { }
  67};
  68
  69struct ucma_file {
  70        struct mutex            mut;
  71        struct file             *filp;
  72        struct list_head        ctx_list;
  73        struct list_head        event_list;
  74        wait_queue_head_t       poll_wait;
  75};
  76
  77struct ucma_context {
  78        int                     id;
  79        struct completion       comp;
  80        atomic_t                ref;
  81        int                     events_reported;
  82        int                     backlog;
  83
  84        struct ucma_file        *file;
  85        struct rdma_cm_id       *cm_id;
  86        u64                     uid;
  87
  88        struct list_head        list;
  89        struct list_head        mc_list;
  90};
  91
  92struct ucma_multicast {
  93        struct ucma_context     *ctx;
  94        int                     id;
  95        int                     events_reported;
  96
  97        u64                     uid;
  98        struct list_head        list;
  99        struct sockaddr_storage addr;
 100};
 101
 102struct ucma_event {
 103        struct ucma_context     *ctx;
 104        struct ucma_multicast   *mc;
 105        struct list_head        list;
 106        struct rdma_cm_id       *cm_id;
 107        struct rdma_ucm_event_resp resp;
 108};
 109
 110static DEFINE_MUTEX(mut);
 111static DEFINE_IDR(ctx_idr);
 112static DEFINE_IDR(multicast_idr);
 113
 114static inline struct ucma_context *_ucma_find_context(int id,
 115                                                      struct ucma_file *file)
 116{
 117        struct ucma_context *ctx;
 118
 119        ctx = idr_find(&ctx_idr, id);
 120        if (!ctx)
 121                ctx = ERR_PTR(-ENOENT);
 122        else if (ctx->file != file)
 123                ctx = ERR_PTR(-EINVAL);
 124        return ctx;
 125}
 126
 127static struct ucma_context *ucma_get_ctx(struct ucma_file *file, int id)
 128{
 129        struct ucma_context *ctx;
 130
 131        mutex_lock(&mut);
 132        ctx = _ucma_find_context(id, file);
 133        if (!IS_ERR(ctx))
 134                atomic_inc(&ctx->ref);
 135        mutex_unlock(&mut);
 136        return ctx;
 137}
 138
 139static void ucma_put_ctx(struct ucma_context *ctx)
 140{
 141        if (atomic_dec_and_test(&ctx->ref))
 142                complete(&ctx->comp);
 143}
 144
 145static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
 146{
 147        struct ucma_context *ctx;
 148        int ret;
 149
 150        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 151        if (!ctx)
 152                return NULL;
 153
 154        atomic_set(&ctx->ref, 1);
 155        init_completion(&ctx->comp);
 156        INIT_LIST_HEAD(&ctx->mc_list);
 157        ctx->file = file;
 158
 159        do {
 160                ret = idr_pre_get(&ctx_idr, GFP_KERNEL);
 161                if (!ret)
 162                        goto error;
 163
 164                mutex_lock(&mut);
 165                ret = idr_get_new(&ctx_idr, ctx, &ctx->id);
 166                mutex_unlock(&mut);
 167        } while (ret == -EAGAIN);
 168
 169        if (ret)
 170                goto error;
 171
 172        list_add_tail(&ctx->list, &file->ctx_list);
 173        return ctx;
 174
 175error:
 176        kfree(ctx);
 177        return NULL;
 178}
 179
 180static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
 181{
 182        struct ucma_multicast *mc;
 183        int ret;
 184
 185        mc = kzalloc(sizeof(*mc), GFP_KERNEL);
 186        if (!mc)
 187                return NULL;
 188
 189        do {
 190                ret = idr_pre_get(&multicast_idr, GFP_KERNEL);
 191                if (!ret)
 192                        goto error;
 193
 194                mutex_lock(&mut);
 195                ret = idr_get_new(&multicast_idr, mc, &mc->id);
 196                mutex_unlock(&mut);
 197        } while (ret == -EAGAIN);
 198
 199        if (ret)
 200                goto error;
 201
 202        mc->ctx = ctx;
 203        list_add_tail(&mc->list, &ctx->mc_list);
 204        return mc;
 205
 206error:
 207        kfree(mc);
 208        return NULL;
 209}
 210
 211static void ucma_copy_conn_event(struct rdma_ucm_conn_param *dst,
 212                                 struct rdma_conn_param *src)
 213{
 214        if (src->private_data_len)
 215                memcpy(dst->private_data, src->private_data,
 216                       src->private_data_len);
 217        dst->private_data_len = src->private_data_len;
 218        dst->responder_resources =src->responder_resources;
 219        dst->initiator_depth = src->initiator_depth;
 220        dst->flow_control = src->flow_control;
 221        dst->retry_count = src->retry_count;
 222        dst->rnr_retry_count = src->rnr_retry_count;
 223        dst->srq = src->srq;
 224        dst->qp_num = src->qp_num;
 225}
 226
 227static void ucma_copy_ud_event(struct rdma_ucm_ud_param *dst,
 228                               struct rdma_ud_param *src)
 229{
 230        if (src->private_data_len)
 231                memcpy(dst->private_data, src->private_data,
 232                       src->private_data_len);
 233        dst->private_data_len = src->private_data_len;
 234        ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr);
 235        dst->qp_num = src->qp_num;
 236        dst->qkey = src->qkey;
 237}
 238
 239static void ucma_set_event_context(struct ucma_context *ctx,
 240                                   struct rdma_cm_event *event,
 241                                   struct ucma_event *uevent)
 242{
 243        uevent->ctx = ctx;
 244        switch (event->event) {
 245        case RDMA_CM_EVENT_MULTICAST_JOIN:
 246        case RDMA_CM_EVENT_MULTICAST_ERROR:
 247                uevent->mc = (struct ucma_multicast *)
 248                             event->param.ud.private_data;
 249                uevent->resp.uid = uevent->mc->uid;
 250                uevent->resp.id = uevent->mc->id;
 251                break;
 252        default:
 253                uevent->resp.uid = ctx->uid;
 254                uevent->resp.id = ctx->id;
 255                break;
 256        }
 257}
 258
 259static int ucma_event_handler(struct rdma_cm_id *cm_id,
 260                              struct rdma_cm_event *event)
 261{
 262        struct ucma_event *uevent;
 263        struct ucma_context *ctx = cm_id->context;
 264        int ret = 0;
 265
 266        uevent = kzalloc(sizeof(*uevent), GFP_KERNEL);
 267        if (!uevent)
 268                return event->event == RDMA_CM_EVENT_CONNECT_REQUEST;
 269
 270        mutex_lock(&ctx->file->mut);
 271        uevent->cm_id = cm_id;
 272        ucma_set_event_context(ctx, event, uevent);
 273        uevent->resp.event = event->event;
 274        uevent->resp.status = event->status;
 275        if (cm_id->qp_type == IB_QPT_UD)
 276                ucma_copy_ud_event(&uevent->resp.param.ud, &event->param.ud);
 277        else
 278                ucma_copy_conn_event(&uevent->resp.param.conn,
 279                                     &event->param.conn);
 280
 281        if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) {
 282                if (!ctx->backlog) {
 283                        ret = -ENOMEM;
 284                        kfree(uevent);
 285                        goto out;
 286                }
 287                ctx->backlog--;
 288        } else if (!ctx->uid) {
 289                /*
 290                 * We ignore events for new connections until userspace has set
 291                 * their context.  This can only happen if an error occurs on a
 292                 * new connection before the user accepts it.  This is okay,
 293                 * since the accept will just fail later.
 294                 */
 295                kfree(uevent);
 296                goto out;
 297        }
 298
 299        list_add_tail(&uevent->list, &ctx->file->event_list);
 300        wake_up_interruptible(&ctx->file->poll_wait);
 301out:
 302        mutex_unlock(&ctx->file->mut);
 303        return ret;
 304}
 305
 306static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf,
 307                              int in_len, int out_len)
 308{
 309        struct ucma_context *ctx;
 310        struct rdma_ucm_get_event cmd;
 311        struct ucma_event *uevent;
 312        int ret = 0;
 313        DEFINE_WAIT(wait);
 314
 315        if (out_len < sizeof uevent->resp)
 316                return -ENOSPC;
 317
 318        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 319                return -EFAULT;
 320
 321        mutex_lock(&file->mut);
 322        while (list_empty(&file->event_list)) {
 323                mutex_unlock(&file->mut);
 324
 325                if (file->filp->f_flags & O_NONBLOCK)
 326                        return -EAGAIN;
 327
 328                if (wait_event_interruptible(file->poll_wait,
 329                                             !list_empty(&file->event_list)))
 330                        return -ERESTARTSYS;
 331
 332                mutex_lock(&file->mut);
 333        }
 334
 335        uevent = list_entry(file->event_list.next, struct ucma_event, list);
 336
 337        if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST) {
 338                ctx = ucma_alloc_ctx(file);
 339                if (!ctx) {
 340                        ret = -ENOMEM;
 341                        goto done;
 342                }
 343                uevent->ctx->backlog++;
 344                ctx->cm_id = uevent->cm_id;
 345                ctx->cm_id->context = ctx;
 346                uevent->resp.id = ctx->id;
 347        }
 348
 349        if (copy_to_user((void __user *)(unsigned long)cmd.response,
 350                         &uevent->resp, sizeof uevent->resp)) {
 351                ret = -EFAULT;
 352                goto done;
 353        }
 354
 355        list_del(&uevent->list);
 356        uevent->ctx->events_reported++;
 357        if (uevent->mc)
 358                uevent->mc->events_reported++;
 359        kfree(uevent);
 360done:
 361        mutex_unlock(&file->mut);
 362        return ret;
 363}
 364
 365static int ucma_get_qp_type(struct rdma_ucm_create_id *cmd, enum ib_qp_type *qp_type)
 366{
 367        switch (cmd->ps) {
 368        case RDMA_PS_TCP:
 369                *qp_type = IB_QPT_RC;
 370                return 0;
 371        case RDMA_PS_UDP:
 372        case RDMA_PS_IPOIB:
 373                *qp_type = IB_QPT_UD;
 374                return 0;
 375        case RDMA_PS_IB:
 376                *qp_type = cmd->qp_type;
 377                return 0;
 378        default:
 379                return -EINVAL;
 380        }
 381}
 382
 383static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
 384                              int in_len, int out_len)
 385{
 386        struct rdma_ucm_create_id cmd;
 387        struct rdma_ucm_create_id_resp resp;
 388        struct ucma_context *ctx;
 389        enum ib_qp_type qp_type;
 390        int ret;
 391
 392        if (out_len < sizeof(resp))
 393                return -ENOSPC;
 394
 395        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 396                return -EFAULT;
 397
 398        ret = ucma_get_qp_type(&cmd, &qp_type);
 399        if (ret)
 400                return ret;
 401
 402        mutex_lock(&file->mut);
 403        ctx = ucma_alloc_ctx(file);
 404        mutex_unlock(&file->mut);
 405        if (!ctx)
 406                return -ENOMEM;
 407
 408        ctx->uid = cmd.uid;
 409        ctx->cm_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps, qp_type);
 410        if (IS_ERR(ctx->cm_id)) {
 411                ret = PTR_ERR(ctx->cm_id);
 412                goto err1;
 413        }
 414
 415        resp.id = ctx->id;
 416        if (copy_to_user((void __user *)(unsigned long)cmd.response,
 417                         &resp, sizeof(resp))) {
 418                ret = -EFAULT;
 419                goto err2;
 420        }
 421        return 0;
 422
 423err2:
 424        rdma_destroy_id(ctx->cm_id);
 425err1:
 426        mutex_lock(&mut);
 427        idr_remove(&ctx_idr, ctx->id);
 428        mutex_unlock(&mut);
 429        kfree(ctx);
 430        return ret;
 431}
 432
 433static void ucma_cleanup_multicast(struct ucma_context *ctx)
 434{
 435        struct ucma_multicast *mc, *tmp;
 436
 437        mutex_lock(&mut);
 438        list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) {
 439                list_del(&mc->list);
 440                idr_remove(&multicast_idr, mc->id);
 441                kfree(mc);
 442        }
 443        mutex_unlock(&mut);
 444}
 445
 446static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
 447{
 448        struct ucma_event *uevent, *tmp;
 449
 450        list_for_each_entry_safe(uevent, tmp, &mc->ctx->file->event_list, list) {
 451                if (uevent->mc != mc)
 452                        continue;
 453
 454                list_del(&uevent->list);
 455                kfree(uevent);
 456        }
 457}
 458
 459/*
 460 * We cannot hold file->mut when calling rdma_destroy_id() or we can
 461 * deadlock.  We also acquire file->mut in ucma_event_handler(), and
 462 * rdma_destroy_id() will wait until all callbacks have completed.
 463 */
 464static int ucma_free_ctx(struct ucma_context *ctx)
 465{
 466        int events_reported;
 467        struct ucma_event *uevent, *tmp;
 468        LIST_HEAD(list);
 469
 470        /* No new events will be generated after destroying the id. */
 471        rdma_destroy_id(ctx->cm_id);
 472
 473        ucma_cleanup_multicast(ctx);
 474
 475        /* Cleanup events not yet reported to the user. */
 476        mutex_lock(&ctx->file->mut);
 477        list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) {
 478                if (uevent->ctx == ctx)
 479                        list_move_tail(&uevent->list, &list);
 480        }
 481        list_del(&ctx->list);
 482        mutex_unlock(&ctx->file->mut);
 483
 484        list_for_each_entry_safe(uevent, tmp, &list, list) {
 485                list_del(&uevent->list);
 486                if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST)
 487                        rdma_destroy_id(uevent->cm_id);
 488                kfree(uevent);
 489        }
 490
 491        events_reported = ctx->events_reported;
 492        kfree(ctx);
 493        return events_reported;
 494}
 495
 496static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf,
 497                               int in_len, int out_len)
 498{
 499        struct rdma_ucm_destroy_id cmd;
 500        struct rdma_ucm_destroy_id_resp resp;
 501        struct ucma_context *ctx;
 502        int ret = 0;
 503
 504        if (out_len < sizeof(resp))
 505                return -ENOSPC;
 506
 507        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 508                return -EFAULT;
 509
 510        mutex_lock(&mut);
 511        ctx = _ucma_find_context(cmd.id, file);
 512        if (!IS_ERR(ctx))
 513                idr_remove(&ctx_idr, ctx->id);
 514        mutex_unlock(&mut);
 515
 516        if (IS_ERR(ctx))
 517                return PTR_ERR(ctx);
 518
 519        ucma_put_ctx(ctx);
 520        wait_for_completion(&ctx->comp);
 521        resp.events_reported = ucma_free_ctx(ctx);
 522
 523        if (copy_to_user((void __user *)(unsigned long)cmd.response,
 524                         &resp, sizeof(resp)))
 525                ret = -EFAULT;
 526
 527        return ret;
 528}
 529
 530static ssize_t ucma_bind_addr(struct ucma_file *file, const char __user *inbuf,
 531                              int in_len, int out_len)
 532{
 533        struct rdma_ucm_bind_addr cmd;
 534        struct ucma_context *ctx;
 535        int ret;
 536
 537        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 538                return -EFAULT;
 539
 540        ctx = ucma_get_ctx(file, cmd.id);
 541        if (IS_ERR(ctx))
 542                return PTR_ERR(ctx);
 543
 544        ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr);
 545        ucma_put_ctx(ctx);
 546        return ret;
 547}
 548
 549static ssize_t ucma_resolve_addr(struct ucma_file *file,
 550                                 const char __user *inbuf,
 551                                 int in_len, int out_len)
 552{
 553        struct rdma_ucm_resolve_addr cmd;
 554        struct ucma_context *ctx;
 555        int ret;
 556
 557        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 558                return -EFAULT;
 559
 560        ctx = ucma_get_ctx(file, cmd.id);
 561        if (IS_ERR(ctx))
 562                return PTR_ERR(ctx);
 563
 564        ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
 565                                (struct sockaddr *) &cmd.dst_addr,
 566                                cmd.timeout_ms);
 567        ucma_put_ctx(ctx);
 568        return ret;
 569}
 570
 571static ssize_t ucma_resolve_route(struct ucma_file *file,
 572                                  const char __user *inbuf,
 573                                  int in_len, int out_len)
 574{
 575        struct rdma_ucm_resolve_route cmd;
 576        struct ucma_context *ctx;
 577        int ret;
 578
 579        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 580                return -EFAULT;
 581
 582        ctx = ucma_get_ctx(file, cmd.id);
 583        if (IS_ERR(ctx))
 584                return PTR_ERR(ctx);
 585
 586        ret = rdma_resolve_route(ctx->cm_id, cmd.timeout_ms);
 587        ucma_put_ctx(ctx);
 588        return ret;
 589}
 590
 591static void ucma_copy_ib_route(struct rdma_ucm_query_route_resp *resp,
 592                               struct rdma_route *route)
 593{
 594        struct rdma_dev_addr *dev_addr;
 595
 596        resp->num_paths = route->num_paths;
 597        switch (route->num_paths) {
 598        case 0:
 599                dev_addr = &route->addr.dev_addr;
 600                rdma_addr_get_dgid(dev_addr,
 601                                   (union ib_gid *) &resp->ib_route[0].dgid);
 602                rdma_addr_get_sgid(dev_addr,
 603                                   (union ib_gid *) &resp->ib_route[0].sgid);
 604                resp->ib_route[0].pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
 605                break;
 606        case 2:
 607                ib_copy_path_rec_to_user(&resp->ib_route[1],
 608                                         &route->path_rec[1]);
 609                /* fall through */
 610        case 1:
 611                ib_copy_path_rec_to_user(&resp->ib_route[0],
 612                                         &route->path_rec[0]);
 613                break;
 614        default:
 615                break;
 616        }
 617}
 618
 619static void ucma_copy_iboe_route(struct rdma_ucm_query_route_resp *resp,
 620                                 struct rdma_route *route)
 621{
 622        struct rdma_dev_addr *dev_addr;
 623        struct net_device *dev;
 624        u16 vid = 0;
 625
 626        resp->num_paths = route->num_paths;
 627        switch (route->num_paths) {
 628        case 0:
 629                dev_addr = &route->addr.dev_addr;
 630                dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
 631                        if (dev) {
 632                                vid = rdma_vlan_dev_vlan_id(dev);
 633                                dev_put(dev);
 634                        }
 635
 636                iboe_mac_vlan_to_ll((union ib_gid *) &resp->ib_route[0].dgid,
 637                                    dev_addr->dst_dev_addr, vid);
 638                iboe_addr_get_sgid(dev_addr,
 639                                   (union ib_gid *) &resp->ib_route[0].sgid);
 640                resp->ib_route[0].pkey = cpu_to_be16(0xffff);
 641                break;
 642        case 2:
 643                ib_copy_path_rec_to_user(&resp->ib_route[1],
 644                                         &route->path_rec[1]);
 645                /* fall through */
 646        case 1:
 647                ib_copy_path_rec_to_user(&resp->ib_route[0],
 648                                         &route->path_rec[0]);
 649                break;
 650        default:
 651                break;
 652        }
 653}
 654
 655static void ucma_copy_iw_route(struct rdma_ucm_query_route_resp *resp,
 656                               struct rdma_route *route)
 657{
 658        struct rdma_dev_addr *dev_addr;
 659
 660        dev_addr = &route->addr.dev_addr;
 661        rdma_addr_get_dgid(dev_addr, (union ib_gid *) &resp->ib_route[0].dgid);
 662        rdma_addr_get_sgid(dev_addr, (union ib_gid *) &resp->ib_route[0].sgid);
 663}
 664
 665static ssize_t ucma_query_route(struct ucma_file *file,
 666                                const char __user *inbuf,
 667                                int in_len, int out_len)
 668{
 669        struct rdma_ucm_query_route cmd;
 670        struct rdma_ucm_query_route_resp resp;
 671        struct ucma_context *ctx;
 672        struct sockaddr *addr;
 673        int ret = 0;
 674
 675        if (out_len < sizeof(resp))
 676                return -ENOSPC;
 677
 678        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 679                return -EFAULT;
 680
 681        ctx = ucma_get_ctx(file, cmd.id);
 682        if (IS_ERR(ctx))
 683                return PTR_ERR(ctx);
 684
 685        memset(&resp, 0, sizeof resp);
 686        addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr;
 687        memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ?
 688                                     sizeof(struct sockaddr_in) :
 689                                     sizeof(struct sockaddr_in6));
 690        addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr;
 691        memcpy(&resp.dst_addr, addr, addr->sa_family == AF_INET ?
 692                                     sizeof(struct sockaddr_in) :
 693                                     sizeof(struct sockaddr_in6));
 694        if (!ctx->cm_id->device)
 695                goto out;
 696
 697        resp.node_guid = (__force __u64) ctx->cm_id->device->node_guid;
 698        resp.port_num = ctx->cm_id->port_num;
 699        switch (rdma_node_get_transport(ctx->cm_id->device->node_type)) {
 700        case RDMA_TRANSPORT_IB:
 701                switch (rdma_port_get_link_layer(ctx->cm_id->device,
 702                        ctx->cm_id->port_num)) {
 703                case IB_LINK_LAYER_INFINIBAND:
 704                        ucma_copy_ib_route(&resp, &ctx->cm_id->route);
 705                        break;
 706                case IB_LINK_LAYER_ETHERNET:
 707                        ucma_copy_iboe_route(&resp, &ctx->cm_id->route);
 708                        break;
 709                default:
 710                        break;
 711                }
 712                break;
 713        case RDMA_TRANSPORT_IWARP:
 714                ucma_copy_iw_route(&resp, &ctx->cm_id->route);
 715                break;
 716        default:
 717                break;
 718        }
 719
 720out:
 721        if (copy_to_user((void __user *)(unsigned long)cmd.response,
 722                         &resp, sizeof(resp)))
 723                ret = -EFAULT;
 724
 725        ucma_put_ctx(ctx);
 726        return ret;
 727}
 728
 729static void ucma_copy_conn_param(struct rdma_conn_param *dst,
 730                                 struct rdma_ucm_conn_param *src)
 731{
 732        dst->private_data = src->private_data;
 733        dst->private_data_len = src->private_data_len;
 734        dst->responder_resources =src->responder_resources;
 735        dst->initiator_depth = src->initiator_depth;
 736        dst->flow_control = src->flow_control;
 737        dst->retry_count = src->retry_count;
 738        dst->rnr_retry_count = src->rnr_retry_count;
 739        dst->srq = src->srq;
 740        dst->qp_num = src->qp_num;
 741}
 742
 743static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf,
 744                            int in_len, int out_len)
 745{
 746        struct rdma_ucm_connect cmd;
 747        struct rdma_conn_param conn_param;
 748        struct ucma_context *ctx;
 749        int ret;
 750
 751        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 752                return -EFAULT;
 753
 754        if (!cmd.conn_param.valid)
 755                return -EINVAL;
 756
 757        ctx = ucma_get_ctx(file, cmd.id);
 758        if (IS_ERR(ctx))
 759                return PTR_ERR(ctx);
 760
 761        ucma_copy_conn_param(&conn_param, &cmd.conn_param);
 762        ret = rdma_connect(ctx->cm_id, &conn_param);
 763        ucma_put_ctx(ctx);
 764        return ret;
 765}
 766
 767static ssize_t ucma_listen(struct ucma_file *file, const char __user *inbuf,
 768                           int in_len, int out_len)
 769{
 770        struct rdma_ucm_listen cmd;
 771        struct ucma_context *ctx;
 772        int ret;
 773
 774        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 775                return -EFAULT;
 776
 777        ctx = ucma_get_ctx(file, cmd.id);
 778        if (IS_ERR(ctx))
 779                return PTR_ERR(ctx);
 780
 781        ctx->backlog = cmd.backlog > 0 && cmd.backlog < max_backlog ?
 782                       cmd.backlog : max_backlog;
 783        ret = rdma_listen(ctx->cm_id, ctx->backlog);
 784        ucma_put_ctx(ctx);
 785        return ret;
 786}
 787
 788static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf,
 789                           int in_len, int out_len)
 790{
 791        struct rdma_ucm_accept cmd;
 792        struct rdma_conn_param conn_param;
 793        struct ucma_context *ctx;
 794        int ret;
 795
 796        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 797                return -EFAULT;
 798
 799        ctx = ucma_get_ctx(file, cmd.id);
 800        if (IS_ERR(ctx))
 801                return PTR_ERR(ctx);
 802
 803        if (cmd.conn_param.valid) {
 804                ucma_copy_conn_param(&conn_param, &cmd.conn_param);
 805                mutex_lock(&file->mut);
 806                ret = rdma_accept(ctx->cm_id, &conn_param);
 807                if (!ret)
 808                        ctx->uid = cmd.uid;
 809                mutex_unlock(&file->mut);
 810        } else
 811                ret = rdma_accept(ctx->cm_id, NULL);
 812
 813        ucma_put_ctx(ctx);
 814        return ret;
 815}
 816
 817static ssize_t ucma_reject(struct ucma_file *file, const char __user *inbuf,
 818                           int in_len, int out_len)
 819{
 820        struct rdma_ucm_reject cmd;
 821        struct ucma_context *ctx;
 822        int ret;
 823
 824        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 825                return -EFAULT;
 826
 827        ctx = ucma_get_ctx(file, cmd.id);
 828        if (IS_ERR(ctx))
 829                return PTR_ERR(ctx);
 830
 831        ret = rdma_reject(ctx->cm_id, cmd.private_data, cmd.private_data_len);
 832        ucma_put_ctx(ctx);
 833        return ret;
 834}
 835
 836static ssize_t ucma_disconnect(struct ucma_file *file, const char __user *inbuf,
 837                               int in_len, int out_len)
 838{
 839        struct rdma_ucm_disconnect cmd;
 840        struct ucma_context *ctx;
 841        int ret;
 842
 843        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 844                return -EFAULT;
 845
 846        ctx = ucma_get_ctx(file, cmd.id);
 847        if (IS_ERR(ctx))
 848                return PTR_ERR(ctx);
 849
 850        ret = rdma_disconnect(ctx->cm_id);
 851        ucma_put_ctx(ctx);
 852        return ret;
 853}
 854
 855static ssize_t ucma_init_qp_attr(struct ucma_file *file,
 856                                 const char __user *inbuf,
 857                                 int in_len, int out_len)
 858{
 859        struct rdma_ucm_init_qp_attr cmd;
 860        struct ib_uverbs_qp_attr resp;
 861        struct ucma_context *ctx;
 862        struct ib_qp_attr qp_attr;
 863        int ret;
 864
 865        if (out_len < sizeof(resp))
 866                return -ENOSPC;
 867
 868        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 869                return -EFAULT;
 870
 871        ctx = ucma_get_ctx(file, cmd.id);
 872        if (IS_ERR(ctx))
 873                return PTR_ERR(ctx);
 874
 875        resp.qp_attr_mask = 0;
 876        memset(&qp_attr, 0, sizeof qp_attr);
 877        qp_attr.qp_state = cmd.qp_state;
 878        ret = rdma_init_qp_attr(ctx->cm_id, &qp_attr, &resp.qp_attr_mask);
 879        if (ret)
 880                goto out;
 881
 882        ib_copy_qp_attr_to_user(&resp, &qp_attr);
 883        if (copy_to_user((void __user *)(unsigned long)cmd.response,
 884                         &resp, sizeof(resp)))
 885                ret = -EFAULT;
 886
 887out:
 888        ucma_put_ctx(ctx);
 889        return ret;
 890}
 891
 892static int ucma_set_option_id(struct ucma_context *ctx, int optname,
 893                              void *optval, size_t optlen)
 894{
 895        int ret = 0;
 896
 897        switch (optname) {
 898        case RDMA_OPTION_ID_TOS:
 899                if (optlen != sizeof(u8)) {
 900                        ret = -EINVAL;
 901                        break;
 902                }
 903                rdma_set_service_type(ctx->cm_id, *((u8 *) optval));
 904                break;
 905        case RDMA_OPTION_ID_REUSEADDR:
 906                if (optlen != sizeof(int)) {
 907                        ret = -EINVAL;
 908                        break;
 909                }
 910                ret = rdma_set_reuseaddr(ctx->cm_id, *((int *) optval) ? 1 : 0);
 911                break;
 912        case RDMA_OPTION_ID_AFONLY:
 913                if (optlen != sizeof(int)) {
 914                        ret = -EINVAL;
 915                        break;
 916                }
 917                ret = rdma_set_afonly(ctx->cm_id, *((int *) optval) ? 1 : 0);
 918                break;
 919        default:
 920                ret = -ENOSYS;
 921        }
 922
 923        return ret;
 924}
 925
 926static int ucma_set_ib_path(struct ucma_context *ctx,
 927                            struct ib_path_rec_data *path_data, size_t optlen)
 928{
 929        struct ib_sa_path_rec sa_path;
 930        struct rdma_cm_event event;
 931        int ret;
 932
 933        if (optlen % sizeof(*path_data))
 934                return -EINVAL;
 935
 936        for (; optlen; optlen -= sizeof(*path_data), path_data++) {
 937                if (path_data->flags == (IB_PATH_GMP | IB_PATH_PRIMARY |
 938                                         IB_PATH_BIDIRECTIONAL))
 939                        break;
 940        }
 941
 942        if (!optlen)
 943                return -EINVAL;
 944
 945        ib_sa_unpack_path(path_data->path_rec, &sa_path);
 946        ret = rdma_set_ib_paths(ctx->cm_id, &sa_path, 1);
 947        if (ret)
 948                return ret;
 949
 950        memset(&event, 0, sizeof event);
 951        event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
 952        return ucma_event_handler(ctx->cm_id, &event);
 953}
 954
 955static int ucma_set_option_ib(struct ucma_context *ctx, int optname,
 956                              void *optval, size_t optlen)
 957{
 958        int ret;
 959
 960        switch (optname) {
 961        case RDMA_OPTION_IB_PATH:
 962                ret = ucma_set_ib_path(ctx, optval, optlen);
 963                break;
 964        default:
 965                ret = -ENOSYS;
 966        }
 967
 968        return ret;
 969}
 970
 971static int ucma_set_option_level(struct ucma_context *ctx, int level,
 972                                 int optname, void *optval, size_t optlen)
 973{
 974        int ret;
 975
 976        switch (level) {
 977        case RDMA_OPTION_ID:
 978                ret = ucma_set_option_id(ctx, optname, optval, optlen);
 979                break;
 980        case RDMA_OPTION_IB:
 981                ret = ucma_set_option_ib(ctx, optname, optval, optlen);
 982                break;
 983        default:
 984                ret = -ENOSYS;
 985        }
 986
 987        return ret;
 988}
 989
 990static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,
 991                               int in_len, int out_len)
 992{
 993        struct rdma_ucm_set_option cmd;
 994        struct ucma_context *ctx;
 995        void *optval;
 996        int ret;
 997
 998        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 999                return -EFAULT;
1000
1001        ctx = ucma_get_ctx(file, cmd.id);
1002        if (IS_ERR(ctx))
1003                return PTR_ERR(ctx);
1004
1005        optval = memdup_user((void __user *) (unsigned long) cmd.optval,
1006                             cmd.optlen);
1007        if (IS_ERR(optval)) {
1008                ret = PTR_ERR(optval);
1009                goto out;
1010        }
1011
1012        ret = ucma_set_option_level(ctx, cmd.level, cmd.optname, optval,
1013                                    cmd.optlen);
1014        kfree(optval);
1015
1016out:
1017        ucma_put_ctx(ctx);
1018        return ret;
1019}
1020
1021static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
1022                           int in_len, int out_len)
1023{
1024        struct rdma_ucm_notify cmd;
1025        struct ucma_context *ctx;
1026        int ret;
1027
1028        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1029                return -EFAULT;
1030
1031        ctx = ucma_get_ctx(file, cmd.id);
1032        if (IS_ERR(ctx))
1033                return PTR_ERR(ctx);
1034
1035        ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event);
1036        ucma_put_ctx(ctx);
1037        return ret;
1038}
1039
1040static ssize_t ucma_join_multicast(struct ucma_file *file,
1041                                   const char __user *inbuf,
1042                                   int in_len, int out_len)
1043{
1044        struct rdma_ucm_join_mcast cmd;
1045        struct rdma_ucm_create_id_resp resp;
1046        struct ucma_context *ctx;
1047        struct ucma_multicast *mc;
1048        int ret;
1049
1050        if (out_len < sizeof(resp))
1051                return -ENOSPC;
1052
1053        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1054                return -EFAULT;
1055
1056        ctx = ucma_get_ctx(file, cmd.id);
1057        if (IS_ERR(ctx))
1058                return PTR_ERR(ctx);
1059
1060        mutex_lock(&file->mut);
1061        mc = ucma_alloc_multicast(ctx);
1062        if (!mc) {
1063                ret = -ENOMEM;
1064                goto err1;
1065        }
1066
1067        mc->uid = cmd.uid;
1068        memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr);
1069        ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc);
1070        if (ret)
1071                goto err2;
1072
1073        resp.id = mc->id;
1074        if (copy_to_user((void __user *)(unsigned long)cmd.response,
1075                         &resp, sizeof(resp))) {
1076                ret = -EFAULT;
1077                goto err3;
1078        }
1079
1080        mutex_unlock(&file->mut);
1081        ucma_put_ctx(ctx);
1082        return 0;
1083
1084err3:
1085        rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr);
1086        ucma_cleanup_mc_events(mc);
1087err2:
1088        mutex_lock(&mut);
1089        idr_remove(&multicast_idr, mc->id);
1090        mutex_unlock(&mut);
1091        list_del(&mc->list);
1092        kfree(mc);
1093err1:
1094        mutex_unlock(&file->mut);
1095        ucma_put_ctx(ctx);
1096        return ret;
1097}
1098
1099static ssize_t ucma_leave_multicast(struct ucma_file *file,
1100                                    const char __user *inbuf,
1101                                    int in_len, int out_len)
1102{
1103        struct rdma_ucm_destroy_id cmd;
1104        struct rdma_ucm_destroy_id_resp resp;
1105        struct ucma_multicast *mc;
1106        int ret = 0;
1107
1108        if (out_len < sizeof(resp))
1109                return -ENOSPC;
1110
1111        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1112                return -EFAULT;
1113
1114        mutex_lock(&mut);
1115        mc = idr_find(&multicast_idr, cmd.id);
1116        if (!mc)
1117                mc = ERR_PTR(-ENOENT);
1118        else if (mc->ctx->file != file)
1119                mc = ERR_PTR(-EINVAL);
1120        else {
1121                idr_remove(&multicast_idr, mc->id);
1122                atomic_inc(&mc->ctx->ref);
1123        }
1124        mutex_unlock(&mut);
1125
1126        if (IS_ERR(mc)) {
1127                ret = PTR_ERR(mc);
1128                goto out;
1129        }
1130
1131        rdma_leave_multicast(mc->ctx->cm_id, (struct sockaddr *) &mc->addr);
1132        mutex_lock(&mc->ctx->file->mut);
1133        ucma_cleanup_mc_events(mc);
1134        list_del(&mc->list);
1135        mutex_unlock(&mc->ctx->file->mut);
1136
1137        ucma_put_ctx(mc->ctx);
1138        resp.events_reported = mc->events_reported;
1139        kfree(mc);
1140
1141        if (copy_to_user((void __user *)(unsigned long)cmd.response,
1142                         &resp, sizeof(resp)))
1143                ret = -EFAULT;
1144out:
1145        return ret;
1146}
1147
1148static void ucma_lock_files(struct ucma_file *file1, struct ucma_file *file2)
1149{
1150        /* Acquire mutex's based on pointer comparison to prevent deadlock. */
1151        if (file1 < file2) {
1152                mutex_lock(&file1->mut);
1153                mutex_lock(&file2->mut);
1154        } else {
1155                mutex_lock(&file2->mut);
1156                mutex_lock(&file1->mut);
1157        }
1158}
1159
1160static void ucma_unlock_files(struct ucma_file *file1, struct ucma_file *file2)
1161{
1162        if (file1 < file2) {
1163                mutex_unlock(&file2->mut);
1164                mutex_unlock(&file1->mut);
1165        } else {
1166                mutex_unlock(&file1->mut);
1167                mutex_unlock(&file2->mut);
1168        }
1169}
1170
1171static void ucma_move_events(struct ucma_context *ctx, struct ucma_file *file)
1172{
1173        struct ucma_event *uevent, *tmp;
1174
1175        list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list)
1176                if (uevent->ctx == ctx)
1177                        list_move_tail(&uevent->list, &file->event_list);
1178}
1179
1180static ssize_t ucma_migrate_id(struct ucma_file *new_file,
1181                               const char __user *inbuf,
1182                               int in_len, int out_len)
1183{
1184        struct rdma_ucm_migrate_id cmd;
1185        struct rdma_ucm_migrate_resp resp;
1186        struct ucma_context *ctx;
1187        struct file *filp;
1188        struct ucma_file *cur_file;
1189        int ret = 0;
1190
1191        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
1192                return -EFAULT;
1193
1194        /* Get current fd to protect against it being closed */
1195        filp = fget(cmd.fd);
1196        if (!filp)
1197                return -ENOENT;
1198
1199        /* Validate current fd and prevent destruction of id. */
1200        ctx = ucma_get_ctx(filp->private_data, cmd.id);
1201        if (IS_ERR(ctx)) {
1202                ret = PTR_ERR(ctx);
1203                goto file_put;
1204        }
1205
1206        cur_file = ctx->file;
1207        if (cur_file == new_file) {
1208                resp.events_reported = ctx->events_reported;
1209                goto response;
1210        }
1211
1212        /*
1213         * Migrate events between fd's, maintaining order, and avoiding new
1214         * events being added before existing events.
1215         */
1216        ucma_lock_files(cur_file, new_file);
1217        mutex_lock(&mut);
1218
1219        list_move_tail(&ctx->list, &new_file->ctx_list);
1220        ucma_move_events(ctx, new_file);
1221        ctx->file = new_file;
1222        resp.events_reported = ctx->events_reported;
1223
1224        mutex_unlock(&mut);
1225        ucma_unlock_files(cur_file, new_file);
1226
1227response:
1228        if (copy_to_user((void __user *)(unsigned long)cmd.response,
1229                         &resp, sizeof(resp)))
1230                ret = -EFAULT;
1231
1232        ucma_put_ctx(ctx);
1233file_put:
1234        fput(filp);
1235        return ret;
1236}
1237
1238static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
1239                                   const char __user *inbuf,
1240                                   int in_len, int out_len) = {
1241        [RDMA_USER_CM_CMD_CREATE_ID]    = ucma_create_id,
1242        [RDMA_USER_CM_CMD_DESTROY_ID]   = ucma_destroy_id,
1243        [RDMA_USER_CM_CMD_BIND_ADDR]    = ucma_bind_addr,
1244        [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr,
1245        [RDMA_USER_CM_CMD_RESOLVE_ROUTE]= ucma_resolve_route,
1246        [RDMA_USER_CM_CMD_QUERY_ROUTE]  = ucma_query_route,
1247        [RDMA_USER_CM_CMD_CONNECT]      = ucma_connect,
1248        [RDMA_USER_CM_CMD_LISTEN]       = ucma_listen,
1249        [RDMA_USER_CM_CMD_ACCEPT]       = ucma_accept,
1250        [RDMA_USER_CM_CMD_REJECT]       = ucma_reject,
1251        [RDMA_USER_CM_CMD_DISCONNECT]   = ucma_disconnect,
1252        [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr,
1253        [RDMA_USER_CM_CMD_GET_EVENT]    = ucma_get_event,
1254        [RDMA_USER_CM_CMD_GET_OPTION]   = NULL,
1255        [RDMA_USER_CM_CMD_SET_OPTION]   = ucma_set_option,
1256        [RDMA_USER_CM_CMD_NOTIFY]       = ucma_notify,
1257        [RDMA_USER_CM_CMD_JOIN_MCAST]   = ucma_join_multicast,
1258        [RDMA_USER_CM_CMD_LEAVE_MCAST]  = ucma_leave_multicast,
1259        [RDMA_USER_CM_CMD_MIGRATE_ID]   = ucma_migrate_id
1260};
1261
1262static ssize_t ucma_write(struct file *filp, const char __user *buf,
1263                          size_t len, loff_t *pos)
1264{
1265        struct ucma_file *file = filp->private_data;
1266        struct rdma_ucm_cmd_hdr hdr;
1267        ssize_t ret;
1268
1269        if (len < sizeof(hdr))
1270                return -EINVAL;
1271
1272        if (copy_from_user(&hdr, buf, sizeof(hdr)))
1273                return -EFAULT;
1274
1275        if (hdr.cmd >= ARRAY_SIZE(ucma_cmd_table))
1276                return -EINVAL;
1277
1278        if (hdr.in + sizeof(hdr) > len)
1279                return -EINVAL;
1280
1281        if (!ucma_cmd_table[hdr.cmd])
1282                return -ENOSYS;
1283
1284        ret = ucma_cmd_table[hdr.cmd](file, buf + sizeof(hdr), hdr.in, hdr.out);
1285        if (!ret)
1286                ret = len;
1287
1288        return ret;
1289}
1290
1291static unsigned int ucma_poll(struct file *filp, struct poll_table_struct *wait)
1292{
1293        struct ucma_file *file = filp->private_data;
1294        unsigned int mask = 0;
1295
1296        poll_wait(filp, &file->poll_wait, wait);
1297
1298        if (!list_empty(&file->event_list))
1299                mask = POLLIN | POLLRDNORM;
1300
1301        return mask;
1302}
1303
1304/*
1305 * ucma_open() does not need the BKL:
1306 *
1307 *  - no global state is referred to;
1308 *  - there is no ioctl method to race against;
1309 *  - no further module initialization is required for open to work
1310 *    after the device is registered.
1311 */
1312static int ucma_open(struct inode *inode, struct file *filp)
1313{
1314        struct ucma_file *file;
1315
1316        file = kmalloc(sizeof *file, GFP_KERNEL);
1317        if (!file)
1318                return -ENOMEM;
1319
1320        INIT_LIST_HEAD(&file->event_list);
1321        INIT_LIST_HEAD(&file->ctx_list);
1322        init_waitqueue_head(&file->poll_wait);
1323        mutex_init(&file->mut);
1324
1325        filp->private_data = file;
1326        file->filp = filp;
1327
1328        return nonseekable_open(inode, filp);
1329}
1330
1331static int ucma_close(struct inode *inode, struct file *filp)
1332{
1333        struct ucma_file *file = filp->private_data;
1334        struct ucma_context *ctx, *tmp;
1335
1336        mutex_lock(&file->mut);
1337        list_for_each_entry_safe(ctx, tmp, &file->ctx_list, list) {
1338                mutex_unlock(&file->mut);
1339
1340                mutex_lock(&mut);
1341                idr_remove(&ctx_idr, ctx->id);
1342                mutex_unlock(&mut);
1343
1344                ucma_free_ctx(ctx);
1345                mutex_lock(&file->mut);
1346        }
1347        mutex_unlock(&file->mut);
1348        kfree(file);
1349        return 0;
1350}
1351
1352static const struct file_operations ucma_fops = {
1353        .owner   = THIS_MODULE,
1354        .open    = ucma_open,
1355        .release = ucma_close,
1356        .write   = ucma_write,
1357        .poll    = ucma_poll,
1358        .llseek  = no_llseek,
1359};
1360
1361static struct miscdevice ucma_misc = {
1362        .minor          = MISC_DYNAMIC_MINOR,
1363        .name           = "rdma_cm",
1364        .nodename       = "infiniband/rdma_cm",
1365        .mode           = 0666,
1366        .fops           = &ucma_fops,
1367};
1368
1369static ssize_t show_abi_version(struct device *dev,
1370                                struct device_attribute *attr,
1371                                char *buf)
1372{
1373        return sprintf(buf, "%d\n", RDMA_USER_CM_ABI_VERSION);
1374}
1375static DEVICE_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
1376
1377static int __init ucma_init(void)
1378{
1379        int ret;
1380
1381        ret = misc_register(&ucma_misc);
1382        if (ret)
1383                return ret;
1384
1385        ret = device_create_file(ucma_misc.this_device, &dev_attr_abi_version);
1386        if (ret) {
1387                printk(KERN_ERR "rdma_ucm: couldn't create abi_version attr\n");
1388                goto err1;
1389        }
1390
1391        ucma_ctl_table_hdr = register_net_sysctl(&init_net, "net/rdma_ucm", ucma_ctl_table);
1392        if (!ucma_ctl_table_hdr) {
1393                printk(KERN_ERR "rdma_ucm: couldn't register sysctl paths\n");
1394                ret = -ENOMEM;
1395                goto err2;
1396        }
1397        return 0;
1398err2:
1399        device_remove_file(ucma_misc.this_device, &dev_attr_abi_version);
1400err1:
1401        misc_deregister(&ucma_misc);
1402        return ret;
1403}
1404
1405static void __exit ucma_cleanup(void)
1406{
1407        unregister_net_sysctl_table(ucma_ctl_table_hdr);
1408        device_remove_file(ucma_misc.this_device, &dev_attr_abi_version);
1409        misc_deregister(&ucma_misc);
1410        idr_destroy(&ctx_idr);
1411}
1412
1413module_init(ucma_init);
1414module_exit(ucma_cleanup);
1415