NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
rp_rtt_template_dev_main.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #include <doca_pcc_dev.h>
27 #include <doca_pcc_dev_event.h>
29 #include "pcc_common_dev.h"
30 #include "rtt_template.h"
31 
32 #define DOCA_PCC_DEV_EVNT_ROCE_ACK_MASK (1 << DOCA_PCC_DEV_EVNT_ROCE_ACK)
33 #define SAMPLER_THREAD_RANK (0)
34 #define COUNTERS_SAMPLE_WINDOW_IN_MICROSEC (10)
35 
43 uint32_t last_sample_ts;
47 uint32_t ports_num = 0;
51 uint32_t counters_started = 0;
52 
53 #ifdef DOCA_PCC_SAMPLE_TX_BYTES
54 /*
55  * Dedicate one thread to sample tx bytes counters on a defined time frame,
56  * calculate current bandwidth and compare with maximum port bandwidth.
57  * This call is enabled by user option to sample TX bytes counter
58  */
59 FORCE_INLINE void thread0_calc_ports_utilization(void)
60 {
61  uint32_t tx_bytes_delta[DOCA_PCC_DEV_MAX_NUM_PORTS], current_bw[DOCA_PCC_DEV_MAX_NUM_PORTS], ts_delta,
62  current_ts;
63 
65  current_ts = doca_pcc_dev_get_timer_lo();
66  ts_delta = diff_with_wrap32(current_ts, last_sample_ts);
67  if (ts_delta >= COUNTERS_SAMPLE_WINDOW_IN_MICROSEC) {
69  for (uint32_t i = 0; i < ports_num; i++) {
70  tx_bytes_delta[i] =
73  current_bw[i] =
74  (doca_pcc_dev_fxp_mult(tx_bytes_delta[i], doca_pcc_dev_fxp_recip(ts_delta)) >>
75  16);
76  g_utilized_bw[i] = (1 << 16);
77  if (current_bw[i] < ports_bw[i])
78  g_utilized_bw[i] = doca_pcc_dev_fxp_mult(current_bw[i],
80  }
81  last_sample_ts = current_ts;
82  }
83  }
84 }
85 
93 FORCE_INLINE uint32_t count_ports(uint32_t ports_mask)
94 {
95  // find maximum port id enabled. Assume enabled ports are continuous
96  return doca_pcc_dev_fls(ports_mask);
97 }
98 
102 FORCE_INLINE void init_counter_ids(void)
103 {
104  for (uint32_t i = 0; i < DOCA_PCC_DEV_MAX_NUM_PORTS; i++)
106 }
107 
108 /*
109  * Initialize TX counters sampling
110  */
111 FORCE_INLINE void tx_counters_sampling_init(uint32_t portid)
112 {
113  /* number of ports to initiate counters for */
115  /* Configure counters to read */
117  /* save port speed in MBps units */
118  ports_bw[portid] = (doca_pcc_dev_mult(doca_pcc_dev_get_port_speed(portid), 1000) >> 3);
119  /* Sample counters and save in global table */
122  /* Save sampled TX bytes */
123  for (uint32_t i = 0; i < ports_num; i++)
125  counters_started = 1;
126 }
127 
128 /*
129  * Called on link or port info state change.
130  * This callback is used to configure port counters to query TX bytes on
131  *
132  * @return - void
133  */
134 void doca_pcc_dev_user_port_info_changed(uint32_t portid)
135 {
136  tx_counters_sampling_init(portid);
137 }
138 #endif
139 
140 /*
141  * Main entry point to user CC algorithm (Reference code)
142  * This function starts the algorithm code of a single event
143  * It receives the flow context data, the event info and outputs the new rate parameters
144  * The function can support multiple algorithms and can call the per algorithm handler based on
145  * the algo type. If a single algorithm is required this code can be simplified
146  * The function can not be renamed as it is called by the handler infrastructure
147  *
148  * @algo_ctxt [in]: A pointer to a flow context data retrieved by libpcc.
149  * @event [in]: A pointer to an event data structure to be passed to extractor functions
150  * @attr [in]: A pointer to additional parameters (algo type).
151  * @results [out]: A pointer to result struct to update rate in HW.
152  */
154  doca_pcc_dev_event_t *event,
155  const doca_pcc_dev_attr_t *attr,
156  doca_pcc_dev_results_t *results)
157 {
158  uint32_t port_num = doca_pcc_dev_get_ev_attr(event).port_num;
159  uint32_t *param = doca_pcc_dev_get_algo_params(port_num, attr->algo_slot);
160  uint32_t *counter = doca_pcc_dev_get_counters(port_num, attr->algo_slot);
161 
162 #ifdef DOCA_PCC_SAMPLE_TX_BYTES
163  thread0_calc_ports_utilization();
164 #endif
165 
166  switch (attr->algo_slot) {
167  case 0: {
168  rtt_template_algo(event, param, counter, algo_ctxt, results);
169  break;
170  }
171  default: {
172  doca_pcc_dev_default_internal_algo(algo_ctxt, event, attr, results);
173  break;
174  }
175  };
176 }
177 
178 /*
179  * Main entry point to user algorithm initialization (reference code)
180  * This function starts the user algorithm initialization code
181  * The function will be called once per process load and should init all supported
182  * algorithms and all ports
183  *
184  * @disable_event_bitmask [out]: user code can tell the infrastructure which event
185  * types to ignore (mask out). Events of this type will be dropped and not passed to
186  * any algo
187  */
188 void doca_pcc_dev_user_init(uint32_t *disable_event_bitmask)
189 {
190  uint32_t algo_idx = 0, algo_slot = 0, algo_en = 1;
191 
192  /* Initialize algorithm with algo_idx=0 */
193  rtt_template_init(algo_idx);
194 
195  for (int port_num = 0; port_num < DOCA_PCC_DEV_MAX_NUM_PORTS; ++port_num) {
196  /* Slot 0 will use algo_idx 0, default enabled */
197  doca_pcc_dev_init_algo_slot(port_num, algo_slot, algo_idx, algo_en);
198  doca_pcc_dev_trace_5(0, port_num, algo_idx, algo_slot, algo_en, DOCA_PCC_DEV_EVNT_ROCE_ACK_MASK);
199  }
200 
201 #ifdef DOCA_PCC_SAMPLE_TX_BYTES
203  init_counter_ids();
204 #endif
205 
206  /* disable events of below type */
207  *disable_event_bitmask = DOCA_PCC_DEV_EVNT_ROCE_ACK_MASK;
209  *disable_event_bitmask |= (1 << DOCA_PCC_DEV_EVNT_ROCE_TX_FOR_ACK_NACK);
210  }
211 
212  doca_pcc_dev_printf("%s, disable_event_bitmask=0x%x\n", __func__, *disable_event_bitmask);
214 }
215 
216 /*
217  * Called when the parameter change was set externally.
218  * The implementation should:
219  * Check the given new_parameters values. If those are correct from the algorithm perspective,
220  * assign them to the given parameter array.
221 
222  * @port_num [in]: index of the port
223  * @algo_slot [in]: Algo slot identifier as referred to in the PPCC command field "algo_slot"
224  * if possible it should be equal to the algo_idx
225  * @param_id_base [in]: id of the first parameter that was changed.
226  * @param_num [in]: number of all parameters that were changed
227  * @new_param_values [in]: pointer to an array which holds param_num number of new values for parameters
228  * @params [in]: pointer to an array which holds beginning of the current parameters to be changed
229  * @return -
230  * DOCA_PCC_DEV_STATUS_OK: Parameters were set
231  * DOCA_PCC_DEV_STATUS_FAIL: the values (one or more) are not legal. No parameters were changed
232  */
234  uint32_t algo_slot,
235  uint32_t param_id_base,
236  uint32_t param_num,
237  const uint32_t *new_param_values,
238  uint32_t *params)
239 {
240  /* Notify the user that a change happened to take action.
241  * I.E.: Pre calculate values to be used in the algo that are based on the parameter value.
242  * Support more complex checks. E.G.: Param is a bit mask - min and max do not help
243  * Param dependency checking.
244  */
246 
247  switch (algo_slot) {
248  case 0: {
249  uint32_t algo_idx = doca_pcc_dev_get_algo_index(port_num, algo_slot);
250 
251  if (algo_idx == 0)
252  ret = rtt_template_set_algo_params(param_id_base, param_num, new_param_values, params);
253  else
255 
256  break;
257  }
258  default:
259  break;
260  }
261  return ret;
262 }
DOCA_STABLE uint32_t * doca_pcc_dev_get_algo_params(uint32_t port_num, uint32_t algo_slot)
Get pointer to param array of a specific algo and specific port.
DOCA_STABLE uint32_t * doca_pcc_dev_get_counters(uint32_t port_num, uint32_t algo_slot)
Get pointer to counter array of a specific algo and specific port.
DOCA_STABLE doca_pcc_dev_error_t doca_pcc_dev_init_algo_slot(uint32_t portid, uint32_t algo_slot, uint32_t algo_idx, uint32_t algo_en)
Initialize the algo per port database.
DOCA_STABLE uint32_t doca_pcc_dev_get_algo_index(uint32_t port_num, uint32_t algo_slot)
Get identifier of a specific algo and specific port.
DOCA_EXPERIMENTAL ALWAYS_INLINE void doca_pcc_dev_nic_counters_sample(void)
Sample counters according to the prior configuration call.
DOCA_EXPERIMENTAL uint32_t doca_pcc_dev_get_port_speed(uint32_t portid)
Get speed in Gbps units per a given port.
DOCA_EXPERIMENTAL void doca_pcc_dev_nic_counters_config(uint32_t *counter_ids, uint32_t num_counters, uint32_t *values)
Prepare a list of counters to read.
#define DOCA_PCC_DEV_GET_PORT_COUNTER_ID(port, type, plane)
Generates a unique ID using the logical port number, counter type, and plane parameters for identifyi...
#define DOCA_PCC_DEV_MAX_NUM_PORTS
Max number of NIC ports supported by the lib.
#define FORCE_INLINE
static inline wrapper
void doca_pcc_dev_user_port_info_changed(uint32_t portid)
User callback triggered on a port state change.
doca_pcc_dev_error_t
API functions return status.
DOCA_EXPERIMENTAL uint32_t doca_pcc_dev_get_logical_ports(void)
Get mask of initiated logical ports.
@ DOCA_PCC_DEV_NIC_COUNTER_TYPE_TX_BYTES
@ DOCA_PCC_DEV_STATUS_OK
@ DOCA_PCC_DEV_STATUS_FAIL
DOCA_STABLE FORCE_INLINE doca_pcc_dev_event_general_attr_t doca_pcc_dev_get_ev_attr(doca_pcc_dev_event_t *event)
For all events, return structure with general information such as event type, subtype,...
DOCA_EXPERIMENTAL unsigned int doca_pcc_dev_thread_rank(void)
Obtains the thread rank.
DOCA_STABLE void doca_pcc_dev_trace_flush(void)
Flush the trace message buffer to Host.
DOCA_STABLE void DOCA_STABLE void doca_pcc_dev_trace_5(int format_id, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
Creates trace message entry with 5 arguments.
DOCA_STABLE void doca_pcc_dev_printf(const char *format,...) __attribute__((format(printf
Print to Host.
#define doca_pcc_dev_mult(a, b)
mult wrapper
#define doca_pcc_dev_fxp_recip(a_fp)
fixed point 16b reciprocal
#define doca_pcc_dev_fxp_mult(a, b)
fixed point 16b mult
#define doca_pcc_dev_fls(a)
32b find last set
DOCA_STABLE FORCE_INLINE uint32_t doca_pcc_dev_get_timer_lo(void)
Core timer access (elapsed time in uSec) function 32 bits.
doca_pcc_dev_error_t doca_pcc_dev_user_set_algo_params(uint32_t port_num, uint32_t algo_slot, uint32_t param_id_base, uint32_t param_num, const uint32_t *new_param_values, uint32_t *params)
User callback executed then parameters are set.
void doca_pcc_dev_user_init(uint32_t *disable_event_bitmask)
Entry point to the user one time initialization code.
DOCA_STABLE void doca_pcc_dev_default_internal_algo(doca_pcc_dev_algo_ctxt_t *algo_ctxt, doca_pcc_dev_event_t *event, const doca_pcc_dev_attr_t *attr, doca_pcc_dev_results_t *results)
Implements the internal CC algorithm provided by the lib.
void doca_pcc_dev_user_algo(doca_pcc_dev_algo_ctxt_t *algo_ctxt, doca_pcc_dev_event_t *event, const doca_pcc_dev_attr_t *attr, doca_pcc_dev_results_t *results)
Entry point to the user algorithm handling code.
#define DOCA_PCC_DEV_ACK_NACK_TX_EVENT_DISABLED_SUPPORTED
Definition: doca_pcc_dev.h:81
@ DOCA_PCC_DEV_EVNT_ROCE_TX_FOR_ACK_NACK
Definition: doca_pcc_dev.h:53
FORCE_INLINE uint32_t count_ports(uint32_t ports_mask)
Count the number of available logical ports from queried mask.
ALWAYS_INLINE uint32_t diff_with_wrap32(uint32_t greater_num, uint32_t smaller_num)
uint32_t previous_sampled_tx_bytes[DOCA_PCC_DEV_MAX_NUM_PORTS]
uint32_t ports_num
uint32_t last_sample_ts
#define COUNTERS_SAMPLE_WINDOW_IN_MICROSEC
uint32_t g_utilized_bw[DOCA_PCC_DEV_MAX_NUM_PORTS]
uint32_t counter_ids[DOCA_PCC_DEV_MAX_NUM_PORTS]
#define DOCA_PCC_DEV_EVNT_ROCE_ACK_MASK
uint32_t counters_started
uint32_t ports_bw[DOCA_PCC_DEV_MAX_NUM_PORTS]
#define SAMPLER_THREAD_RANK
uint32_t current_sampled_tx_bytes[DOCA_PCC_DEV_MAX_NUM_PORTS]
void rtt_template_algo(doca_pcc_dev_event_t *event, uint32_t *param, uint32_t *counter, doca_pcc_dev_algo_ctxt_t *algo_ctxt, doca_pcc_dev_results_t *results)
Definition: rtt_template.c:441
doca_pcc_dev_error_t rtt_template_set_algo_params(uint32_t param_id_base, uint32_t param_num, const uint32_t *new_param_values, uint32_t *params)
Definition: rtt_template.c:474
void rtt_template_init(uint32_t algo_idx)
Definition: rtt_template.c:81
CC algorithm results.
Definition: doca_pcc_dev.h:69