]>
git.proxmox.com Git - mirror_ovs.git/blob - lib/stress.c
2 * Copyright (c) 2010, 2011 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include "dynamic-string.h"
27 VLOG_DEFINE_THIS_MODULE(stress
);
29 /* The stress options. */
30 #if USE_LINKER_SECTIONS
31 extern struct stress_option
*__start_stress_options
[];
32 extern struct stress_option
*__stop_stress_options
[];
33 #define stress_options __start_stress_options
34 #define n_stress_options (__stop_stress_options - __start_stress_options)
35 #else /* !USE_LINKER_SECTIONS */
37 #define STRESS_OPTION(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT) \
38 STRESS_OPTION__(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT);
42 struct stress_option
*stress_options
[] = {
43 #define STRESS_OPTION(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT) \
48 #define n_stress_options ARRAY_SIZE(stress_options)
49 #endif /* !USE_LINKER_SECTIONS */
51 /* Enable stress options? */
52 static bool stress_enabled
;
55 stress_reset(struct stress_option
*option
)
57 if (!option
->period
|| !stress_enabled
) {
58 option
->counter
= UINT_MAX
;
59 } else if (!option
->random
) {
60 option
->counter
= option
->period
;
61 } else if (option
->period
< UINT32_MAX
/ 2) {
62 /* Random distribution with mean of option->period. */
63 option
->counter
= random_uint32() % ((2 * option
->period
) - 1) + 1;
65 option
->counter
= random_uint32();
70 stress_enable(bool enable
)
72 if (stress_enabled
!= enable
) {
75 stress_enabled
= enable
;
76 for (i
= 0; i
< n_stress_options
; i
++) {
77 stress_reset(stress_options
[i
]);
83 stress_sample_slowpath__(struct stress_option
*option
)
86 if (option
->period
&& stress_enabled
) {
87 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(5, 1);
90 VLOG_DBG_RL(&rl
, "%s hit (%llu total)", option
->name
, option
->hits
);
99 stress_set(struct stress_option
*option
, unsigned int period
, bool random
)
101 if (period
> option
->max
) {
102 period
= option
->max
;
104 if (period
< option
->min
) {
105 period
= option
->min
;
107 if (period
!= option
->period
|| random
!= option
->random
) {
108 option
->random
= random
;
109 option
->period
= period
;
110 stress_reset(option
);
115 stress_unixctl_list(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
116 const char *argv
[] OVS_UNUSED
, void *aux OVS_UNUSED
)
122 ds_put_cstr(&results
, "NAME (DESCRIPTION)\n");
123 ds_put_format(&results
, "%11s %10s %10s %10s\n",
124 "PERIOD", "MODE", "COUNTER", "HITS");
125 ds_put_format(&results
, "%11s %10s %10s %10s\n",
126 "RECOMMENDED", "MINIMUM", "MAXIMUM", "DEFAULT");
127 for (i
= 0; i
< n_stress_options
; i
++) {
128 struct stress_option
*option
= stress_options
[i
];
129 if (!argv
[1] || strstr(option
->name
, argv
[1])) {
130 ds_put_format(&results
, "\n%s (%s)\n",
131 option
->name
, option
->description
);
132 if (option
->period
) {
133 ds_put_format(&results
, "%11u %10s ", option
->period
,
134 option
->random
? "random" : "periodic");
135 if (stress_enabled
) {
136 ds_put_format(&results
, "%10u", option
->counter
);
138 ds_put_cstr(&results
, " n/a");
141 ds_put_format(&results
, "%11s %10s %10s",
142 "disabled", "n/a", "n/a");
144 ds_put_format(&results
, " %10llu\n", option
->hits
);
145 ds_put_format(&results
, "%11u %10u %10u ",
146 option
->recommended
, option
->min
, option
->max
);
148 ds_put_format(&results
, "%10s", "disabled");
150 ds_put_format(&results
, "%10u", option
->def
);
152 ds_put_char(&results
, '\n');
157 unixctl_command_reply(conn
, ds_cstr(&results
));
159 unixctl_command_reply_error(conn
, NULL
);
161 ds_destroy(&results
);
165 stress_unixctl_enable(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
166 const char *argv
[] OVS_UNUSED
, void *aux OVS_UNUSED
)
169 unixctl_command_reply(conn
, NULL
);
173 stress_unixctl_disable(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
174 const char *argv
[] OVS_UNUSED
, void *aux OVS_UNUSED
)
176 stress_enable(false);
177 unixctl_command_reply(conn
, NULL
);
181 stress_unixctl_set(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
182 const char *argv
[], void *aux OVS_UNUSED
)
184 const char *option_name
= argv
[1];
185 const char *option_val
= argv
[2];
188 for (i
= 0; i
< n_stress_options
; i
++) {
189 struct stress_option
*option
= stress_options
[i
];
190 if (!strcmp(option_name
, option
->name
)) {
191 unsigned int period
= strtoul(option_val
, NULL
, 0);
192 bool random
= !strcmp(argv
[3], "random");
194 stress_set(option
, period
, random
);
195 unixctl_command_reply(conn
, NULL
);
200 unixctl_command_reply_error(conn
, NULL
);
203 /* Exposes ovs-appctl access to the stress options.
205 * This function is not required to simply reference stress options and have
206 * them fire at their default periods.
209 stress_init_command(void)
211 unixctl_command_register("stress/list", "", 0, 1,
212 stress_unixctl_list
, NULL
);
213 unixctl_command_register("stress/set", "option period [random | periodic]",
214 2, 3, stress_unixctl_set
, NULL
);
215 unixctl_command_register("stress/enable", "", 0, 0,
216 stress_unixctl_enable
, NULL
);
217 unixctl_command_register("stress/disable", "", 0, 0,
218 stress_unixctl_disable
, NULL
);