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