Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RDMA/counter: Add set/clear per-port auto mode support

Add an API to support set/clear per-port auto mode.

Signed-off-by: Mark Zhang <markz@mellanox.com>
Reviewed-by: Majd Dibbiny <majd@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>

authored by

Mark Zhang and committed by
Jason Gunthorpe
413d3347 6a6c306a

+132 -1
+1 -1
drivers/infiniband/core/Makefile
··· 11 11 device.o fmr_pool.o cache.o netlink.o \ 12 12 roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \ 13 13 multicast.o mad.o smi.o agent.o mad_rmpp.o \ 14 - nldev.o restrack.o 14 + nldev.o restrack.o counters.o 15 15 16 16 ib_core-$(CONFIG_SECURITY_INFINIBAND) += security.o 17 17 ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o
+74
drivers/infiniband/core/counters.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 + /* 3 + * Copyright (c) 2019 Mellanox Technologies. All rights reserved. 4 + */ 5 + #include <rdma/ib_verbs.h> 6 + #include <rdma/rdma_counter.h> 7 + 8 + #include "core_priv.h" 9 + #include "restrack.h" 10 + 11 + #define ALL_AUTO_MODE_MASKS (RDMA_COUNTER_MASK_QP_TYPE) 12 + 13 + static int __counter_set_mode(struct rdma_counter_mode *curr, 14 + enum rdma_nl_counter_mode new_mode, 15 + enum rdma_nl_counter_mask new_mask) 16 + { 17 + if ((new_mode == RDMA_COUNTER_MODE_AUTO) && 18 + ((new_mask & (~ALL_AUTO_MODE_MASKS)) || 19 + (curr->mode != RDMA_COUNTER_MODE_NONE))) 20 + return -EINVAL; 21 + 22 + curr->mode = new_mode; 23 + curr->mask = new_mask; 24 + return 0; 25 + } 26 + 27 + /** 28 + * rdma_counter_set_auto_mode() - Turn on/off per-port auto mode 29 + * 30 + * When @on is true, the @mask must be set 31 + */ 32 + int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port, 33 + bool on, enum rdma_nl_counter_mask mask) 34 + { 35 + struct rdma_port_counter *port_counter; 36 + int ret; 37 + 38 + port_counter = &dev->port_data[port].port_counter; 39 + mutex_lock(&port_counter->lock); 40 + if (on) { 41 + ret = __counter_set_mode(&port_counter->mode, 42 + RDMA_COUNTER_MODE_AUTO, mask); 43 + } else { 44 + if (port_counter->mode.mode != RDMA_COUNTER_MODE_AUTO) { 45 + ret = -EINVAL; 46 + goto out; 47 + } 48 + ret = __counter_set_mode(&port_counter->mode, 49 + RDMA_COUNTER_MODE_NONE, 0); 50 + } 51 + 52 + out: 53 + mutex_unlock(&port_counter->lock); 54 + return ret; 55 + } 56 + 57 + void rdma_counter_init(struct ib_device *dev) 58 + { 59 + struct rdma_port_counter *port_counter; 60 + u32 port; 61 + 62 + if (!dev->ops.alloc_hw_stats || !dev->port_data) 63 + return; 64 + 65 + rdma_for_each_port(dev, port) { 66 + port_counter = &dev->port_data[port].port_counter; 67 + port_counter->mode.mode = RDMA_COUNTER_MODE_NONE; 68 + mutex_init(&port_counter->lock); 69 + } 70 + } 71 + 72 + void rdma_counter_release(struct ib_device *dev) 73 + { 74 + }
+5
drivers/infiniband/core/device.c
··· 46 46 #include <rdma/rdma_netlink.h> 47 47 #include <rdma/ib_addr.h> 48 48 #include <rdma/ib_cache.h> 49 + #include <rdma/rdma_counter.h> 49 50 50 51 #include "core_priv.h" 51 52 #include "restrack.h" ··· 493 492 if (dev->port_data) { 494 493 ib_cache_release_one(dev); 495 494 ib_security_release_port_pkey_list(dev); 495 + rdma_counter_release(dev); 496 496 kfree_rcu(container_of(dev->port_data, struct ib_port_data_rcu, 497 497 pdata[0]), 498 498 rcu_head); 499 499 } 500 + 500 501 xa_destroy(&dev->compat_devs); 501 502 xa_destroy(&dev->client_data); 502 503 kfree_rcu(dev, rcu_head); ··· 1318 1315 } 1319 1316 1320 1317 ib_device_register_rdmacg(device); 1318 + 1319 + rdma_counter_init(device); 1321 1320 1322 1321 /* 1323 1322 * Ensure that ADD uevent is not fired because it
+2
include/rdma/ib_verbs.h
··· 62 62 #include <linux/irqflags.h> 63 63 #include <linux/preempt.h> 64 64 #include <uapi/rdma/ib_user_verbs.h> 65 + #include <rdma/rdma_counter.h> 65 66 #include <rdma/restrack.h> 66 67 #include <rdma/signature.h> 67 68 #include <uapi/rdma/rdma_user_ioctl.h> ··· 2120 2119 spinlock_t netdev_lock; 2121 2120 struct net_device __rcu *netdev; 2122 2121 struct hlist_node ndev_hash_link; 2122 + struct rdma_port_counter port_counter; 2123 2123 }; 2124 2124 2125 2125 /* rdma netdev type - specifies protocol type */
+24
include/rdma/rdma_counter.h
··· 6 6 #ifndef _RDMA_COUNTER_H_ 7 7 #define _RDMA_COUNTER_H_ 8 8 9 + #include <linux/mutex.h> 10 + 9 11 #include <rdma/ib_verbs.h> 10 12 #include <rdma/restrack.h> 13 + #include <rdma/rdma_netlink.h> 14 + 15 + struct auto_mode_param { 16 + int qp_type; 17 + }; 18 + 19 + struct rdma_counter_mode { 20 + enum rdma_nl_counter_mode mode; 21 + enum rdma_nl_counter_mask mask; 22 + struct auto_mode_param param; 23 + }; 24 + 25 + struct rdma_port_counter { 26 + struct rdma_counter_mode mode; 27 + struct mutex lock; 28 + }; 11 29 12 30 struct rdma_counter { 13 31 struct rdma_restrack_entry res; ··· 33 15 uint32_t id; 34 16 u8 port; 35 17 }; 18 + 19 + void rdma_counter_init(struct ib_device *dev); 20 + void rdma_counter_release(struct ib_device *dev); 21 + int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port, 22 + bool on, enum rdma_nl_counter_mask mask); 23 + 36 24 #endif /* _RDMA_COUNTER_H_ */
+26
include/uapi/rdma/rdma_netlink.h
··· 507 507 */ 508 508 RDMA_NLDEV_ATTR_MAX 509 509 }; 510 + 511 + /* 512 + * Supported counter bind modes. All modes are mutual-exclusive. 513 + */ 514 + enum rdma_nl_counter_mode { 515 + RDMA_COUNTER_MODE_NONE, 516 + 517 + /* 518 + * A qp is bound with a counter automatically during initialization 519 + * based on the auto mode (e.g., qp type, ...) 520 + */ 521 + RDMA_COUNTER_MODE_AUTO, 522 + 523 + /* 524 + * Always the end 525 + */ 526 + RDMA_COUNTER_MODE_MAX, 527 + }; 528 + 529 + /* 530 + * Supported criteria in counter auto mode. 531 + * Currently only "qp type" is supported 532 + */ 533 + enum rdma_nl_counter_mask { 534 + RDMA_COUNTER_MASK_QP_TYPE = 1, 535 + }; 510 536 #endif /* _UAPI_RDMA_NETLINK_H */