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