Commit da371107 authored by Patrisious Haddad's avatar Patrisious Haddad Committed by Leon Romanovsky
Browse files

RDMA/core: Add support to optional-counters binding configuration



Whenever a new counter is created, save inside it the user requested
configuration for optional-counters binding, for manual configuration it
is requested directly by the user and for the automatic configuration it
depends on if the automatic binding was enabled with or without
optional-counters binding.

This argument will later be used by the driver to determine if to bind the
optional-counters as well or not when trying to bind this counter to a QP.

It indicates that when binding counters to a QP we also want the
currently enabled link optional-counters to be bound as well.

Signed-off-by: default avatarPatrisious Haddad <phaddad@nvidia.com>
Reviewed-by: default avatarMark Bloch <mbloch@nvidia.com>
Link: https://patch.msgid.link/82f1c357606a16932979ef9a5910122675c74a3a.1741875070.git.leon@kernel.org


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 7e53b31a
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -12,7 +12,8 @@

static int __counter_set_mode(struct rdma_port_counter *port_counter,
			      enum rdma_nl_counter_mode new_mode,
			      enum rdma_nl_counter_mask new_mask)
			      enum rdma_nl_counter_mask new_mask,
			      bool bind_opcnt)
{
	if (new_mode == RDMA_COUNTER_MODE_AUTO) {
		if (new_mask & (~ALL_AUTO_MODE_MASKS))
@@ -23,6 +24,7 @@ static int __counter_set_mode(struct rdma_port_counter *port_counter,

	port_counter->mode.mode = new_mode;
	port_counter->mode.mask = new_mask;
	port_counter->mode.bind_opcnt = bind_opcnt;
	return 0;
}

@@ -41,6 +43,7 @@ static int __counter_set_mode(struct rdma_port_counter *port_counter,
 */
int rdma_counter_set_auto_mode(struct ib_device *dev, u32 port,
			       enum rdma_nl_counter_mask mask,
			       bool bind_opcnt,
			       struct netlink_ext_ack *extack)
{
	struct rdma_port_counter *port_counter;
@@ -59,12 +62,13 @@ int rdma_counter_set_auto_mode(struct ib_device *dev, u32 port,
						      RDMA_COUNTER_MODE_NONE;

	if (port_counter->mode.mode == mode &&
	    port_counter->mode.mask == mask) {
	    port_counter->mode.mask == mask &&
	    port_counter->mode.bind_opcnt == bind_opcnt) {
		ret = 0;
		goto out;
	}

	ret = __counter_set_mode(port_counter, mode, mask);
	ret = __counter_set_mode(port_counter, mode, mask, bind_opcnt);

out:
	mutex_unlock(&port_counter->lock);
@@ -140,7 +144,8 @@ int rdma_counter_modify(struct ib_device *dev, u32 port,

static struct rdma_counter *alloc_and_bind(struct ib_device *dev, u32 port,
					   struct ib_qp *qp,
					   enum rdma_nl_counter_mode mode)
					   enum rdma_nl_counter_mode mode,
					   bool bind_opcnt)
{
	struct rdma_port_counter *port_counter;
	struct rdma_counter *counter;
@@ -168,7 +173,7 @@ static struct rdma_counter *alloc_and_bind(struct ib_device *dev, u32 port,
	switch (mode) {
	case RDMA_COUNTER_MODE_MANUAL:
		ret = __counter_set_mode(port_counter, RDMA_COUNTER_MODE_MANUAL,
					 0);
					 0, bind_opcnt);
		if (ret) {
			mutex_unlock(&port_counter->lock);
			goto err_mode;
@@ -187,6 +192,7 @@ static struct rdma_counter *alloc_and_bind(struct ib_device *dev, u32 port,
	mutex_unlock(&port_counter->lock);

	counter->mode.mode = mode;
	counter->mode.bind_opcnt = bind_opcnt;
	kref_init(&counter->kref);
	mutex_init(&counter->lock);

@@ -215,7 +221,8 @@ static void rdma_counter_free(struct rdma_counter *counter)
	port_counter->num_counters--;
	if (!port_counter->num_counters &&
	    (port_counter->mode.mode == RDMA_COUNTER_MODE_MANUAL))
		__counter_set_mode(port_counter, RDMA_COUNTER_MODE_NONE, 0);
		__counter_set_mode(port_counter, RDMA_COUNTER_MODE_NONE, 0,
				   false);

	mutex_unlock(&port_counter->lock);

@@ -347,7 +354,8 @@ int rdma_counter_bind_qp_auto(struct ib_qp *qp, u32 port)
			return ret;
		}
	} else {
		counter = alloc_and_bind(dev, port, qp, RDMA_COUNTER_MODE_AUTO);
		counter = alloc_and_bind(dev, port, qp, RDMA_COUNTER_MODE_AUTO,
					 port_counter->mode.bind_opcnt);
		if (!counter)
			return -ENOMEM;
	}
@@ -560,7 +568,7 @@ int rdma_counter_bind_qpn_alloc(struct ib_device *dev, u32 port,
		goto err;
	}

	counter = alloc_and_bind(dev, port, qp, RDMA_COUNTER_MODE_MANUAL);
	counter = alloc_and_bind(dev, port, qp, RDMA_COUNTER_MODE_MANUAL, true);
	if (!counter) {
		ret = -ENOMEM;
		goto err;
@@ -615,13 +623,15 @@ int rdma_counter_unbind_qpn(struct ib_device *dev, u32 port,

int rdma_counter_get_mode(struct ib_device *dev, u32 port,
			  enum rdma_nl_counter_mode *mode,
			  enum rdma_nl_counter_mask *mask)
			  enum rdma_nl_counter_mask *mask,
			  bool *opcnt)
{
	struct rdma_port_counter *port_counter;

	port_counter = &dev->port_data[port].port_counter;
	*mode = port_counter->mode.mode;
	*mask = port_counter->mode.mask;
	*opcnt = port_counter->mode.bind_opcnt;

	return 0;
}
+16 −2
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
	[RDMA_NLDEV_ATTR_PARENT_NAME]		= { .type = NLA_NUL_STRING },
	[RDMA_NLDEV_ATTR_NAME_ASSIGN_TYPE]	= { .type = NLA_U8 },
	[RDMA_NLDEV_ATTR_EVENT_TYPE]		= { .type = NLA_U8 },
	[RDMA_NLDEV_ATTR_STAT_OPCOUNTER_ENABLED] = { .type = NLA_U8 },
};

static int put_driver_name_print_type(struct sk_buff *msg, const char *name,
@@ -2028,6 +2029,7 @@ static int nldev_stat_set_mode_doit(struct sk_buff *msg,
				    struct ib_device *device, u32 port)
{
	u32 mode, mask = 0, qpn, cntn = 0;
	bool opcnt = false;
	int ret;

	/* Currently only counter for QP is supported */
@@ -2035,12 +2037,17 @@ static int nldev_stat_set_mode_doit(struct sk_buff *msg,
	    nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_RES]) != RDMA_NLDEV_ATTR_RES_QP)
		return -EINVAL;

	if (tb[RDMA_NLDEV_ATTR_STAT_OPCOUNTER_ENABLED])
		opcnt = !!nla_get_u8(
			tb[RDMA_NLDEV_ATTR_STAT_OPCOUNTER_ENABLED]);

	mode = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_MODE]);
	if (mode == RDMA_COUNTER_MODE_AUTO) {
		if (tb[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK])
			mask = nla_get_u32(
				tb[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK]);
		return rdma_counter_set_auto_mode(device, port, mask, extack);
		return rdma_counter_set_auto_mode(device, port, mask, opcnt,
						  extack);
	}

	if (!tb[RDMA_NLDEV_ATTR_RES_LQPN])
@@ -2358,6 +2365,7 @@ static int stat_get_doit_qp(struct sk_buff *skb, struct nlmsghdr *nlh,
	struct ib_device *device;
	struct sk_buff *msg;
	u32 index, port;
	bool opcnt;
	int ret;

	if (tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID])
@@ -2393,7 +2401,7 @@ static int stat_get_doit_qp(struct sk_buff *skb, struct nlmsghdr *nlh,
		goto err_msg;
	}

	ret = rdma_counter_get_mode(device, port, &mode, &mask);
	ret = rdma_counter_get_mode(device, port, &mode, &mask, &opcnt);
	if (ret)
		goto err_msg;

@@ -2410,6 +2418,12 @@ static int stat_get_doit_qp(struct sk_buff *skb, struct nlmsghdr *nlh,
		goto err_msg;
	}

	if ((mode == RDMA_COUNTER_MODE_AUTO) &&
	    nla_put_u8(msg, RDMA_NLDEV_ATTR_STAT_OPCOUNTER_ENABLED, opcnt)) {
		ret = -EMSGSIZE;
		goto err_msg;
	}

	nlmsg_end(msg, nlh);
	ib_device_put(device);
	return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
+4 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ struct rdma_counter_mode {
	enum rdma_nl_counter_mode mode;
	enum rdma_nl_counter_mask mask;
	struct auto_mode_param param;
	bool bind_opcnt;
};

struct rdma_port_counter {
@@ -47,6 +48,7 @@ void rdma_counter_init(struct ib_device *dev);
void rdma_counter_release(struct ib_device *dev);
int rdma_counter_set_auto_mode(struct ib_device *dev, u32 port,
			       enum rdma_nl_counter_mask mask,
			       bool bind_opcnt,
			       struct netlink_ext_ack *extack);
int rdma_counter_bind_qp_auto(struct ib_qp *qp, u32 port);
int rdma_counter_unbind_qp(struct ib_qp *qp, bool force);
@@ -61,7 +63,8 @@ int rdma_counter_unbind_qpn(struct ib_device *dev, u32 port,
			    u32 qp_num, u32 counter_id);
int rdma_counter_get_mode(struct ib_device *dev, u32 port,
			  enum rdma_nl_counter_mode *mode,
			  enum rdma_nl_counter_mask *mask);
			  enum rdma_nl_counter_mask *mask,
			  bool *opcnt);

int rdma_counter_modify(struct ib_device *dev, u32 port,
			unsigned int index, bool enable);
+2 −0
Original line number Diff line number Diff line
@@ -580,6 +580,8 @@ enum rdma_nldev_attr {
	RDMA_NLDEV_ATTR_EVENT_TYPE,		/* u8 */

	RDMA_NLDEV_SYS_ATTR_MONITOR_MODE,	/* u8 */

	RDMA_NLDEV_ATTR_STAT_OPCOUNTER_ENABLED,	/* u8 */
	/*
	 * Always the end
	 */