linux/drivers/infiniband/hw/efa/efa_ah_cache.h
Yonatan Nachum 234895fa8b RDMA/efa: Add AH cache handling on create and destroy AH
On create AH, first check if the AH cache entry already exists and if
so, returns the already stored AH number. If the entry doesn't exist,
the driver creates it and calls the device to create the AH. A per-entry
mutex serializes concurrent device commands on the same AH cache entry,
ensuring only one thread issues the device create while others wait and
reuse the result. If the device create fails, the entry's user count
remains zero so subsequent threads will retry the device create.

On destroy AH, the user count is decremented under the entry mutex. If
it reaches zero, the driver issues the device destroy command. After
the device destroy completes, it removes the entry from the hashtable
and frees it if no other references exist.  If new users arrived during
the destroy, the entry remains in the hashtable for reuse.

Reviewed-by: Firas Jahjah <firasj@amazon.com>
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
Link: https://patch.msgid.link/20260706170008.1039417-3-ynachum@amazon.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
2026-07-12 04:43:17 -04:00

40 lines
1.1 KiB
C

/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
/*
* Copyright 2026 Amazon.com, Inc. or its affiliates. All rights reserved.
*/
#ifndef _EFA_AH_CACHE_H_
#define _EFA_AH_CACHE_H_
#include <linux/refcount.h>
#include <linux/rhashtable.h>
#define EFA_AH_GID_SIZE 16
struct efa_ah_cache_key {
u8 gid[EFA_AH_GID_SIZE];
u16 pd;
};
struct efa_ah_cache_entry {
struct efa_ah_cache_key key;
u16 ah;
unsigned int usecnt;
refcount_t refcount;
struct rhash_head linkage;
struct mutex lock; /* Serializes device commands per cache entry */
};
struct efa_ah_cache {
struct rhashtable hashtable;
struct mutex lock; /* Protects AH cache hashtable */
};
int efa_ah_cache_init(struct efa_ah_cache *ah_cache);
void efa_ah_cache_destroy(struct efa_ah_cache *ah_cache);
struct efa_ah_cache_entry *efa_ah_cache_get(struct efa_ah_cache *ah_cache, u16 pd, u8 *gid);
struct efa_ah_cache_entry *efa_ah_cache_lookup(struct efa_ah_cache *ah_cache, u16 pd, u8 *gid);
void efa_ah_cache_put(struct efa_ah_cache *ah_cache, struct efa_ah_cache_entry *entry);
#endif /* _EFA_AH_CACHE_H_ */