RDMA/core: Add support to optional-counters binding configuration
authorPatrisious Haddad <phaddad@nvidia.com>
Thu, 13 Mar 2025 14:18:43 +0000 (16:18 +0200)
committerLeon Romanovsky <leon@kernel.org>
Tue, 18 Mar 2025 10:18:42 +0000 (06:18 -0400)
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: Patrisious Haddad <phaddad@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Link: https://patch.msgid.link/82f1c357606a16932979ef9a5910122675c74a3a.1741875070.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/core/counters.c
drivers/infiniband/core/nldev.c
include/rdma/rdma_counter.h
include/uapi/rdma/rdma_netlink.h

index 981d5a28614a21a1694dd07bf2c06c51c40a4476..b270a208214e2f4625782afa76caba66194081ce 100644 (file)
@@ -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 @@ out:
 
 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 @@ out:
 
 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;
 }
index cb987ab0177c857a34e94f032323cb0522675598..a872643e8039fc182fd77fb1f0a6e8807697fdbb 100644 (file)
@@ -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);
index 45d5481a7846abc566a31ecae789d3037ab8af06..74e635409ff73f54d6cdc33260fe10e7b14382e7 100644 (file)
@@ -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);
index 9f9cf20c1cd87978171f71f5fa8f35ad93e981b1..f41f0228fcd0e0b74e74b4d87611546b00f799a1 100644 (file)
@@ -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
         */