The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
load.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /**
19  * $Id: cc63fe7a225dee4170919ef0e7ce27efb35c383a $
20  *
21  * @file io/load.h
22  * @brief Load generation
23  *
24  * @copyright 2019 Network RADIUS SAS (legal@networkradius.com)
25  */
26 RCSIDH(load_h, "$Id: cc63fe7a225dee4170919ef0e7ce27efb35c383a $")
27 
28 #include <freeradius-devel/util/event.h>
29 #include <freeradius-devel/util/talloc.h>
30 
31 /** Load generation configuration.
32  *
33  * The load generator runs a callback periodically in order to
34  * generate load. The callback MUST do all of the work, and track
35  * all necessary state itself. The load generator simply provides a
36  * periodic signal.
37  *
38  * The load begins with "start_pps", and ends after ramping up to
39  * "max_pps", no matter how long that takes. The ramp-up is done by
40  * "step" increments. Each step is run for "duration" seconds.
41  *
42  * The callback is run "1/pps" times per second.
43  *
44  * In order to send higher load, it is possible to run the callback
45  * "parallel" times per timeout. i.e. with "start_pps = 100", and
46  * "parallel = 10", the load generator will run the callback 10
47  * times, wait 1/10s, run the callback another 10 times, and so on.
48  *
49  * In order to prevent the load generator from overloading the
50  * backend, we have a configurable maximum backlog. i.e. packets
51  * sent without reply. This backlog is expressed in milliseconds of
52  * packets, *not* in numbers of packets. Expressing the backlog this
53  * way allows it to automatically scale to higher loads.
54  *
55  * i.e. if the generator is senting 10K packets/s, and the
56  * "milliseconds" parameter is 1000, then the generator will allow
57  * 10K packets in the backlog.
58  *
59  * Once the backlog limit is reached, the load generator will switch
60  * to a "gated" method of sending packets. It will only send one new
61  * packet when it has received a reply for one old packet.
62  *
63  * If the generator receives many replies and the backlog is lower
64  * than the limit, the generator switches again to sending the
65  * configured "pps" packets
66  *
67  * The generator will try to increase the packet rate after
68  * "duration" seconds, even if the maximum backlog is currently
69  * reached. This increase has the effect of also increasing the
70  * maximum backlog.
71  */
72 typedef struct {
73  uint32_t start_pps; //!< start PPS
74  uint32_t max_pps; //!< max PPS, 0 for "no limit".
75  fr_time_delta_t duration; //!< duration of each step
76  uint32_t step; //!< how much to increase each load test by
77  uint32_t parallel; //!< how many packets in parallel to send
78  uint32_t milliseconds; //!< how many milliseconds of backlog to top out at
80 
81 typedef struct {
82  fr_time_t start; //! when the test started
83  fr_time_t end; //!< when the test ended, due to last reply received
84  fr_time_t last_send; //!< last packet we sent
85  fr_time_delta_t rtt; //!< smoothed round trip time
86  fr_time_delta_t rttvar; //!< RTT variation
87  int pps; //!< current offered packets/s
88  int pps_accepted; //!< Accepted PPS for the last second
89  int sent; //!< total packets sent
90  int received; //!< total packets received (should be == sent)
91  int skipped; //!< we skipped sending this number of packets
92  int backlog; //!< current backlog
93  int max_backlog; //!< maximum backlog we saw during the test
94  bool blocked; //!< whether or not we're blocked
95  int times[8]; //!< response time in microseconds to tens of seconds
97 
98 typedef struct fr_load_s fr_load_t;
99 
100 /** Whether or not the application should continue.
101  *
102  */
103 typedef enum {
104  FR_LOAD_CONTINUE = 0, //!< continue sending packets.
105  FR_LOAD_DONE //!< the load generator is done
107 
108 
109 typedef int (*fr_load_callback_t)(fr_time_t now, void *uctx);
110 
112  fr_load_callback_t callback, void *uctx) CC_HINT(nonnull(2,3,4));
113 
114 int fr_load_generator_start(fr_load_t *l) CC_HINT(nonnull);
115 
116 int fr_load_generator_stop(fr_load_t *l) CC_HINT(nonnull);
117 
119 
120 size_t fr_load_generator_stats_sprint(fr_load_t *l, fr_time_t now, char *buffer, size_t buflen);
121 
122 fr_load_stats_t const * fr_load_generator_stats(fr_load_t const *l) CC_HINT(nonnull);
static int const char char buffer[256]
Definition: acutest.h:574
#define RCSIDH(h, id)
Definition: build.h:482
fr_dcursor_eval_t void const * uctx
Definition: dcursor.h:546
Stores all information relating to an event list.
Definition: event.c:411
fr_load_callback_t callback
Definition: load.c:69
Definition: load.c:65
int sent
total packets sent
Definition: load.h:89
fr_time_t last_send
last packet we sent
Definition: load.h:84
fr_time_delta_t rtt
smoothed round trip time
Definition: load.h:85
int received
total packets received (should be == sent)
Definition: load.h:90
int(* fr_load_callback_t)(fr_time_t now, void *uctx)
Definition: load.h:109
int skipped
we skipped sending this number of packets
Definition: load.h:91
bool blocked
whether or not we're blocked
Definition: load.h:94
fr_time_t end
when the test started
Definition: load.h:83
int pps_accepted
Accepted PPS for the last second.
Definition: load.h:88
uint32_t start_pps
start PPS
Definition: load.h:73
int pps
current offered packets/s
Definition: load.h:87
int fr_load_generator_start(fr_load_t *l)
Start the load generator.
Definition: load.c:230
fr_load_t * fr_load_generator_create(TALLOC_CTX *ctx, fr_event_list_t *el, fr_load_config_t *config, fr_load_callback_t callback, void *uctx))
Definition: load.c:87
int fr_load_generator_stop(fr_load_t *l)
Stop the load generation through the simple expedient of deleting the timer associated with it.
Definition: load.c:252
fr_load_reply_t
Whether or not the application should continue.
Definition: load.h:103
@ FR_LOAD_DONE
the load generator is done
Definition: load.h:105
@ FR_LOAD_CONTINUE
continue sending packets.
Definition: load.h:104
fr_time_t start
Definition: load.h:82
uint32_t parallel
how many packets in parallel to send
Definition: load.h:77
fr_time_delta_t duration
duration of each step
Definition: load.h:75
int backlog
current backlog
Definition: load.h:92
uint32_t step
how much to increase each load test by
Definition: load.h:76
int max_backlog
maximum backlog we saw during the test
Definition: load.h:93
size_t fr_load_generator_stats_sprint(fr_load_t *l, fr_time_t now, char *buffer, size_t buflen)
Print load generator statistics in CVS format.
Definition: load.c:341
fr_time_delta_t rttvar
RTT variation.
Definition: load.h:86
uint32_t max_pps
max PPS, 0 for "no limit".
Definition: load.h:74
fr_load_reply_t fr_load_generator_have_reply(fr_load_t *l, fr_time_t request_time)
Tell the load generator that we have a reply to a packet we sent.
Definition: load.c:263
uint32_t milliseconds
how many milliseconds of backlog to top out at
Definition: load.h:78
fr_load_stats_t const * fr_load_generator_stats(fr_load_t const *l)
Definition: load.c:387
Load generation configuration.
Definition: load.h:72
unsigned int uint32_t
Definition: merged_model.c:33
static const conf_parser_t config[]
Definition: base.c:183
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
"server local" time.
Definition: time.h:69
static fr_event_list_t * el
int nonnull(2, 5))