summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Kotucek <pkotucek@cisco.com>2016-09-23 08:54:14 +0200
committerDamjan Marion <dmarion.lists@gmail.com>2016-09-27 09:04:22 +0000
commit1e7658340ac4cba20defba056c2e13ec0e1a0a69 (patch)
treefa86dc988d6d1c1ac78c9328651074c5f5347227
parent82bf7cddd26b626d3e2d7e3337d52cf2c1b83a22 (diff)
VPP-425: Scheduler policy & priority configuration
Add ability to hadle scheduling policy and priority via config file. CPU section contains new items to specify scheduling policy and priority: cpu { scheduler-priority <num> scheduler-policy [other | batch | idle | fifo | rr ] } Change-Id: Ie20765280e458e1d7deb4a8c66daaa69793f795e Signed-off-by: Pavel Kotucek <pkotucek@cisco.com>
-rw-r--r--vlib/vlib/threads.c53
-rw-r--r--vlib/vlib/threads.h22
-rw-r--r--vlib/vlib/threads_cli.c29
3 files changed, 100 insertions, 4 deletions
diff --git a/vlib/vlib/threads.c b/vlib/vlib/threads.c
index dc9b1bbecd7..67c57a60f41 100644
--- a/vlib/vlib/threads.c
+++ b/vlib/vlib/threads.c
@@ -13,7 +13,6 @@
* limitations under the License.
*/
#define _GNU_SOURCE
-#include <sched.h>
#include <signal.h>
#include <math.h>
@@ -216,6 +215,17 @@ vlib_thread_init (vlib_main_t * vm)
w->lwp = syscall (SYS_gettid);
tm->n_vlib_mains = 1;
+ if (tm->sched_policy != ~0)
+ {
+ struct sched_param sched_param;
+ if (!sched_getparam (w->lwp, &sched_param))
+ {
+ if (tm->sched_priority != ~0)
+ sched_param.sched_priority = tm->sched_priority;
+ sched_setscheduler (w->lwp, tm->sched_policy, &sched_param);
+ }
+ }
+
/* assign threads to cores and set n_vlib_mains */
tr = tm->next;
@@ -995,6 +1005,20 @@ vlib_worker_thread_node_runtime_update (void)
}
}
+u32
+unformat_sched_policy (unformat_input_t * input, va_list * args)
+{
+ u32 *r = va_arg (*args, u32 *);
+
+ if (0);
+#define _(v,f,s) else if (unformat (input, s)) *r = SCHED_POLICY_##f;
+ foreach_sched_policy
+#undef _
+ else
+ return 0;
+ return 1;
+}
+
static clib_error_t *
cpu_config (vlib_main_t * vm, unformat_input_t * input)
{
@@ -1007,7 +1031,10 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input)
u32 count;
tm->thread_registrations_by_name = hash_create_string (0, sizeof (uword));
+
tm->n_thread_stacks = 1; /* account for main thread */
+ tm->sched_policy = ~0;
+ tm->sched_priority = ~0;
tr = tm->next;
@@ -1061,11 +1088,18 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input)
tr->coremask = bitmap;
tr->count = clib_bitmap_count_set_bits (tr->coremask);
}
+ else
+ if (unformat
+ (input, "scheduler-policy %U", unformat_sched_policy,
+ &tm->sched_policy))
+ ;
+ else if (unformat (input, "scheduler-prio %u", &tm->sched_priority))
+ ;
else if (unformat (input, "%s %u", &name, &count))
{
p = hash_get_mem (tm->thread_registrations_by_name, name);
if (p == 0)
- return clib_error_return (0, "no such thread type '%s'", name);
+ return clib_error_return (0, "no such thread type 3 '%s'", name);
tr = (vlib_thread_registration_t *) p[0];
if (tr->fixed_count)
@@ -1077,6 +1111,21 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input)
break;
}
+ if (tm->sched_policy != ~0)
+ {
+ if (tm->sched_priority != ~0
+ && (tm->sched_policy == SCHED_FIFO || tm->sched_policy == SCHED_RR))
+ {
+ u32 prio_max = sched_get_priority_max (tm->sched_policy);
+ u32 prio_min = sched_get_priority_min (tm->sched_policy);
+ if (tm->sched_priority > prio_max)
+ tm->sched_priority = prio_max;
+ if (tm->sched_priority < prio_min)
+ tm->sched_priority = prio_min;
+ }
+ else
+ tm->sched_priority = 0;
+ }
tr = tm->next;
if (!tm->thread_prefix)
diff --git a/vlib/vlib/threads.h b/vlib/vlib/threads.h
index 4283b70a61d..589d1f3a1ec 100644
--- a/vlib/vlib/threads.h
+++ b/vlib/vlib/threads.h
@@ -16,6 +16,7 @@
#define included_vlib_threads_h
#include <vlib/main.h>
+#include <linux/sched.h>
vlib_main_t **vlib_mains;
@@ -257,6 +258,21 @@ typedef struct vlib_efd_t
u8 pad;
} vlib_efd_t;
+#define foreach_sched_policy \
+ _(SCHED_OTHER, OTHER, "other") \
+ _(SCHED_BATCH, BATCH, "batch") \
+ _(SCHED_IDLE, IDLE, "idle") \
+ _(SCHED_FIFO, FIFO, "fifo") \
+ _(SCHED_RR, RR, "rr")
+
+typedef enum
+{
+#define _(v,f,s) SCHED_POLICY_##f = v,
+ foreach_sched_policy
+#undef _
+ SCHED_POLICY_N,
+} sched_policy_t;
+
typedef struct
{
/* Link list of registrations, built by constructors */
@@ -314,6 +330,12 @@ typedef struct
/* worker thread initialization barrier */
volatile u32 worker_thread_release;
+ /* scheduling policy */
+ u32 sched_policy;
+
+ /* scheduling policy priority */
+ u32 sched_priority;
+
} vlib_thread_main_t;
vlib_thread_main_t vlib_thread_main;
diff --git a/vlib/vlib/threads_cli.c b/vlib/vlib/threads_cli.c
index 9ab4edcd357..179906ba51b 100644
--- a/vlib/vlib/threads_cli.c
+++ b/vlib/vlib/threads_cli.c
@@ -17,6 +17,23 @@
#include <vlib/vlib.h>
#include <vlib/threads.h>
+#include <linux/sched.h>
+
+u8 *
+format_sched_policy (u8 * s, va_list * args)
+{
+ u32 i = va_arg (*args, u32);
+ u8 *t = 0;
+
+ switch (i)
+ {
+#define _(v,f,str) case SCHED_POLICY_##f: t = (u8 *) str; break;
+ foreach_sched_policy
+#undef _
+ }
+ s = format (s, "%-6s ", t);
+ return s;
+}
static clib_error_t *
show_threads_fn (vlib_main_t * vm,
@@ -25,8 +42,8 @@ show_threads_fn (vlib_main_t * vm,
vlib_worker_thread_t *w;
int i;
- vlib_cli_output (vm, "%-7s%-20s%-12s%-8s%-7s%-7s%-7s%-10s",
- "ID", "Name", "Type", "LWP",
+ vlib_cli_output (vm, "%-7s%-20s%-12s%-8s%-7s%-9s%-7s%-7s%-7s%-10s",
+ "ID", "Name", "Type", "LWP", "Policy", "Priority",
"lcore", "Core", "Socket", "State");
#if !defined(__powerpc64__)
@@ -40,6 +57,14 @@ show_threads_fn (vlib_main_t * vm,
w->name ? w->name : (u8 *) "",
w->registration ? w->registration->name : "", w->lwp);
+ line =
+ format (line, "%U", format_sched_policy, sched_getscheduler (w->lwp));
+
+ struct sched_param sched_param;
+ line = format (line, "%8d ",
+ (!sched_getparam (w->lwp, &sched_param)) ?
+ sched_param.sched_priority : -1);
+
#if DPDK==1
int lcore = w->dpdk_lcore_id;
if (lcore > -1)