1/*-
2 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26#ifndef __MLX5_EN_RL_H__
27#define __MLX5_EN_RL_H__
28
29#include <sys/param.h>
30#include <sys/lock.h>
31#include <sys/mutex.h>
32#include <sys/sx.h>
33#include <sys/proc.h>
34#include <sys/condvar.h>
35#include <sys/interrupt.h>
36#include <sys/unistd.h>
37
38#include <sys/queue.h>
39
40#define	MLX5E_RL_MAX_WORKERS		128	/* limited by Toeplitz hash */
41#define	MLX5E_RL_MAX_TX_RATES		(64 * 1024)	/* software limit */
42#define	MLX5E_RL_DEF_SQ_PER_WORKER	(12 * 1024)	/* software limit */
43#define	MLX5E_RL_MAX_SQS		(120 * 1024)	/* software limit */
44
45#define	MLX5E_RL_TX_COAL_USEC_DEFAULT	32
46#define	MLX5E_RL_TX_COAL_PKTS_DEFAULT	4
47#define	MLX5E_RL_TX_COAL_MODE_DEFAULT	0
48#define	MLX5E_RL_TX_COMP_FACT_DEFAULT	1
49
50#define	MLX5E_RL_WORKER_LOCK(rlw)		mtx_lock(&(rlw)->mtx)
51#define	MLX5E_RL_WORKER_UNLOCK(rlw)		mtx_unlock(&(rlw)->mtx)
52
53#define	MLX5E_RL_RLOCK(rl) sx_slock(&(rl)->rl_sxlock)
54#define	MLX5E_RL_RUNLOCK(rl) sx_sunlock(&(rl)->rl_sxlock)
55
56#define	MLX5E_RL_WLOCK(rl) sx_xlock(&(rl)->rl_sxlock)
57#define	MLX5E_RL_WUNLOCK(rl) sx_xunlock(&(rl)->rl_sxlock)
58
59#define	MLX5E_RL_PARAMS(m) \
60  m(+1, u64, tx_queue_size, "tx_queue_size", "Default send queue size") \
61  m(+1, u64, tx_coalesce_usecs, "tx_coalesce_usecs", "Limit in usec for joining TX packets") \
62  m(+1, u64, tx_coalesce_pkts, "tx_coalesce_pkts", "Maximum number of TX packets to join") \
63  m(+1, u64, tx_coalesce_mode, "tx_coalesce_mode", "0: EQE mode 1: CQE mode") \
64  m(+1, u64, tx_completion_fact, "tx_completion_fact", "1..MAX: Completion event ratio") \
65  m(+1, u64, tx_completion_fact_max, "tx_completion_fact_max", "Maximum completion event ratio") \
66  m(+1, u64, tx_worker_threads_max, "tx_worker_threads_max", "Max number of TX worker threads") \
67  m(+1, u64, tx_worker_threads_def, "tx_worker_threads_def", "Default number of TX worker threads") \
68  m(+1, u64, tx_channels_per_worker_max, "tx_channels_per_worker_max", "Max number of TX channels per worker") \
69  m(+1, u64, tx_channels_per_worker_def, "tx_channels_per_worker_def", "Default number of TX channels per worker") \
70  m(+1, u64, tx_rates_max, "tx_rates_max", "Max number of TX rates") \
71  m(+1, u64, tx_rates_def, "tx_rates_def", "Default number of TX rates") \
72  m(+1, u64, tx_limit_min, "tx_limit_min", "Minimum TX rate in bits/s") \
73  m(+1, u64, tx_limit_max, "tx_limit_max", "Maximum TX rate in bits/s") \
74  m(+1, u64, tx_burst_size, "tx_burst_size", "Current burst size in number of packets. A value of zero means use firmware default.") \
75  m(+1, u64, tx_burst_size_max, "tx_burst_size_max", "Maximum burst size in number of packets") \
76  m(+1, u64, tx_burst_size_min, "tx_burst_size_min", "Minimum burst size in number of packets")
77
78#define	MLX5E_RL_PARAMS_NUM (0 MLX5E_RL_PARAMS(MLX5E_STATS_COUNT))
79
80#define MLX5E_RL_STATS(m) \
81  m(+1, u64, tx_allocate_resource_failure, "tx_allocate_resource_failure", "Number of times firmware resource allocation failed") \
82  m(+1, u64, tx_add_new_rate_failure, "tx_add_new_rate_failure", "Number of times adding a new firmware rate failed") \
83  m(+1, u64, tx_modify_rate_failure, "tx_modify_rate_failure", "Number of times modifying a firmware rate failed") \
84  m(+1, u64, tx_active_connections, "tx_active_connections", "Number of active connections") \
85  m(+1, u64, tx_open_queues, "tx_open_queues", "Number of open TX queues") \
86  m(+1, u64, tx_available_resource_failure, "tx_available_resource_failure", "Number of times TX resources were not available")
87
88#define MLX5E_RL_STATS_NUM (0 MLX5E_RL_STATS(MLX5E_STATS_COUNT))
89
90#define	MLX5E_RL_TABLE_PARAMS(m) \
91  m(+1, u64, tx_limit_add, "tx_limit_add", "Add TX rate limit in bits/s to empty slot") \
92  m(+1, u64, tx_limit_clr, "tx_limit_clr", "Clear all TX rates in table") \
93  m(+1, u64, tx_allowed_deviation, "tx_allowed_deviation", "Relative rate deviation allowed in 1/1000") \
94  m(+1, u64, tx_allowed_deviation_min, "tx_allowed_deviation_min", "Minimum allowed rate deviation in 1/1000") \
95  m(+1, u64, tx_allowed_deviation_max, "tx_allowed_deviation_max", "Maximum allowed rate deviation in 1/1000")
96
97#define	MLX5E_RL_TABLE_PARAMS_NUM (0 MLX5E_RL_TABLE_PARAMS(MLX5E_STATS_COUNT))
98
99#define	MLX5E_RL_PARAMS_INDEX(n)			\
100    (__offsetof(struct mlx5e_rl_params, n) / sizeof(uint64_t))
101
102struct mlx5e_priv;
103
104/* Indicates channel's state */
105enum {
106	MLX5E_RL_ST_FREE,
107	MLX5E_RL_ST_USED,
108	MLX5E_RL_ST_MODIFY,
109	MLX5E_RL_ST_DESTROY,
110};
111
112struct mlx5e_rl_stats {
113	u64	arg [0];
114	MLX5E_RL_STATS(MLX5E_STATS_VAR)
115};
116
117struct mlx5e_rl_params {
118	u64	arg [0];
119	MLX5E_RL_PARAMS(MLX5E_STATS_VAR)
120	u64	table_arg [0];
121	MLX5E_RL_TABLE_PARAMS(MLX5E_STATS_VAR)
122};
123
124struct mlx5e_rl_channel_param {
125	struct mlx5e_sq_param sq;
126	struct mlx5e_cq_param cq;
127};
128
129struct mlx5e_rl_channel {
130	struct m_snd_tag tag;
131	STAILQ_ENTRY(mlx5e_rl_channel) entry;
132	struct mlx5e_sq * volatile sq;
133	struct mlx5e_rl_worker *worker;
134	uint64_t new_rate;
135	uint64_t init_rate;
136	uint64_t last_rate;
137	uint32_t refcount;
138	uint16_t last_burst;
139	uint16_t state;
140};
141
142struct mlx5e_rl_worker {
143	struct mtx mtx;
144	struct cv cv;
145	STAILQ_HEAD(, mlx5e_rl_channel) index_list_head;
146	STAILQ_HEAD(, mlx5e_rl_channel) process_head;
147	struct mlx5e_priv *priv;
148	struct mlx5e_rl_channel *channels;
149	unsigned worker_done;
150};
151
152struct mlx5e_rl_priv_data {
153	struct sx rl_sxlock;
154	struct sysctl_ctx_list ctx;
155	struct mlx5e_rl_channel_param chan_param;
156	struct mlx5e_rl_params param;
157	struct mlx5e_rl_stats stats;
158	struct mlx5e_rl_worker *workers;
159	struct mlx5e_priv *priv;
160	uint64_t *rate_limit_table;
161	unsigned opened;
162	uint32_t tisn;
163};
164
165int mlx5e_rl_init(struct mlx5e_priv *priv);
166void mlx5e_rl_cleanup(struct mlx5e_priv *priv);
167void mlx5e_rl_refresh_sq_inline(struct mlx5e_rl_priv_data *rl);
168
169if_snd_tag_alloc_t mlx5e_rl_snd_tag_alloc;
170
171#endif		/* __MLX5_EN_RL_H__ */
172