aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c56
-rw-r--r--include/rdma/rdma_vt.h5
2 files changed, 46 insertions, 15 deletions
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
index ee19eae38d0b..43346a773ff3 100644
--- a/drivers/infiniband/sw/rdmavt/qp.c
+++ b/drivers/infiniband/sw/rdmavt/qp.c
@@ -53,9 +53,11 @@
53#include "qp.h" 53#include "qp.h"
54#include "vt.h" 54#include "vt.h"
55 55
56static void get_map_page(struct rvt_qpn_table *qpt, struct rvt_qpn_map *map) 56static void get_map_page(struct rvt_qpn_table *qpt,
57 struct rvt_qpn_map *map,
58 gfp_t gfp)
57{ 59{
58 unsigned long page = get_zeroed_page(GFP_KERNEL); 60 unsigned long page = get_zeroed_page(gfp);
59 61
60 /* 62 /*
61 * Free the page if someone raced with us installing it. 63 * Free the page if someone raced with us installing it.
@@ -107,7 +109,7 @@ static int init_qpn_table(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt)
107 rdi->dparms.qpn_res_start, rdi->dparms.qpn_res_end); 109 rdi->dparms.qpn_res_start, rdi->dparms.qpn_res_end);
108 for (i = rdi->dparms.qpn_res_start; i <= rdi->dparms.qpn_res_end; i++) { 110 for (i = rdi->dparms.qpn_res_start; i <= rdi->dparms.qpn_res_end; i++) {
109 if (!map->page) { 111 if (!map->page) {
110 get_map_page(qpt, map); 112 get_map_page(qpt, map, GFP_KERNEL);
111 if (!map->page) { 113 if (!map->page) {
112 ret = -ENOMEM; 114 ret = -ENOMEM;
113 break; 115 break;
@@ -263,14 +265,15 @@ static inline unsigned mk_qpn(struct rvt_qpn_table *qpt,
263 * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI. 265 * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI.
264 */ 266 */
265static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt, 267static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
266 enum ib_qp_type type, u8 port) 268 enum ib_qp_type type, u8 port, gfp_t gfp)
267{ 269{
268 u32 i, offset, max_scan, qpn; 270 u32 i, offset, max_scan, qpn;
269 struct rvt_qpn_map *map; 271 struct rvt_qpn_map *map;
270 u32 ret; 272 u32 ret;
271 273
272 if (rdi->driver_f.alloc_qpn) 274 if (rdi->driver_f.alloc_qpn)
273 return rdi->driver_f.alloc_qpn(rdi, qpt, type, port); 275 return rdi->driver_f.alloc_qpn(rdi, qpt, type, port,
276 GFP_KERNEL);
274 277
275 if (type == IB_QPT_SMI || type == IB_QPT_GSI) { 278 if (type == IB_QPT_SMI || type == IB_QPT_GSI) {
276 unsigned n; 279 unsigned n;
@@ -295,7 +298,7 @@ static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
295 max_scan = qpt->nmaps - !offset; 298 max_scan = qpt->nmaps - !offset;
296 for (i = 0;;) { 299 for (i = 0;;) {
297 if (unlikely(!map->page)) { 300 if (unlikely(!map->page)) {
298 get_map_page(qpt, map); 301 get_map_page(qpt, map, gfp);
299 if (unlikely(!map->page)) 302 if (unlikely(!map->page))
300 break; 303 break;
301 } 304 }
@@ -437,15 +440,25 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
437 struct ib_qp *ret = ERR_PTR(-ENOMEM); 440 struct ib_qp *ret = ERR_PTR(-ENOMEM);
438 struct rvt_dev_info *rdi = ib_to_rvt(ibpd->device); 441 struct rvt_dev_info *rdi = ib_to_rvt(ibpd->device);
439 void *priv = NULL; 442 void *priv = NULL;
443 gfp_t gfp;
440 444
441 if (!rdi) 445 if (!rdi)
442 return ERR_PTR(-EINVAL); 446 return ERR_PTR(-EINVAL);
443 447
444 if (init_attr->cap.max_send_sge > rdi->dparms.props.max_sge || 448 if (init_attr->cap.max_send_sge > rdi->dparms.props.max_sge ||
445 init_attr->cap.max_send_wr > rdi->dparms.props.max_qp_wr || 449 init_attr->cap.max_send_wr > rdi->dparms.props.max_qp_wr ||
446 init_attr->create_flags) 450 init_attr->create_flags & ~(IB_QP_CREATE_USE_GFP_NOIO))
447 return ERR_PTR(-EINVAL); 451 return ERR_PTR(-EINVAL);
448 452
453 /* GFP_NOIO is applicable to RC QP's only */
454
455 if (init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO &&
456 init_attr->qp_type != IB_QPT_RC)
457 return ERR_PTR(-EINVAL);
458
459 gfp = init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO ?
460 GFP_NOIO : GFP_KERNEL;
461
449 /* Check receive queue parameters if no SRQ is specified. */ 462 /* Check receive queue parameters if no SRQ is specified. */
450 if (!init_attr->srq) { 463 if (!init_attr->srq) {
451 if (init_attr->cap.max_recv_sge > rdi->dparms.props.max_sge || 464 if (init_attr->cap.max_recv_sge > rdi->dparms.props.max_sge ||
@@ -471,7 +484,13 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
471 sz = sizeof(struct rvt_sge) * 484 sz = sizeof(struct rvt_sge) *
472 init_attr->cap.max_send_sge + 485 init_attr->cap.max_send_sge +
473 sizeof(struct rvt_swqe); 486 sizeof(struct rvt_swqe);
474 swq = vmalloc((init_attr->cap.max_send_wr + 1) * sz); 487 if (gfp == GFP_NOIO)
488 swq = __vmalloc(
489 (init_attr->cap.max_send_wr + 1) * sz,
490 gfp, PAGE_KERNEL);
491 else
492 swq = vmalloc(
493 (init_attr->cap.max_send_wr + 1) * sz);
475 if (!swq) 494 if (!swq)
476 return ERR_PTR(-ENOMEM); 495 return ERR_PTR(-ENOMEM);
477 496
@@ -486,7 +505,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
486 } else if (init_attr->cap.max_recv_sge > 1) 505 } else if (init_attr->cap.max_recv_sge > 1)
487 sg_list_sz = sizeof(*qp->r_sg_list) * 506 sg_list_sz = sizeof(*qp->r_sg_list) *
488 (init_attr->cap.max_recv_sge - 1); 507 (init_attr->cap.max_recv_sge - 1);
489 qp = kzalloc(sz + sg_list_sz, GFP_KERNEL); 508 qp = kzalloc(sz + sg_list_sz, gfp);
490 if (!qp) 509 if (!qp)
491 goto bail_swq; 510 goto bail_swq;
492 511
@@ -496,7 +515,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
496 * Driver needs to set up it's private QP structure and do any 515 * Driver needs to set up it's private QP structure and do any
497 * initialization that is needed. 516 * initialization that is needed.
498 */ 517 */
499 priv = rdi->driver_f.qp_priv_alloc(rdi, qp); 518 priv = rdi->driver_f.qp_priv_alloc(rdi, qp, gfp);
500 if (!priv) 519 if (!priv)
501 goto bail_qp; 520 goto bail_qp;
502 qp->priv = priv; 521 qp->priv = priv;
@@ -510,8 +529,19 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
510 qp->r_rq.max_sge = init_attr->cap.max_recv_sge; 529 qp->r_rq.max_sge = init_attr->cap.max_recv_sge;
511 sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) + 530 sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) +
512 sizeof(struct rvt_rwqe); 531 sizeof(struct rvt_rwqe);
513 qp->r_rq.wq = vmalloc_user(sizeof(struct rvt_rwq) + 532 if (udata)
514 qp->r_rq.size * sz); 533 qp->r_rq.wq = vmalloc_user(
534 sizeof(struct rvt_rwq) +
535 qp->r_rq.size * sz);
536 else if (gfp == GFP_NOIO)
537 qp->r_rq.wq = __vmalloc(
538 sizeof(struct rvt_rwq) +
539 qp->r_rq.size * sz,
540 gfp, PAGE_KERNEL);
541 else
542 qp->r_rq.wq = vmalloc(
543 sizeof(struct rvt_rwq) +
544 qp->r_rq.size * sz);
515 if (!qp->r_rq.wq) 545 if (!qp->r_rq.wq)
516 goto bail_driver_priv; 546 goto bail_driver_priv;
517 } 547 }
@@ -537,7 +567,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
537 567
538 err = alloc_qpn(rdi, &rdi->qp_dev->qpn_table, 568 err = alloc_qpn(rdi, &rdi->qp_dev->qpn_table,
539 init_attr->qp_type, 569 init_attr->qp_type,
540 init_attr->port_num); 570 init_attr->port_num, gfp);
541 if (err < 0) { 571 if (err < 0) {
542 ret = ERR_PTR(err); 572 ret = ERR_PTR(err);
543 goto bail_rq_wq; 573 goto bail_rq_wq;
diff --git a/include/rdma/rdma_vt.h b/include/rdma/rdma_vt.h
index 725778a6781d..70a9596b859d 100644
--- a/include/rdma/rdma_vt.h
+++ b/include/rdma/rdma_vt.h
@@ -223,7 +223,8 @@ struct rvt_driver_provided {
223 const char * (*get_card_name)(struct rvt_dev_info *rdi); 223 const char * (*get_card_name)(struct rvt_dev_info *rdi);
224 struct pci_dev * (*get_pci_dev)(struct rvt_dev_info *rdi); 224 struct pci_dev * (*get_pci_dev)(struct rvt_dev_info *rdi);
225 unsigned (*free_all_qps)(struct rvt_dev_info *rdi); 225 unsigned (*free_all_qps)(struct rvt_dev_info *rdi);
226 void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp); 226 void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp,
227 gfp_t gfp);
227 void (*qp_priv_free)(struct rvt_dev_info *rdi, struct rvt_qp *qp); 228 void (*qp_priv_free)(struct rvt_dev_info *rdi, struct rvt_qp *qp);
228 void (*notify_qp_reset)(struct rvt_qp *qp); 229 void (*notify_qp_reset)(struct rvt_qp *qp);
229 230
@@ -234,7 +235,7 @@ struct rvt_driver_provided {
234 void (*notify_new_ah)(struct ib_device *, struct ib_ah_attr *, 235 void (*notify_new_ah)(struct ib_device *, struct ib_ah_attr *,
235 struct rvt_ah *); 236 struct rvt_ah *);
236 int (*alloc_qpn)(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt, 237 int (*alloc_qpn)(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
237 enum ib_qp_type type, u8 port); 238 enum ib_qp_type type, u8 port, gfp_t gfp);
238}; 239};
239 240
240struct rvt_dev_info { 241struct rvt_dev_info {