X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vlib%2Fvlib%2Fthreads.c;h=70505b072ffa4cdb946b6808cbda4c5c7428fdf2;hb=9876520f9ba746ed4d9923f392911c4f1888a105;hp=7b5b8ff0544e424d187bc0f77257e33131aae1d1;hpb=853e720fdd74b1ffb1168c1503cd97eb5b7f8b60;p=vpp.git diff --git a/vlib/vlib/threads.c b/vlib/vlib/threads.c index 7b5b8ff0544..70505b072ff 100644 --- a/vlib/vlib/threads.c +++ b/vlib/vlib/threads.c @@ -13,7 +13,6 @@ * limitations under the License. */ #define _GNU_SOURCE -#include #include #include @@ -212,10 +211,22 @@ vlib_thread_init (vlib_main_t * vm) w = vlib_worker_threads; w->thread_mheap = clib_mem_get_heap (); w->thread_stack = vlib_thread_stacks[0]; - w->dpdk_lcore_id = -1; + w->lcore_id = tm->main_lcore; w->lwp = syscall (SYS_gettid); + w->thread_id = pthread_self (); 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; @@ -500,15 +511,7 @@ vlib_worker_thread_bootstrap_fn (void *arg) vlib_worker_thread_t *w = arg; w->lwp = syscall (SYS_gettid); - w->dpdk_lcore_id = -1; -#if DPDK==1 - if (w->registration && !w->registration->use_pthreads && rte_socket_id) /* do we really have dpdk linked */ - { - unsigned lcore = rte_lcore_id (); - lcore = lcore < RTE_MAX_LCORE ? lcore : -1; - w->dpdk_lcore_id = lcore; - } -#endif + w->thread_id = pthread_self (); rv = (void *) clib_calljmp ((uword (*)(uword)) w->thread_function, @@ -522,6 +525,7 @@ vlib_launch_thread (void *fp, vlib_worker_thread_t * w, unsigned lcore_id) { void *(*fp_arg) (void *) = fp; + w->lcore_id = lcore_id; #if DPDK==1 if (!w->registration->use_pthreads) if (rte_eal_remote_launch) /* do we have dpdk linked */ @@ -574,15 +578,6 @@ start_workers (vlib_main_t * vm) vlib_set_thread_name ((char *) w->name); } -#if DPDK==1 - w->dpdk_lcore_id = -1; - if (rte_socket_id) /* do we really have dpdk linked */ - { - unsigned lcore = rte_lcore_id (); - w->dpdk_lcore_id = lcore < RTE_MAX_LCORE ? lcore : -1;; - } -#endif - /* * Truth of the matter: we always use at least two * threads. So, make the main heap thread-safe @@ -995,6 +990,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 +1016,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 +1073,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-priority %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 +1096,25 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input) break; } + if (tm->sched_priority != ~0) + { + if (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 + { + return clib_error_return + (0, + "scheduling priority (%d) is not allowed for `normal` scheduling policy", + tm->sched_priority); + } + } tr = tm->next; if (!tm->thread_prefix) @@ -1337,6 +1375,8 @@ vlib_worker_thread_internal (vlib_main_t * vm) vlib_node_main_t *nm = &vm->node_main; u64 cpu_time_now = clib_cpu_time_now (); + vec_alloc (nm->pending_interrupt_node_runtime_indices, 32); + while (1) { vlib_worker_thread_barrier_check (); @@ -1351,6 +1391,28 @@ vlib_worker_thread_internal (vlib_main_t * vm) cpu_time_now); } + /* Next handle interrupts. */ + { + uword l = _vec_len (nm->pending_interrupt_node_runtime_indices); + uword i; + if (l > 0) + { + _vec_len (nm->pending_interrupt_node_runtime_indices) = 0; + for (i = 0; i < l; i++) + { + n = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT], + nm-> + pending_interrupt_node_runtime_indices + [i]); + cpu_time_now = + dispatch_node (vm, n, VLIB_NODE_TYPE_INPUT, + VLIB_NODE_STATE_INTERRUPT, + /* frame */ 0, + cpu_time_now); + } + } + } + if (_vec_len (nm->pending_frames)) { int i;