drivers/infiniband/hw/mlx4/mcg.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mlx4/mcg.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mlx4/mcg.c
Extension
.c
Size
36091 bytes
Lines
1268
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source 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 mcast_member {
	enum mcast_state state;
	uint8_t			join_state;
	int			num_pend_reqs;
	struct list_head	pending;
};

struct ib_sa_mcmember_data {
	union ib_gid	mgid;
	union ib_gid	port_gid;
	__be32		qkey;
	__be16		mlid;
	u8		mtusel_mtu;
	u8		tclass;
	__be16		pkey;
	u8		ratesel_rate;
	u8		lifetmsel_lifetm;
	__be32		sl_flowlabel_hoplimit;
	u8		scope_join_state;
	u8		proxy_join;
	u8		reserved[2];
} __packed __aligned(4);

struct mcast_group {
	struct ib_sa_mcmember_data rec;
	struct rb_node		node;
	struct list_head	mgid0_list;
	struct mlx4_ib_demux_ctx *demux;
	struct mcast_member	func[MAX_VFS];
	struct mutex		lock;
	struct work_struct	work;
	struct list_head	pending_list;
	int			members[3];
	enum mcast_group_state	state;
	enum mcast_group_state	prev_state;
	struct ib_sa_mad	response_sa_mad;
	__be64			last_req_tid;

	char			name[33]; /* MGID string */
	struct device_attribute	dentry;

	/* refcount is the reference count for the following:
	   1. Each queued request
	   2. Each invocation of the worker thread
	   3. Membership of the port at the SA
	*/
	atomic_t		refcount;

	/* delayed work to clean pending SM request */
	struct delayed_work	timeout_work;
	struct list_head	cleanup_list;
};

struct mcast_req {
	int			func;
	struct ib_sa_mad	sa_mad;
	struct list_head	group_list;
	struct list_head	func_list;
	struct mcast_group	*group;
	int			clean;
};


#define safe_atomic_dec(ref) \
	do {\
		if (atomic_dec_and_test(ref)) \
			mcg_warn_group(group, "did not expect to reach zero\n"); \
	} while (0)

static const char *get_state_string(enum mcast_group_state state)
{
	switch (state) {
	case MCAST_IDLE:
		return "MCAST_IDLE";
	case MCAST_JOIN_SENT:
		return "MCAST_JOIN_SENT";
	case MCAST_LEAVE_SENT:
		return "MCAST_LEAVE_SENT";
	case MCAST_RESP_READY:
		return "MCAST_RESP_READY";
	}
	return "Invalid State";
}

static struct mcast_group *mcast_find(struct mlx4_ib_demux_ctx *ctx,
				      union ib_gid *mgid)
{
	struct rb_node *node = ctx->mcg_table.rb_node;
	struct mcast_group *group;
	int ret;

Annotation

Implementation Notes