drivers/infiniband/core/cache.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/core/cache.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/core/cache.c
Extension
.c
Size
43485 bytes
Lines
1658
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ib_pkey_cache {
	int             table_len;
	u16             table[] __counted_by(table_len);
};

struct ib_update_work {
	struct work_struct work;
	struct ib_event event;
	bool enforce_security;
};

union ib_gid zgid;
EXPORT_SYMBOL(zgid);

enum gid_attr_find_mask {
	GID_ATTR_FIND_MASK_GID          = 1UL << 0,
	GID_ATTR_FIND_MASK_NETDEV	= 1UL << 1,
	GID_ATTR_FIND_MASK_DEFAULT	= 1UL << 2,
	GID_ATTR_FIND_MASK_GID_TYPE	= 1UL << 3,
};

enum gid_table_entry_state {
	GID_TABLE_ENTRY_INVALID		= 1,
	GID_TABLE_ENTRY_VALID		= 2,
	/*
	 * Indicates that entry is pending to be removed, there may
	 * be active users of this GID entry.
	 * When last user of the GID entry releases reference to it,
	 * GID entry is detached from the table.
	 */
	GID_TABLE_ENTRY_PENDING_DEL	= 3,
};

struct roce_gid_ndev_storage {
	struct rcu_head rcu_head;
	struct net_device *ndev;
};

struct ib_gid_table_entry {
	struct kref			kref;
	struct work_struct		del_work;
	struct ib_gid_attr		attr;
	void				*context;
	/* Store the ndev pointer to release reference later on in
	 * call_rcu context because by that time gid_table_entry
	 * and attr might be already freed. So keep a copy of it.
	 * ndev_storage is freed by rcu callback.
	 */
	struct roce_gid_ndev_storage	*ndev_storage;
	enum gid_table_entry_state	state;
};

struct ib_gid_table {
	int				sz;
	/* In RoCE, adding a GID to the table requires:
	 * (a) Find if this GID is already exists.
	 * (b) Find a free space.
	 * (c) Write the new GID
	 *
	 * Delete requires different set of operations:
	 * (a) Find the GID
	 * (b) Delete it.
	 *
	 **/
	/* Any writer to data_vec must hold this lock and the write side of
	 * rwlock. Readers must hold only rwlock. All writers must be in a
	 * sleepable context.
	 */
	struct mutex			lock;
	/* rwlock protects data_vec[ix]->state and entry pointer.
	 */
	rwlock_t			rwlock;
	/* bit field, each bit indicates the index of default GID */
	u32				default_gid_indices;
	struct ib_gid_table_entry	*data_vec[] __counted_by(sz);
};

static void dispatch_gid_change_event(struct ib_device *ib_dev, u32 port)
{
	struct ib_event event;

	event.device		= ib_dev;
	event.element.port_num	= port;
	event.event		= IB_EVENT_GID_CHANGE;

	ib_dispatch_event_clients(&event);
}

static const char * const gid_type_str[] = {
	/* IB/RoCE v1 value is set for IB_GID_TYPE_IB and IB_GID_TYPE_ROCE for

Annotation

Implementation Notes