Skip to content

Commit

Permalink
IB/core: add a simple MR pool
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Hellwig <hch@lst.de>
Tested-by: Steve Wise <swise@opengridcomputing.com>
Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
  • Loading branch information
Christoph Hellwig authored and Doug Ledford committed May 13, 2016
1 parent 04c41bf commit fffb038
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 2 deletions.
2 changes: 1 addition & 1 deletion drivers/infiniband/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \

ib_core-y := packer.o ud_header.o verbs.o cq.o sysfs.o \
device.o fmr_pool.o cache.o netlink.o \
roce_gid_mgmt.o
roce_gid_mgmt.o mr_pool.o
ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o

Expand Down
86 changes: 86 additions & 0 deletions drivers/infiniband/core/mr_pool.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2016 HGST, a Western Digital Company.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <rdma/ib_verbs.h>
#include <rdma/mr_pool.h>

struct ib_mr *ib_mr_pool_get(struct ib_qp *qp, struct list_head *list)
{
struct ib_mr *mr;
unsigned long flags;

spin_lock_irqsave(&qp->mr_lock, flags);
mr = list_first_entry_or_null(list, struct ib_mr, qp_entry);
if (mr) {
list_del(&mr->qp_entry);
qp->mrs_used++;
}
spin_unlock_irqrestore(&qp->mr_lock, flags);

return mr;
}
EXPORT_SYMBOL(ib_mr_pool_get);

void ib_mr_pool_put(struct ib_qp *qp, struct list_head *list, struct ib_mr *mr)
{
unsigned long flags;

spin_lock_irqsave(&qp->mr_lock, flags);
list_add(&mr->qp_entry, list);
qp->mrs_used--;
spin_unlock_irqrestore(&qp->mr_lock, flags);
}
EXPORT_SYMBOL(ib_mr_pool_put);

int ib_mr_pool_init(struct ib_qp *qp, struct list_head *list, int nr,
enum ib_mr_type type, u32 max_num_sg)
{
struct ib_mr *mr;
unsigned long flags;
int ret, i;

for (i = 0; i < nr; i++) {
mr = ib_alloc_mr(qp->pd, type, max_num_sg);
if (IS_ERR(mr)) {
ret = PTR_ERR(mr);
goto out;
}

spin_lock_irqsave(&qp->mr_lock, flags);
list_add_tail(&mr->qp_entry, list);
spin_unlock_irqrestore(&qp->mr_lock, flags);
}

return 0;
out:
ib_mr_pool_destroy(qp, list);
return ret;
}
EXPORT_SYMBOL(ib_mr_pool_init);

void ib_mr_pool_destroy(struct ib_qp *qp, struct list_head *list)
{
struct ib_mr *mr;
unsigned long flags;

spin_lock_irqsave(&qp->mr_lock, flags);
while (!list_empty(list)) {
mr = list_first_entry(list, struct ib_mr, qp_entry);
list_del(&mr->qp_entry);

spin_unlock_irqrestore(&qp->mr_lock, flags);
ib_dereg_mr(mr);
spin_lock_irqsave(&qp->mr_lock, flags);
}
spin_unlock_irqrestore(&qp->mr_lock, flags);
}
EXPORT_SYMBOL(ib_mr_pool_destroy);
5 changes: 5 additions & 0 deletions drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,9 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->qp_type = qp_init_attr->qp_type;

atomic_set(&qp->usecnt, 0);
qp->mrs_used = 0;
spin_lock_init(&qp->mr_lock);

if (qp_init_attr->qp_type == IB_QPT_XRC_TGT)
return ib_create_xrc_qp(qp, qp_init_attr);

Expand Down Expand Up @@ -1255,6 +1258,8 @@ int ib_destroy_qp(struct ib_qp *qp)
struct ib_srq *srq;
int ret;

WARN_ON_ONCE(qp->mrs_used > 0);

if (atomic_read(&qp->usecnt))
return -EBUSY;

Expand Down
8 changes: 7 additions & 1 deletion include/rdma/ib_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1421,9 +1421,12 @@ struct ib_qp {
struct ib_pd *pd;
struct ib_cq *send_cq;
struct ib_cq *recv_cq;
spinlock_t mr_lock;
int mrs_used;
struct ib_srq *srq;
struct ib_xrcd *xrcd; /* XRC TGT QPs only */
struct list_head xrcd_list;

/* count times opened, mcast attaches, flow attaches */
atomic_t usecnt;
struct list_head open_list;
Expand All @@ -1438,12 +1441,15 @@ struct ib_qp {
struct ib_mr {
struct ib_device *device;
struct ib_pd *pd;
struct ib_uobject *uobject;
u32 lkey;
u32 rkey;
u64 iova;
u32 length;
unsigned int page_size;
union {
struct ib_uobject *uobject; /* user */
struct list_head qp_entry; /* FR */
};
};

struct ib_mw {
Expand Down
25 changes: 25 additions & 0 deletions include/rdma/mr_pool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2016 HGST, a Western Digital Company.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef _RDMA_MR_POOL_H
#define _RDMA_MR_POOL_H 1

#include <rdma/ib_verbs.h>

struct ib_mr *ib_mr_pool_get(struct ib_qp *qp, struct list_head *list);
void ib_mr_pool_put(struct ib_qp *qp, struct list_head *list, struct ib_mr *mr);

int ib_mr_pool_init(struct ib_qp *qp, struct list_head *list, int nr,
enum ib_mr_type type, u32 max_num_sg);
void ib_mr_pool_destroy(struct ib_qp *qp, struct list_head *list);

#endif /* _RDMA_MR_POOL_H */

0 comments on commit fffb038

Please sign in to comment.