Thread (16 messages) 16 messages, 2 authors, 2021-12-09

Re: [PATCH for-next v6 3/8] RDMA/rxe: Cleanup pool APIs for keyed objects

From: Jason Gunthorpe <jgg@nvidia.com>
Date: 2021-12-07 19:19:03

On Mon, Dec 06, 2021 at 03:12:38PM -0600, Bob Pearson wrote:
+/**
+ * rxe_pool_add_key() - lookup or add object with key in pool
+ * @pool: the object pool
+ * @key: the key
+ *
+ * Returns: If object matching key is present in pool return
+ *	    its address and take a reference else allocate a
+ *	    new object to pool with key and return its address
+ *	    with one reference.
+ */
+void *rxe_pool_add_key(struct rxe_pool *pool, void *key)
+{
+	void *obj;
+
+	rxe_pool_lock_bh(pool);
+	obj = __rxe_get_key(pool, key);
+	if (obj)
+		goto done;
+
+	obj = __rxe_alloc(pool, GFP_ATOMIC);
Really try hard to avoid GFP_ATOMIC:

	rxe_pool_lock_bh(pool);
	obj = __rxe_get_key(pool, key);
        rxe_pool_unlock_bh(pool);
	if (obj)
	   return obj;

	obj = __rxe_alloc(pool, GFP_KERNEL);
	if (!obj)
	   return NULL;

	rxe_pool_lock_bh(pool);
	old_obj = __xa_cmpxchg(&pool->xarray.xa, key, NULL, entry, GFP_KERNEL);
	if (xa_is_err(old_obj))
           kfree(obj)
	   return NULL;

 	if (old_obj) {
	   kfree(obj);
	   obj = old_obj;
        }
        kref_get(old_obj)
        rxe_pool_unlock_bh(pool);
	return obj;       

If it is very rare that this function would collide the index then
forget the first lookup and use the cmpxchg
+void rxe_elem_release(struct kref *kref)
+{
+	struct rxe_pool_elem *elem =
+		container_of(kref, struct rxe_pool_elem, ref_cnt);
+	struct rxe_pool *pool = elem->pool;
+
+	if (pool->flags & RXE_POOL_INDEX)
+		__xa_erase(&pool->xarray.xa, elem->index);
+
+	if (pool->flags & RXE_POOL_KEY)
+		rb_erase(&elem->key_node, &pool->key.tree);
It is a bit jarring to see these as not exclusive ?

Jason
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help