X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fthreads.c;h=055998adac8cc2ef08521dec4b123d98b14ad544;hb=5d64c7868f67749a6c99eb4ee5998b518ab6c71c;hp=8e75592c0e21938a8f58787c6c15eafbe4711ca2;hpb=e4a9eb7873f140f88be7fffb83e1215fbf181116;p=vpp.git diff --git a/src/vlib/threads.c b/src/vlib/threads.c index 8e75592c0e2..055998adac8 100644 --- a/src/vlib/threads.c +++ b/src/vlib/threads.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -42,11 +43,6 @@ vlib_thread_main_t vlib_thread_main; * imapacts observed timings. */ -#ifdef BARRIER_TRACING - /* - * Output of barrier tracing can be to syslog or elog as suits - */ -#ifdef BARRIER_TRACING_ELOG static u32 elog_id_for_msg_name (const char *msg_name) { @@ -69,24 +65,22 @@ elog_id_for_msg_name (const char *msg_name) return r; } - /* - * elog Barrier trace functions, which are nulled out if BARRIER_TRACING isn't - * defined - */ - static inline void barrier_trace_sync (f64 t_entry, f64 t_open, f64 t_closed) { + if (!vlib_worker_threads->barrier_elog_enabled) + return; + /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = { - .format = "barrier <%d#%s(O:%dus:%dus)(%dus)", - .format_args = "i4T4i4i4i4", + .format = "bar-trace-%s-#%d", + .format_args = "T4i4", }; /* *INDENT-ON* */ struct { - u32 count, caller, t_entry, t_open, t_closed; + u32 caller, count, t_entry, t_open, t_closed; } *ed = 0; ed = ELOG_DATA (&vlib_global_main.elog_main, e); @@ -100,57 +94,64 @@ barrier_trace_sync (f64 t_entry, f64 t_open, f64 t_closed) static inline void barrier_trace_sync_rec (f64 t_entry) { + if (!vlib_worker_threads->barrier_elog_enabled) + return; + /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = { - .format = "barrier <%d(%dus)%s", - .format_args = "i4i4T4", + .format = "bar-syncrec-%s-#%d", + .format_args = "T4i4", }; /* *INDENT-ON* */ struct { - u32 depth, t_entry, caller; + u32 caller, depth; } *ed = 0; ed = ELOG_DATA (&vlib_global_main.elog_main, e); ed->depth = (int) vlib_worker_threads[0].recursion_level - 1; - ed->t_entry = (int) (1000000.0 * t_entry); ed->caller = elog_id_for_msg_name (vlib_worker_threads[0].barrier_caller); } static inline void barrier_trace_release_rec (f64 t_entry) { + if (!vlib_worker_threads->barrier_elog_enabled) + return; + /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = { - .format = "barrier (%dus)%d>", - .format_args = "i4i4", + .format = "bar-relrrec-#%d", + .format_args = "i4", }; /* *INDENT-ON* */ struct { - u32 t_entry, depth; + u32 depth; } *ed = 0; ed = ELOG_DATA (&vlib_global_main.elog_main, e); - ed->t_entry = (int) (1000000.0 * t_entry); ed->depth = (int) vlib_worker_threads[0].recursion_level; } static inline void barrier_trace_release (f64 t_entry, f64 t_closed_total, f64 t_update_main) { + if (!vlib_worker_threads->barrier_elog_enabled) + return; + /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = { - .format = "barrier (%dus){%d}(C:%dus)#%d>", + .format = "bar-rel-#%d-e%d-u%d-t%d", .format_args = "i4i4i4i4", }; /* *INDENT-ON* */ struct { - u32 t_entry, t_update_main, t_closed_total, count; + u32 count, t_entry, t_update_main, t_closed_total; } *ed = 0; ed = ELOG_DATA (&vlib_global_main.elog_main, e); @@ -162,94 +163,6 @@ barrier_trace_release (f64 t_entry, f64 t_closed_total, f64 t_update_main) /* Reset context for next trace */ vlib_worker_threads[0].barrier_context = NULL; } -#else -char barrier_trace[65536]; -char *btp = barrier_trace; - - /* - * syslog Barrier trace functions, which are nulled out if BARRIER_TRACING - * isn't defined - */ - - -static inline void -barrier_trace_sync (f64 t_entry, f64 t_open, f64 t_closed) -{ - btp += sprintf (btp, "<%u#%s", - (unsigned int) vlib_worker_threads[0].barrier_sync_count, - vlib_worker_threads[0].barrier_caller); - - if (vlib_worker_threads[0].barrier_context) - { - btp += sprintf (btp, "[%s]", vlib_worker_threads[0].barrier_context); - - } - - btp += sprintf (btp, "(O:%dus:%dus)(%dus):", - (int) (1000000.0 * t_entry), - (int) (1000000.0 * t_open), (int) (1000000.0 * t_closed)); - -} - -static inline void -barrier_trace_sync_rec (f64 t_entry) -{ - btp += sprintf (btp, "<%u(%dus)%s:", - (int) vlib_worker_threads[0].recursion_level - 1, - (int) (1000000.0 * t_entry), - vlib_worker_threads[0].barrier_caller); -} - -static inline void -barrier_trace_release_rec (f64 t_entry) -{ - btp += sprintf (btp, ":(%dus)%u>", (int) (1000000.0 * t_entry), - (int) vlib_worker_threads[0].recursion_level); -} - -static inline void -barrier_trace_release (f64 t_entry, f64 t_closed_total, f64 t_update_main) -{ - - btp += sprintf (btp, ":(%dus)", (int) (1000000.0 * t_entry)); - if (t_update_main > 0) - { - btp += sprintf (btp, "{%dus}", (int) (1000000.0 * t_update_main)); - } - - btp += sprintf (btp, "(C:%dus)#%u>", - (int) (1000000.0 * t_closed_total), - (int) vlib_worker_threads[0].barrier_sync_count); - - /* Dump buffer to syslog, and reset for next trace */ - fformat (stderr, "BTRC %s\n", barrier_trace); - btp = barrier_trace; - vlib_worker_threads[0].barrier_context = NULL; -} -#endif -#else - - /* Null functions for default case where barrier tracing isn't used */ -static inline void -barrier_trace_sync (f64 t_entry, f64 t_open, f64 t_closed) -{ -} - -static inline void -barrier_trace_sync_rec (f64 t_entry) -{ -} - -static inline void -barrier_trace_release_rec (f64 t_entry) -{ -} - -static inline void -barrier_trace_release (f64 t_entry, f64 t_closed_total, f64 t_update_main) -{ -} -#endif uword os_get_nthreads (void) @@ -393,7 +306,7 @@ 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->lcore_id = tm->main_lcore; + w->cpu_id = tm->main_lcore; w->lwp = syscall (SYS_gettid); w->thread_id = pthread_self (); tm->n_vlib_mains = 1; @@ -688,21 +601,42 @@ vlib_worker_thread_bootstrap_fn (void *arg) return rv; } +static void +vlib_get_thread_core_socket (vlib_worker_thread_t * w, unsigned cpu_id) +{ + const char *sys_cpu_path = "/sys/devices/system/cpu/cpu"; + u8 *p = 0; + int core_id = -1, socket_id = -1; + + p = format (p, "%s%u/topology/core_id%c", sys_cpu_path, cpu_id, 0); + clib_sysfs_read ((char *) p, "%d", &core_id); + vec_reset_length (p); + p = + format (p, "%s%u/topology/physical_package_id%c", sys_cpu_path, cpu_id, + 0); + clib_sysfs_read ((char *) p, "%d", &socket_id); + vec_free (p); + + w->core_id = core_id; + w->socket_id = socket_id; +} + static clib_error_t * -vlib_launch_thread_int (void *fp, vlib_worker_thread_t * w, unsigned lcore_id) +vlib_launch_thread_int (void *fp, vlib_worker_thread_t * w, unsigned cpu_id) { vlib_thread_main_t *tm = &vlib_thread_main; void *(*fp_arg) (void *) = fp; - w->lcore_id = lcore_id; + w->cpu_id = cpu_id; + vlib_get_thread_core_socket (w, cpu_id); if (tm->cb.vlib_launch_thread_cb && !w->registration->use_pthreads) - return tm->cb.vlib_launch_thread_cb (fp, (void *) w, lcore_id); + return tm->cb.vlib_launch_thread_cb (fp, (void *) w, cpu_id); else { pthread_t worker; cpu_set_t cpuset; CPU_ZERO (&cpuset); - CPU_SET (lcore_id, &cpuset); + CPU_SET (cpu_id, &cpuset); if (pthread_create (&worker, NULL /* attr */ , fp_arg, (void *) w)) return clib_error_return_unix (0, "pthread_create"); @@ -1466,9 +1400,21 @@ vlib_worker_thread_barrier_sync_int (vlib_main_t * vm) /* Enforce minimum barrier open time to minimize packet loss */ ASSERT (vm->barrier_no_close_before <= (now + BARRIER_MINIMUM_OPEN_LIMIT)); - while ((now = vlib_time_now (vm)) < vm->barrier_no_close_before) - ; + while (1) + { + now = vlib_time_now (vm); + /* Barrier hold-down timer expired? */ + if (now >= vm->barrier_no_close_before) + break; + if ((vm->barrier_no_close_before - now) + > (2.0 * BARRIER_MINIMUM_OPEN_LIMIT)) + { + clib_warning ("clock change: would have waited for %.4f seconds", + (vm->barrier_no_close_before - now)); + break; + } + } /* Record time of closure */ t_open = now - vm->barrier_epoch; vm->barrier_epoch = now;