1 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 /* 3 * Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved. 4 */ 5 6 #ifndef _RDMA_RESTRACK_H_ 7 #define _RDMA_RESTRACK_H_ 8 9 #include <linux/typecheck.h> 10 #include <linux/rwsem.h> 11 #include <linux/sched.h> 12 #include <linux/kref.h> 13 #include <linux/completion.h> 14 15 /** 16 * enum rdma_restrack_type - HW objects to track 17 */ 18 enum rdma_restrack_type { 19 /** 20 * @RDMA_RESTRACK_PD: Protection domain (PD) 21 */ 22 RDMA_RESTRACK_PD, 23 /** 24 * @RDMA_RESTRACK_CQ: Completion queue (CQ) 25 */ 26 RDMA_RESTRACK_CQ, 27 /** 28 * @RDMA_RESTRACK_QP: Queue pair (QP) 29 */ 30 RDMA_RESTRACK_QP, 31 /** 32 * @RDMA_RESTRACK_XRCD: XRC domain (XRCD) 33 */ 34 RDMA_RESTRACK_XRCD, 35 /** 36 * @RDMA_RESTRACK_MAX: Last entry, used for array dclarations 37 */ 38 RDMA_RESTRACK_MAX 39 }; 40 41 #define RDMA_RESTRACK_HASH_BITS 8 42 /** 43 * struct rdma_restrack_root - main resource tracking management 44 * entity, per-device 45 */ 46 struct rdma_restrack_root { 47 /* 48 * @rwsem: Read/write lock to protect lists 49 */ 50 struct rw_semaphore rwsem; 51 /** 52 * @hash: global database for all resources per-device 53 */ 54 DECLARE_HASHTABLE(hash, RDMA_RESTRACK_HASH_BITS); 55 }; 56 57 /** 58 * struct rdma_restrack_entry - metadata per-entry 59 */ 60 struct rdma_restrack_entry { 61 /** 62 * @valid: validity indicator 63 * 64 * The entries are filled during rdma_restrack_add, 65 * can be attempted to be free during rdma_restrack_del. 66 * 67 * As an example for that, see mlx5 QPs with type MLX5_IB_QPT_HW_GSI 68 */ 69 bool valid; 70 /* 71 * @kref: Protect destroy of the resource 72 */ 73 struct kref kref; 74 /* 75 * @comp: Signal that all consumers of resource are completed their work 76 */ 77 struct completion comp; 78 /** 79 * @task: owner of resource tracking entity 80 * 81 * There are two types of entities: created by user and created 82 * by kernel. 83 * 84 * This is relevant for the entities created by users. 85 * For the entities created by kernel, this pointer will be NULL. 86 */ 87 struct task_struct *task; 88 /** 89 * @kern_name: name of owner for the kernel created entities. 90 */ 91 const char *kern_name; 92 /** 93 * @node: hash table entry 94 */ 95 struct hlist_node node; 96 /** 97 * @type: various objects in restrack database 98 */ 99 enum rdma_restrack_type type; 100 }; 101 102 /** 103 * rdma_restrack_init() - initialize resource tracking 104 * @res: resource tracking root 105 */ 106 void rdma_restrack_init(struct rdma_restrack_root *res); 107 108 /** 109 * rdma_restrack_clean() - clean resource tracking 110 * @res: resource tracking root 111 */ 112 void rdma_restrack_clean(struct rdma_restrack_root *res); 113 114 /** 115 * rdma_restrack_count() - the current usage of specific object 116 * @res: resource entry 117 * @type: actual type of object to operate 118 * @ns: PID namespace 119 */ 120 int rdma_restrack_count(struct rdma_restrack_root *res, 121 enum rdma_restrack_type type, 122 struct pid_namespace *ns); 123 124 /** 125 * rdma_restrack_add() - add object to the reource tracking database 126 * @res: resource entry 127 */ 128 void rdma_restrack_add(struct rdma_restrack_entry *res); 129 130 /** 131 * rdma_restrack_del() - delete object from the reource tracking database 132 * @res: resource entry 133 * @type: actual type of object to operate 134 */ 135 void rdma_restrack_del(struct rdma_restrack_entry *res); 136 137 /** 138 * rdma_is_kernel_res() - check the owner of resource 139 * @res: resource entry 140 */ 141 static inline bool rdma_is_kernel_res(struct rdma_restrack_entry *res) 142 { 143 return !res->task; 144 } 145 146 /** 147 * rdma_restrack_get() - grab to protect resource from release 148 * @res: resource entry 149 */ 150 int __must_check rdma_restrack_get(struct rdma_restrack_entry *res); 151 152 /** 153 * rdma_restrack_put() - relase resource 154 * @res: resource entry 155 */ 156 int rdma_restrack_put(struct rdma_restrack_entry *res); 157 #endif /* _RDMA_RESTRACK_H_ */ 158