2 * Copyright (c) 2010 Nicira Networks.
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, const char *args,
116 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 (!*args || strstr(option->name, args)) {
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, 200, ds_cstr(&results));
159 unixctl_command_reply(conn, 404, "");
161 ds_destroy(&results);
165 stress_unixctl_enable(struct unixctl_conn *conn, const char *args OVS_UNUSED,
166 void *aux OVS_UNUSED)
169 unixctl_command_reply(conn, 200, "");
173 stress_unixctl_disable(struct unixctl_conn *conn, const char *args OVS_UNUSED,
174 void *aux OVS_UNUSED)
176 stress_enable(false);
177 unixctl_command_reply(conn, 200, "");
181 stress_unixctl_set(struct unixctl_conn *conn, const char *args_,
182 void *aux OVS_UNUSED)
185 char *args = xstrdup(args_);
186 char *save_ptr = NULL;
190 option_name = strtok_r(args, " ", &save_ptr);
191 option_val = strtok_r(NULL, " ", &save_ptr);
194 for (i = 0; i < n_stress_options; i++) {
195 struct stress_option *option = stress_options[i];
196 if (!strcmp(option_name, option->name)) {
197 unsigned int period = strtoul(option_val, NULL, 0);
198 bool random = strstr(args_, "random");
200 stress_set(option, period, random);
206 unixctl_command_reply(conn, code, "");
210 /* Exposes ovs-appctl access to the stress options.
212 * This function is not required to simply reference stress options and have
213 * them fire at their default periods.
216 stress_init_command(void)
218 unixctl_command_register("stress/list", "", stress_unixctl_list, NULL);
219 unixctl_command_register("stress/set", "option period [random | periodic]",
220 stress_unixctl_set, NULL);
221 unixctl_command_register("stress/enable", "", stress_unixctl_enable, NULL);
222 unixctl_command_register("stress/disable", "",
223 stress_unixctl_disable, NULL);