[PATCH for-next 1/2] RDMA/core: Support drivers use of rcu locking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch allows drivers to optionally include struct rcu_head
in their private object data structs and have rdma-core use kfree_rcu
to free the objects.

The offsets of the rcu_heads are stored in fields in struct
ib_device_ops and a macro RDMA_KFREE_RCU is introduced which calls
(an open coded) kfree_rcu instead of kfree if the value is non-
zero. Currently the supported object types are AH, QP and MW.

Signed-off-by: Bob Pearson <rpearsonhpe@xxxxxxxxx>
---
 drivers/infiniband/core/uverbs_main.c |  2 +-
 drivers/infiniband/core/verbs.c       |  6 +++---
 include/rdma/ib_verbs.h               | 24 ++++++++++++++++++++++++
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 7c9c79c13941..50497e550f18 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -112,7 +112,7 @@ int uverbs_dealloc_mw(struct ib_mw *mw)
 		return ret;
 
 	atomic_dec(&pd->usecnt);
-	kfree(mw);
+	RDMA_KFREE_RCU(mw);
 	return ret;
 }
 
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index b99b3cc283b6..a49ae8c52c66 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -982,7 +982,7 @@ int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata)
 	if (sgid_attr)
 		rdma_put_gid_attr(sgid_attr);
 
-	kfree(ah);
+	RDMA_KFREE_RCU(ah);
 	return ret;
 }
 EXPORT_SYMBOL(rdma_destroy_ah_user);
@@ -1970,7 +1970,7 @@ int ib_close_qp(struct ib_qp *qp)
 	atomic_dec(&real_qp->usecnt);
 	if (qp->qp_sec)
 		ib_close_shared_qp_security(qp->qp_sec);
-	kfree(qp);
+	RDMA_KFREE_RCU(qp);
 
 	return 0;
 }
@@ -2041,7 +2041,7 @@ int ib_destroy_qp_user(struct ib_qp *qp, struct ib_udata *udata)
 		ib_destroy_qp_security_end(sec);
 
 	rdma_restrack_del(&qp->res);
-	kfree(qp);
+	RDMA_KFREE_RCU(qp);
 	return ret;
 }
 EXPORT_SYMBOL(ib_destroy_qp_user);
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 1e7774ac808f..616e9e54a733 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -2684,8 +2684,32 @@ struct ib_device_ops {
 	DECLARE_RDMA_OBJ_SIZE(ib_srq);
 	DECLARE_RDMA_OBJ_SIZE(ib_ucontext);
 	DECLARE_RDMA_OBJ_SIZE(ib_xrcd);
+
+	/* if non-zero holds offset of rcu_head in object */
+	ssize_t rcu_offset_ah;
+	ssize_t rcu_offset_qp;
+	ssize_t rcu_offset_mw;
+
 };
 
+/* drivers may optionally use rcu locking on verbs objects
+ * by including struct rcu_head in their private data and
+ * setting rcu_offset_xx in the ib_driver_ops struct where
+ * xx is one of ah, qp or mw.
+ */
+static inline void __rdma_kfree_rcu(void *obj, ssize_t rcu_offset)
+{
+	if (rcu_offset)
+		kvfree_call_rcu((struct rcu_head *)((u8 *)obj + rcu_offset),
+				obj);
+	else
+		kfree(obj);
+}
+
+/* obj must be one of ah, qp, or mw */
+#define RDMA_KFREE_RCU(obj) __rdma_kfree_rcu(obj,		\
+				obj->device->ops.rcu_offset_##obj)
+
 struct ib_core_device {
 	/* device must be the first element in structure until,
 	 * union of ib_core_device and device exists in ib_device.
-- 
2.39.2




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux