162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef _RDMA_RESTRACK_H_
762306a36Sopenharmony_ci#define _RDMA_RESTRACK_H_
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/typecheck.h>
1062306a36Sopenharmony_ci#include <linux/sched.h>
1162306a36Sopenharmony_ci#include <linux/kref.h>
1262306a36Sopenharmony_ci#include <linux/completion.h>
1362306a36Sopenharmony_ci#include <linux/sched/task.h>
1462306a36Sopenharmony_ci#include <uapi/rdma/rdma_netlink.h>
1562306a36Sopenharmony_ci#include <linux/xarray.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistruct ib_device;
1862306a36Sopenharmony_cistruct sk_buff;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/**
2162306a36Sopenharmony_ci * enum rdma_restrack_type - HW objects to track
2262306a36Sopenharmony_ci */
2362306a36Sopenharmony_cienum rdma_restrack_type {
2462306a36Sopenharmony_ci	/**
2562306a36Sopenharmony_ci	 * @RDMA_RESTRACK_PD: Protection domain (PD)
2662306a36Sopenharmony_ci	 */
2762306a36Sopenharmony_ci	RDMA_RESTRACK_PD,
2862306a36Sopenharmony_ci	/**
2962306a36Sopenharmony_ci	 * @RDMA_RESTRACK_CQ: Completion queue (CQ)
3062306a36Sopenharmony_ci	 */
3162306a36Sopenharmony_ci	RDMA_RESTRACK_CQ,
3262306a36Sopenharmony_ci	/**
3362306a36Sopenharmony_ci	 * @RDMA_RESTRACK_QP: Queue pair (QP)
3462306a36Sopenharmony_ci	 */
3562306a36Sopenharmony_ci	RDMA_RESTRACK_QP,
3662306a36Sopenharmony_ci	/**
3762306a36Sopenharmony_ci	 * @RDMA_RESTRACK_CM_ID: Connection Manager ID (CM_ID)
3862306a36Sopenharmony_ci	 */
3962306a36Sopenharmony_ci	RDMA_RESTRACK_CM_ID,
4062306a36Sopenharmony_ci	/**
4162306a36Sopenharmony_ci	 * @RDMA_RESTRACK_MR: Memory Region (MR)
4262306a36Sopenharmony_ci	 */
4362306a36Sopenharmony_ci	RDMA_RESTRACK_MR,
4462306a36Sopenharmony_ci	/**
4562306a36Sopenharmony_ci	 * @RDMA_RESTRACK_CTX: Verbs contexts (CTX)
4662306a36Sopenharmony_ci	 */
4762306a36Sopenharmony_ci	RDMA_RESTRACK_CTX,
4862306a36Sopenharmony_ci	/**
4962306a36Sopenharmony_ci	 * @RDMA_RESTRACK_COUNTER: Statistic Counter
5062306a36Sopenharmony_ci	 */
5162306a36Sopenharmony_ci	RDMA_RESTRACK_COUNTER,
5262306a36Sopenharmony_ci	/**
5362306a36Sopenharmony_ci	 * @RDMA_RESTRACK_SRQ: Shared receive queue (SRQ)
5462306a36Sopenharmony_ci	 */
5562306a36Sopenharmony_ci	RDMA_RESTRACK_SRQ,
5662306a36Sopenharmony_ci	/**
5762306a36Sopenharmony_ci	 * @RDMA_RESTRACK_MAX: Last entry, used for array dclarations
5862306a36Sopenharmony_ci	 */
5962306a36Sopenharmony_ci	RDMA_RESTRACK_MAX
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci/**
6362306a36Sopenharmony_ci * struct rdma_restrack_entry - metadata per-entry
6462306a36Sopenharmony_ci */
6562306a36Sopenharmony_cistruct rdma_restrack_entry {
6662306a36Sopenharmony_ci	/**
6762306a36Sopenharmony_ci	 * @valid: validity indicator
6862306a36Sopenharmony_ci	 *
6962306a36Sopenharmony_ci	 * The entries are filled during rdma_restrack_add,
7062306a36Sopenharmony_ci	 * can be attempted to be free during rdma_restrack_del.
7162306a36Sopenharmony_ci	 *
7262306a36Sopenharmony_ci	 * As an example for that, see mlx5 QPs with type MLX5_IB_QPT_HW_GSI
7362306a36Sopenharmony_ci	 */
7462306a36Sopenharmony_ci	bool			valid;
7562306a36Sopenharmony_ci	/**
7662306a36Sopenharmony_ci	 * @no_track: don't add this entry to restrack DB
7762306a36Sopenharmony_ci	 *
7862306a36Sopenharmony_ci	 * This field is used to mark an entry that doesn't need to be added to
7962306a36Sopenharmony_ci	 * internal restrack DB and presented later to the users at the nldev
8062306a36Sopenharmony_ci	 * query stage.
8162306a36Sopenharmony_ci	 */
8262306a36Sopenharmony_ci	u8			no_track : 1;
8362306a36Sopenharmony_ci	/*
8462306a36Sopenharmony_ci	 * @kref: Protect destroy of the resource
8562306a36Sopenharmony_ci	 */
8662306a36Sopenharmony_ci	struct kref		kref;
8762306a36Sopenharmony_ci	/*
8862306a36Sopenharmony_ci	 * @comp: Signal that all consumers of resource are completed their work
8962306a36Sopenharmony_ci	 */
9062306a36Sopenharmony_ci	struct completion	comp;
9162306a36Sopenharmony_ci	/**
9262306a36Sopenharmony_ci	 * @task: owner of resource tracking entity
9362306a36Sopenharmony_ci	 *
9462306a36Sopenharmony_ci	 * There are two types of entities: created by user and created
9562306a36Sopenharmony_ci	 * by kernel.
9662306a36Sopenharmony_ci	 *
9762306a36Sopenharmony_ci	 * This is relevant for the entities created by users.
9862306a36Sopenharmony_ci	 * For the entities created by kernel, this pointer will be NULL.
9962306a36Sopenharmony_ci	 */
10062306a36Sopenharmony_ci	struct task_struct	*task;
10162306a36Sopenharmony_ci	/**
10262306a36Sopenharmony_ci	 * @kern_name: name of owner for the kernel created entities.
10362306a36Sopenharmony_ci	 */
10462306a36Sopenharmony_ci	const char		*kern_name;
10562306a36Sopenharmony_ci	/**
10662306a36Sopenharmony_ci	 * @type: various objects in restrack database
10762306a36Sopenharmony_ci	 */
10862306a36Sopenharmony_ci	enum rdma_restrack_type	type;
10962306a36Sopenharmony_ci	/**
11062306a36Sopenharmony_ci	 * @user: user resource
11162306a36Sopenharmony_ci	 */
11262306a36Sopenharmony_ci	bool			user;
11362306a36Sopenharmony_ci	/**
11462306a36Sopenharmony_ci	 * @id: ID to expose to users
11562306a36Sopenharmony_ci	 */
11662306a36Sopenharmony_ci	u32 id;
11762306a36Sopenharmony_ci};
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ciint rdma_restrack_count(struct ib_device *dev,
12062306a36Sopenharmony_ci			enum rdma_restrack_type type);
12162306a36Sopenharmony_ci/**
12262306a36Sopenharmony_ci * rdma_is_kernel_res() - check the owner of resource
12362306a36Sopenharmony_ci * @res:  resource entry
12462306a36Sopenharmony_ci */
12562306a36Sopenharmony_cistatic inline bool rdma_is_kernel_res(const struct rdma_restrack_entry *res)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	return !res->user;
12862306a36Sopenharmony_ci}
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci/**
13162306a36Sopenharmony_ci * rdma_restrack_get() - grab to protect resource from release
13262306a36Sopenharmony_ci * @res:  resource entry
13362306a36Sopenharmony_ci */
13462306a36Sopenharmony_ciint __must_check rdma_restrack_get(struct rdma_restrack_entry *res);
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci/**
13762306a36Sopenharmony_ci * rdma_restrack_put() - release resource
13862306a36Sopenharmony_ci * @res:  resource entry
13962306a36Sopenharmony_ci */
14062306a36Sopenharmony_ciint rdma_restrack_put(struct rdma_restrack_entry *res);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/*
14362306a36Sopenharmony_ci * Helper functions for rdma drivers when filling out
14462306a36Sopenharmony_ci * nldev driver attributes.
14562306a36Sopenharmony_ci */
14662306a36Sopenharmony_ciint rdma_nl_put_driver_u32(struct sk_buff *msg, const char *name, u32 value);
14762306a36Sopenharmony_ciint rdma_nl_put_driver_u32_hex(struct sk_buff *msg, const char *name,
14862306a36Sopenharmony_ci			       u32 value);
14962306a36Sopenharmony_ciint rdma_nl_put_driver_u64(struct sk_buff *msg, const char *name, u64 value);
15062306a36Sopenharmony_ciint rdma_nl_put_driver_u64_hex(struct sk_buff *msg, const char *name,
15162306a36Sopenharmony_ci			       u64 value);
15262306a36Sopenharmony_ciint rdma_nl_put_driver_string(struct sk_buff *msg, const char *name,
15362306a36Sopenharmony_ci			      const char *str);
15462306a36Sopenharmony_ciint rdma_nl_stat_hwcounter_entry(struct sk_buff *msg, const char *name,
15562306a36Sopenharmony_ci				 u64 value);
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_cistruct rdma_restrack_entry *rdma_restrack_get_byid(struct ib_device *dev,
15862306a36Sopenharmony_ci						   enum rdma_restrack_type type,
15962306a36Sopenharmony_ci						   u32 id);
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci/**
16262306a36Sopenharmony_ci * rdma_restrack_no_track() - don't add resource to the DB
16362306a36Sopenharmony_ci * @res: resource entry
16462306a36Sopenharmony_ci *
16562306a36Sopenharmony_ci * Every user of this API should be cross examined.
16662306a36Sopenharmony_ci * Probably you don't need to use this function.
16762306a36Sopenharmony_ci */
16862306a36Sopenharmony_cistatic inline void rdma_restrack_no_track(struct rdma_restrack_entry *res)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	res->no_track = true;
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_cistatic inline bool rdma_restrack_is_tracked(struct rdma_restrack_entry *res)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	return !res->no_track;
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_ci#endif /* _RDMA_RESTRACK_H_ */
177