diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 111 |
1 files changed, 50 insertions, 61 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 79b60c3dc8d0..a0ceb1cbed52 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Cisco Systems. All rights reserved. | 3 | * Copyright (c) 2005 Cisco Systems. All rights reserved. |
4 | * Copyright (c) 2005 PathScale, Inc. All rights reserved. | ||
4 | * | 5 | * |
5 | * This software is available to you under a choice of one of two | 6 | * This software is available to you under a choice of one of two |
6 | * licenses. You may choose to be licensed under the terms of the GNU | 7 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -288,24 +289,20 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, | |||
288 | pd->uobject = uobj; | 289 | pd->uobject = uobj; |
289 | atomic_set(&pd->usecnt, 0); | 290 | atomic_set(&pd->usecnt, 0); |
290 | 291 | ||
292 | down(&ib_uverbs_idr_mutex); | ||
293 | |||
291 | retry: | 294 | retry: |
292 | if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) { | 295 | if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) { |
293 | ret = -ENOMEM; | 296 | ret = -ENOMEM; |
294 | goto err_pd; | 297 | goto err_up; |
295 | } | 298 | } |
296 | 299 | ||
297 | down(&ib_uverbs_idr_mutex); | ||
298 | ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id); | 300 | ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id); |
299 | up(&ib_uverbs_idr_mutex); | ||
300 | 301 | ||
301 | if (ret == -EAGAIN) | 302 | if (ret == -EAGAIN) |
302 | goto retry; | 303 | goto retry; |
303 | if (ret) | 304 | if (ret) |
304 | goto err_pd; | 305 | goto err_up; |
305 | |||
306 | down(&file->mutex); | ||
307 | list_add_tail(&uobj->list, &file->ucontext->pd_list); | ||
308 | up(&file->mutex); | ||
309 | 306 | ||
310 | memset(&resp, 0, sizeof resp); | 307 | memset(&resp, 0, sizeof resp); |
311 | resp.pd_handle = uobj->id; | 308 | resp.pd_handle = uobj->id; |
@@ -313,21 +310,22 @@ retry: | |||
313 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 310 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
314 | &resp, sizeof resp)) { | 311 | &resp, sizeof resp)) { |
315 | ret = -EFAULT; | 312 | ret = -EFAULT; |
316 | goto err_list; | 313 | goto err_idr; |
317 | } | 314 | } |
318 | 315 | ||
319 | return in_len; | 316 | down(&file->mutex); |
320 | 317 | list_add_tail(&uobj->list, &file->ucontext->pd_list); | |
321 | err_list: | ||
322 | down(&file->mutex); | ||
323 | list_del(&uobj->list); | ||
324 | up(&file->mutex); | 318 | up(&file->mutex); |
325 | 319 | ||
326 | down(&ib_uverbs_idr_mutex); | ||
327 | idr_remove(&ib_uverbs_pd_idr, uobj->id); | ||
328 | up(&ib_uverbs_idr_mutex); | 320 | up(&ib_uverbs_idr_mutex); |
329 | 321 | ||
330 | err_pd: | 322 | return in_len; |
323 | |||
324 | err_idr: | ||
325 | idr_remove(&ib_uverbs_pd_idr, uobj->id); | ||
326 | |||
327 | err_up: | ||
328 | up(&ib_uverbs_idr_mutex); | ||
331 | ib_dealloc_pd(pd); | 329 | ib_dealloc_pd(pd); |
332 | 330 | ||
333 | err: | 331 | err: |
@@ -463,24 +461,22 @@ retry: | |||
463 | 461 | ||
464 | resp.mr_handle = obj->uobject.id; | 462 | resp.mr_handle = obj->uobject.id; |
465 | 463 | ||
466 | down(&file->mutex); | ||
467 | list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); | ||
468 | up(&file->mutex); | ||
469 | |||
470 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 464 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
471 | &resp, sizeof resp)) { | 465 | &resp, sizeof resp)) { |
472 | ret = -EFAULT; | 466 | ret = -EFAULT; |
473 | goto err_list; | 467 | goto err_idr; |
474 | } | 468 | } |
475 | 469 | ||
470 | down(&file->mutex); | ||
471 | list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); | ||
472 | up(&file->mutex); | ||
473 | |||
476 | up(&ib_uverbs_idr_mutex); | 474 | up(&ib_uverbs_idr_mutex); |
477 | 475 | ||
478 | return in_len; | 476 | return in_len; |
479 | 477 | ||
480 | err_list: | 478 | err_idr: |
481 | down(&file->mutex); | 479 | idr_remove(&ib_uverbs_mr_idr, obj->uobject.id); |
482 | list_del(&obj->uobject.list); | ||
483 | up(&file->mutex); | ||
484 | 480 | ||
485 | err_unreg: | 481 | err_unreg: |
486 | ib_dereg_mr(mr); | 482 | ib_dereg_mr(mr); |
@@ -616,24 +612,20 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, | |||
616 | cq->cq_context = ev_file; | 612 | cq->cq_context = ev_file; |
617 | atomic_set(&cq->usecnt, 0); | 613 | atomic_set(&cq->usecnt, 0); |
618 | 614 | ||
615 | down(&ib_uverbs_idr_mutex); | ||
616 | |||
619 | retry: | 617 | retry: |
620 | if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) { | 618 | if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) { |
621 | ret = -ENOMEM; | 619 | ret = -ENOMEM; |
622 | goto err_cq; | 620 | goto err_up; |
623 | } | 621 | } |
624 | 622 | ||
625 | down(&ib_uverbs_idr_mutex); | ||
626 | ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id); | 623 | ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id); |
627 | up(&ib_uverbs_idr_mutex); | ||
628 | 624 | ||
629 | if (ret == -EAGAIN) | 625 | if (ret == -EAGAIN) |
630 | goto retry; | 626 | goto retry; |
631 | if (ret) | 627 | if (ret) |
632 | goto err_cq; | 628 | goto err_up; |
633 | |||
634 | down(&file->mutex); | ||
635 | list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); | ||
636 | up(&file->mutex); | ||
637 | 629 | ||
638 | memset(&resp, 0, sizeof resp); | 630 | memset(&resp, 0, sizeof resp); |
639 | resp.cq_handle = uobj->uobject.id; | 631 | resp.cq_handle = uobj->uobject.id; |
@@ -642,21 +634,22 @@ retry: | |||
642 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 634 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
643 | &resp, sizeof resp)) { | 635 | &resp, sizeof resp)) { |
644 | ret = -EFAULT; | 636 | ret = -EFAULT; |
645 | goto err_list; | 637 | goto err_idr; |
646 | } | 638 | } |
647 | 639 | ||
648 | return in_len; | 640 | down(&file->mutex); |
649 | 641 | list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); | |
650 | err_list: | ||
651 | down(&file->mutex); | ||
652 | list_del(&uobj->uobject.list); | ||
653 | up(&file->mutex); | 642 | up(&file->mutex); |
654 | 643 | ||
655 | down(&ib_uverbs_idr_mutex); | ||
656 | idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); | ||
657 | up(&ib_uverbs_idr_mutex); | 644 | up(&ib_uverbs_idr_mutex); |
658 | 645 | ||
659 | err_cq: | 646 | return in_len; |
647 | |||
648 | err_idr: | ||
649 | idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); | ||
650 | |||
651 | err_up: | ||
652 | up(&ib_uverbs_idr_mutex); | ||
660 | ib_destroy_cq(cq); | 653 | ib_destroy_cq(cq); |
661 | 654 | ||
662 | err: | 655 | err: |
@@ -837,24 +830,22 @@ retry: | |||
837 | 830 | ||
838 | resp.qp_handle = uobj->uobject.id; | 831 | resp.qp_handle = uobj->uobject.id; |
839 | 832 | ||
840 | down(&file->mutex); | ||
841 | list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); | ||
842 | up(&file->mutex); | ||
843 | |||
844 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 833 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
845 | &resp, sizeof resp)) { | 834 | &resp, sizeof resp)) { |
846 | ret = -EFAULT; | 835 | ret = -EFAULT; |
847 | goto err_list; | 836 | goto err_idr; |
848 | } | 837 | } |
849 | 838 | ||
839 | down(&file->mutex); | ||
840 | list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); | ||
841 | up(&file->mutex); | ||
842 | |||
850 | up(&ib_uverbs_idr_mutex); | 843 | up(&ib_uverbs_idr_mutex); |
851 | 844 | ||
852 | return in_len; | 845 | return in_len; |
853 | 846 | ||
854 | err_list: | 847 | err_idr: |
855 | down(&file->mutex); | 848 | idr_remove(&ib_uverbs_qp_idr, uobj->uobject.id); |
856 | list_del(&uobj->uobject.list); | ||
857 | up(&file->mutex); | ||
858 | 849 | ||
859 | err_destroy: | 850 | err_destroy: |
860 | ib_destroy_qp(qp); | 851 | ib_destroy_qp(qp); |
@@ -1126,24 +1117,22 @@ retry: | |||
1126 | 1117 | ||
1127 | resp.srq_handle = uobj->uobject.id; | 1118 | resp.srq_handle = uobj->uobject.id; |
1128 | 1119 | ||
1129 | down(&file->mutex); | ||
1130 | list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); | ||
1131 | up(&file->mutex); | ||
1132 | |||
1133 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 1120 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
1134 | &resp, sizeof resp)) { | 1121 | &resp, sizeof resp)) { |
1135 | ret = -EFAULT; | 1122 | ret = -EFAULT; |
1136 | goto err_list; | 1123 | goto err_idr; |
1137 | } | 1124 | } |
1138 | 1125 | ||
1126 | down(&file->mutex); | ||
1127 | list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); | ||
1128 | up(&file->mutex); | ||
1129 | |||
1139 | up(&ib_uverbs_idr_mutex); | 1130 | up(&ib_uverbs_idr_mutex); |
1140 | 1131 | ||
1141 | return in_len; | 1132 | return in_len; |
1142 | 1133 | ||
1143 | err_list: | 1134 | err_idr: |
1144 | down(&file->mutex); | 1135 | idr_remove(&ib_uverbs_srq_idr, uobj->uobject.id); |
1145 | list_del(&uobj->uobject.list); | ||
1146 | up(&file->mutex); | ||
1147 | 1136 | ||
1148 | err_destroy: | 1137 | err_destroy: |
1149 | ib_destroy_srq(srq); | 1138 | ib_destroy_srq(srq); |