delayed until the threshold is reached. A value of zero restores the initial
setting.
-set profiling { tasks | memory } { auto | on | off }
+set profiling memory { on | off }
+set profiling tasks { auto | on | off | lock | no-lock | memory | no-memory }
Enables or disables CPU or memory profiling for the indicated subsystem. This
is equivalent to setting or clearing the "profiling" settings in the "global"
section of the configuration file. Please also see "show profiling". Note
on the linux-glibc target), and requires USE_MEMORY_PROFILING to be set at
compile time.
+. For tasks profiling, it is possible to enable or disable the collection of
+ per-task lock and memory timings at runtime, but the change is only taken
+ into account next time the profiler switches from off/auto to on (either
+ automatically or manually). Thus when using "no-lock" to disable per-task
+ lock profiling and save CPU cycles, it is recommended to flip the task
+ profiling off then on to commit the change.
+
set rate-limit connections global <value>
Change the process-wide connection rate limit, which is set by the global
'maxconnrate' setting. A value of zero disables the limitation. This limit
/* parse a "set profiling" command. It always returns 1. */
static int cli_parse_set_profiling(char **args, char *payload, struct appctx *appctx, void *private)
{
+ int arg;
+
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
return 1;
if (strcmp(args[2], "tasks") != 0)
return cli_err(appctx, "Expects either 'tasks' or 'memory'.\n");
- if (strcmp(args[3], "on") == 0) {
- unsigned int old = profiling;
- int i;
-
- while (!_HA_ATOMIC_CAS(&profiling, &old, (old & ~HA_PROF_TASKS_MASK) | HA_PROF_TASKS_ON))
- ;
-
- HA_ATOMIC_STORE(&prof_task_start_ns, now_ns);
- HA_ATOMIC_STORE(&prof_task_stop_ns, 0);
-
- /* also flush current profiling stats */
- for (i = 0; i < SCHED_ACT_HASH_BUCKETS; i++) {
- HA_ATOMIC_STORE(&sched_activity[i].calls, 0);
- HA_ATOMIC_STORE(&sched_activity[i].cpu_time, 0);
- HA_ATOMIC_STORE(&sched_activity[i].lat_time, 0);
- HA_ATOMIC_STORE(&sched_activity[i].lkw_time, 0);
- HA_ATOMIC_STORE(&sched_activity[i].lkd_time, 0);
- HA_ATOMIC_STORE(&sched_activity[i].mem_time, 0);
- HA_ATOMIC_STORE(&sched_activity[i].func, NULL);
- HA_ATOMIC_STORE(&sched_activity[i].caller, NULL);
+ for (arg = 3; *args[arg]; arg++) {
+ if (strcmp(args[arg], "on") == 0) {
+ unsigned int old = profiling;
+ int i;
+
+ while (!_HA_ATOMIC_CAS(&profiling, &old, (old & ~HA_PROF_TASKS_MASK) | HA_PROF_TASKS_ON))
+ ;
+
+ HA_ATOMIC_STORE(&prof_task_start_ns, now_ns);
+ HA_ATOMIC_STORE(&prof_task_stop_ns, 0);
+
+ /* also flush current profiling stats */
+ for (i = 0; i < SCHED_ACT_HASH_BUCKETS; i++) {
+ HA_ATOMIC_STORE(&sched_activity[i].calls, 0);
+ HA_ATOMIC_STORE(&sched_activity[i].cpu_time, 0);
+ HA_ATOMIC_STORE(&sched_activity[i].lat_time, 0);
+ HA_ATOMIC_STORE(&sched_activity[i].lkw_time, 0);
+ HA_ATOMIC_STORE(&sched_activity[i].lkd_time, 0);
+ HA_ATOMIC_STORE(&sched_activity[i].mem_time, 0);
+ HA_ATOMIC_STORE(&sched_activity[i].func, NULL);
+ HA_ATOMIC_STORE(&sched_activity[i].caller, NULL);
+ }
}
- }
- else if (strcmp(args[3], "auto") == 0) {
- unsigned int old = profiling;
- unsigned int new;
+ else if (strcmp(args[arg], "auto") == 0) {
+ unsigned int old = profiling;
+ unsigned int new;
- do {
- if ((old & HA_PROF_TASKS_MASK) >= HA_PROF_TASKS_AON)
- new = (old & ~HA_PROF_TASKS_MASK) | HA_PROF_TASKS_AON;
- else
- new = (old & ~HA_PROF_TASKS_MASK) | HA_PROF_TASKS_AOFF;
- } while (!_HA_ATOMIC_CAS(&profiling, &old, new));
+ do {
+ if ((old & HA_PROF_TASKS_MASK) >= HA_PROF_TASKS_AON)
+ new = (old & ~HA_PROF_TASKS_MASK) | HA_PROF_TASKS_AON;
+ else
+ new = (old & ~HA_PROF_TASKS_MASK) | HA_PROF_TASKS_AOFF;
+ } while (!_HA_ATOMIC_CAS(&profiling, &old, new));
- HA_ATOMIC_STORE(&prof_task_start_ns, now_ns);
- HA_ATOMIC_STORE(&prof_task_stop_ns, 0);
- }
- else if (strcmp(args[3], "off") == 0) {
- unsigned int old = profiling;
- while (!_HA_ATOMIC_CAS(&profiling, &old, (old & ~HA_PROF_TASKS_MASK) | HA_PROF_TASKS_OFF))
- ;
+ HA_ATOMIC_STORE(&prof_task_start_ns, now_ns);
+ HA_ATOMIC_STORE(&prof_task_stop_ns, 0);
+ }
+ else if (strcmp(args[arg], "off") == 0) {
+ unsigned int old = profiling;
+ while (!_HA_ATOMIC_CAS(&profiling, &old, (old & ~HA_PROF_TASKS_MASK) | HA_PROF_TASKS_OFF))
+ ;
- if (HA_ATOMIC_LOAD(&prof_task_start_ns))
- HA_ATOMIC_STORE(&prof_task_stop_ns, now_ns);
+ if (HA_ATOMIC_LOAD(&prof_task_start_ns))
+ HA_ATOMIC_STORE(&prof_task_stop_ns, now_ns);
+ }
+ else if (strcmp(args[arg], "lock") == 0)
+ HA_ATOMIC_OR(&profiling, HA_PROF_TASKS_LOCK);
+ else if (strcmp(args[arg], "no-lock") == 0)
+ HA_ATOMIC_AND(&profiling, ~HA_PROF_TASKS_LOCK);
+ else if (strcmp(args[arg], "memory") == 0)
+ HA_ATOMIC_OR(&profiling, HA_PROF_TASKS_MEM);
+ else if (strcmp(args[arg], "no-memory") == 0)
+ HA_ATOMIC_AND(&profiling, ~HA_PROF_TASKS_MEM);
+ else
+ break; // unknown arg
}
- else
- return cli_err(appctx, "Expects 'on', 'auto', or 'off'.\n");
+
+ /* either no arg or invalid one */
+ if (arg == 3 || *args[arg])
+ return cli_err(appctx, "Expects a combination of either 'on', 'auto', 'off', 'lock', 'no-lock', 'memory' or 'no-memory'.\n");
return 1;
}