diff options
| -rw-r--r-- | include/linux/sunrpc/svc_rdma.h | 6 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 121 |
2 files changed, 12 insertions, 115 deletions
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index d8d74c4ab504..ef2e3a20bf3b 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h | |||
| @@ -73,7 +73,6 @@ extern atomic_t rdma_stat_sq_prod; | |||
| 73 | struct svc_rdma_op_ctxt { | 73 | struct svc_rdma_op_ctxt { |
| 74 | struct svc_rdma_op_ctxt *read_hdr; | 74 | struct svc_rdma_op_ctxt *read_hdr; |
| 75 | int hdr_count; | 75 | int hdr_count; |
| 76 | struct list_head free_list; | ||
| 77 | struct xdr_buf arg; | 76 | struct xdr_buf arg; |
| 78 | struct list_head dto_q; | 77 | struct list_head dto_q; |
| 79 | enum ib_wr_opcode wr_op; | 78 | enum ib_wr_opcode wr_op; |
| @@ -131,11 +130,6 @@ struct svcxprt_rdma { | |||
| 131 | 130 | ||
| 132 | atomic_t sc_dma_used; | 131 | atomic_t sc_dma_used; |
| 133 | atomic_t sc_ctxt_used; | 132 | atomic_t sc_ctxt_used; |
| 134 | struct list_head sc_ctxt_free; | ||
| 135 | int sc_ctxt_cnt; | ||
| 136 | int sc_ctxt_bump; | ||
| 137 | int sc_ctxt_max; | ||
| 138 | spinlock_t sc_ctxt_lock; | ||
| 139 | struct list_head sc_rq_dto_q; | 133 | struct list_head sc_rq_dto_q; |
| 140 | spinlock_t sc_rq_dto_lock; | 134 | spinlock_t sc_rq_dto_lock; |
| 141 | struct ib_qp *sc_qp; | 135 | struct ib_qp *sc_qp; |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 80104f4999d5..19ddc382b777 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
| @@ -84,69 +84,23 @@ struct svc_xprt_class svc_rdma_class = { | |||
| 84 | .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP, | 84 | .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP, |
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| 87 | static int rdma_bump_context_cache(struct svcxprt_rdma *xprt) | 87 | /* WR context cache. Created in svc_rdma.c */ |
| 88 | { | 88 | extern struct kmem_cache *svc_rdma_ctxt_cachep; |
| 89 | int target; | ||
| 90 | int at_least_one = 0; | ||
| 91 | struct svc_rdma_op_ctxt *ctxt; | ||
| 92 | |||
| 93 | target = min(xprt->sc_ctxt_cnt + xprt->sc_ctxt_bump, | ||
| 94 | xprt->sc_ctxt_max); | ||
| 95 | |||
| 96 | spin_lock_bh(&xprt->sc_ctxt_lock); | ||
| 97 | while (xprt->sc_ctxt_cnt < target) { | ||
| 98 | xprt->sc_ctxt_cnt++; | ||
| 99 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
| 100 | |||
| 101 | ctxt = kmalloc(sizeof(*ctxt), GFP_KERNEL); | ||
| 102 | |||
| 103 | spin_lock_bh(&xprt->sc_ctxt_lock); | ||
| 104 | if (ctxt) { | ||
| 105 | at_least_one = 1; | ||
| 106 | INIT_LIST_HEAD(&ctxt->free_list); | ||
| 107 | list_add(&ctxt->free_list, &xprt->sc_ctxt_free); | ||
| 108 | } else { | ||
| 109 | /* kmalloc failed...give up for now */ | ||
| 110 | xprt->sc_ctxt_cnt--; | ||
| 111 | break; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
| 115 | dprintk("svcrdma: sc_ctxt_max=%d, sc_ctxt_cnt=%d\n", | ||
| 116 | xprt->sc_ctxt_max, xprt->sc_ctxt_cnt); | ||
| 117 | return at_least_one; | ||
| 118 | } | ||
| 119 | 89 | ||
| 120 | struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt) | 90 | struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt) |
| 121 | { | 91 | { |
| 122 | struct svc_rdma_op_ctxt *ctxt; | 92 | struct svc_rdma_op_ctxt *ctxt; |
| 123 | 93 | ||
| 124 | while (1) { | 94 | while (1) { |
| 125 | spin_lock_bh(&xprt->sc_ctxt_lock); | 95 | ctxt = kmem_cache_alloc(svc_rdma_ctxt_cachep, GFP_KERNEL); |
| 126 | if (unlikely(list_empty(&xprt->sc_ctxt_free))) { | 96 | if (ctxt) |
| 127 | /* Try to bump my cache. */ | 97 | break; |
| 128 | spin_unlock_bh(&xprt->sc_ctxt_lock); | 98 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); |
| 129 | |||
| 130 | if (rdma_bump_context_cache(xprt)) | ||
| 131 | continue; | ||
| 132 | |||
| 133 | printk(KERN_INFO "svcrdma: sleeping waiting for " | ||
| 134 | "context memory on xprt=%p\n", | ||
| 135 | xprt); | ||
| 136 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); | ||
| 137 | continue; | ||
| 138 | } | ||
| 139 | ctxt = list_entry(xprt->sc_ctxt_free.next, | ||
| 140 | struct svc_rdma_op_ctxt, | ||
| 141 | free_list); | ||
| 142 | list_del_init(&ctxt->free_list); | ||
| 143 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
| 144 | ctxt->xprt = xprt; | ||
| 145 | INIT_LIST_HEAD(&ctxt->dto_q); | ||
| 146 | ctxt->count = 0; | ||
| 147 | atomic_inc(&xprt->sc_ctxt_used); | ||
| 148 | break; | ||
| 149 | } | 99 | } |
| 100 | ctxt->xprt = xprt; | ||
| 101 | INIT_LIST_HEAD(&ctxt->dto_q); | ||
| 102 | ctxt->count = 0; | ||
| 103 | atomic_inc(&xprt->sc_ctxt_used); | ||
| 150 | return ctxt; | 104 | return ctxt; |
| 151 | } | 105 | } |
| 152 | 106 | ||
| @@ -174,9 +128,7 @@ void svc_rdma_put_context(struct svc_rdma_op_ctxt *ctxt, int free_pages) | |||
| 174 | for (i = 0; i < ctxt->count; i++) | 128 | for (i = 0; i < ctxt->count; i++) |
| 175 | put_page(ctxt->pages[i]); | 129 | put_page(ctxt->pages[i]); |
| 176 | 130 | ||
| 177 | spin_lock_bh(&xprt->sc_ctxt_lock); | 131 | kmem_cache_free(svc_rdma_ctxt_cachep, ctxt); |
| 178 | list_add(&ctxt->free_list, &xprt->sc_ctxt_free); | ||
| 179 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
| 180 | atomic_dec(&xprt->sc_ctxt_used); | 132 | atomic_dec(&xprt->sc_ctxt_used); |
| 181 | } | 133 | } |
| 182 | 134 | ||
| @@ -461,40 +413,6 @@ static void sq_comp_handler(struct ib_cq *cq, void *cq_context) | |||
| 461 | tasklet_schedule(&dto_tasklet); | 413 | tasklet_schedule(&dto_tasklet); |
| 462 | } | 414 | } |
| 463 | 415 | ||
| 464 | static void create_context_cache(struct svcxprt_rdma *xprt, | ||
| 465 | int ctxt_count, int ctxt_bump, int ctxt_max) | ||
| 466 | { | ||
| 467 | struct svc_rdma_op_ctxt *ctxt; | ||
| 468 | int i; | ||
| 469 | |||
| 470 | xprt->sc_ctxt_max = ctxt_max; | ||
| 471 | xprt->sc_ctxt_bump = ctxt_bump; | ||
| 472 | xprt->sc_ctxt_cnt = 0; | ||
| 473 | atomic_set(&xprt->sc_ctxt_used, 0); | ||
| 474 | |||
| 475 | INIT_LIST_HEAD(&xprt->sc_ctxt_free); | ||
| 476 | for (i = 0; i < ctxt_count; i++) { | ||
| 477 | ctxt = kmalloc(sizeof(*ctxt), GFP_KERNEL); | ||
| 478 | if (ctxt) { | ||
| 479 | INIT_LIST_HEAD(&ctxt->free_list); | ||
| 480 | list_add(&ctxt->free_list, &xprt->sc_ctxt_free); | ||
| 481 | xprt->sc_ctxt_cnt++; | ||
| 482 | } | ||
| 483 | } | ||
| 484 | } | ||
| 485 | |||
| 486 | static void destroy_context_cache(struct svcxprt_rdma *xprt) | ||
| 487 | { | ||
| 488 | while (!list_empty(&xprt->sc_ctxt_free)) { | ||
| 489 | struct svc_rdma_op_ctxt *ctxt; | ||
| 490 | ctxt = list_entry(xprt->sc_ctxt_free.next, | ||
| 491 | struct svc_rdma_op_ctxt, | ||
| 492 | free_list); | ||
| 493 | list_del_init(&ctxt->free_list); | ||
| 494 | kfree(ctxt); | ||
| 495 | } | ||
| 496 | } | ||
| 497 | |||
| 498 | static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv, | 416 | static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv, |
| 499 | int listener) | 417 | int listener) |
| 500 | { | 418 | { |
| @@ -511,7 +429,6 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv, | |||
| 511 | 429 | ||
| 512 | spin_lock_init(&cma_xprt->sc_lock); | 430 | spin_lock_init(&cma_xprt->sc_lock); |
| 513 | spin_lock_init(&cma_xprt->sc_read_complete_lock); | 431 | spin_lock_init(&cma_xprt->sc_read_complete_lock); |
| 514 | spin_lock_init(&cma_xprt->sc_ctxt_lock); | ||
| 515 | spin_lock_init(&cma_xprt->sc_rq_dto_lock); | 432 | spin_lock_init(&cma_xprt->sc_rq_dto_lock); |
| 516 | 433 | ||
| 517 | cma_xprt->sc_ord = svcrdma_ord; | 434 | cma_xprt->sc_ord = svcrdma_ord; |
| @@ -522,20 +439,7 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv, | |||
| 522 | atomic_set(&cma_xprt->sc_sq_count, 0); | 439 | atomic_set(&cma_xprt->sc_sq_count, 0); |
| 523 | atomic_set(&cma_xprt->sc_ctxt_used, 0); | 440 | atomic_set(&cma_xprt->sc_ctxt_used, 0); |
| 524 | 441 | ||
| 525 | if (!listener) { | 442 | if (listener) |
| 526 | int reqs = cma_xprt->sc_max_requests; | ||
| 527 | create_context_cache(cma_xprt, | ||
| 528 | reqs << 1, /* starting size */ | ||
| 529 | reqs, /* bump amount */ | ||
| 530 | reqs + | ||
| 531 | cma_xprt->sc_sq_depth + | ||
| 532 | RPCRDMA_MAX_THREADS + 1); /* max */ | ||
| 533 | if (list_empty(&cma_xprt->sc_ctxt_free)) { | ||
| 534 | kfree(cma_xprt); | ||
| 535 | return NULL; | ||
| 536 | } | ||
| 537 | clear_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags); | ||
| 538 | } else | ||
| 539 | set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags); | 443 | set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags); |
| 540 | 444 | ||
| 541 | return cma_xprt; | 445 | return cma_xprt; |
| @@ -1077,7 +981,6 @@ static void __svc_rdma_free(struct work_struct *work) | |||
| 1077 | /* Destroy the CM ID */ | 981 | /* Destroy the CM ID */ |
| 1078 | rdma_destroy_id(rdma->sc_cm_id); | 982 | rdma_destroy_id(rdma->sc_cm_id); |
| 1079 | 983 | ||
| 1080 | destroy_context_cache(rdma); | ||
| 1081 | kfree(rdma); | 984 | kfree(rdma); |
| 1082 | } | 985 | } |
| 1083 | 986 | ||
