w->thread_id = pthread_self ();
tm->n_vlib_mains = 1;
+ vlib_get_thread_core_numa (w, w->cpu_id);
+
if (tm->sched_policy != ~0)
{
struct sched_param sched_param;
return rv;
}
-static void
-vlib_get_thread_core_socket (vlib_worker_thread_t * w, unsigned cpu_id)
+void
+vlib_get_thread_core_numa (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;
+ int core_id = -1, numa_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);
p =
format (p, "%s%u/topology/physical_package_id%c", sys_cpu_path, cpu_id,
0);
- clib_sysfs_read ((char *) p, "%d", &socket_id);
+ clib_sysfs_read ((char *) p, "%d", &numa_id);
vec_free (p);
w->core_id = core_id;
- w->socket_id = socket_id;
+ w->numa_id = numa_id;
}
static clib_error_t *
{
vlib_thread_main_t *tm = &vlib_thread_main;
void *(*fp_arg) (void *) = fp;
+ void *numa_heap;
w->cpu_id = cpu_id;
- vlib_get_thread_core_socket (w, cpu_id);
+ vlib_get_thread_core_numa (w, cpu_id);
+ os_set_numa_index (w->numa_id);
+
+ /* Set up NUMA-bound heap if indicated */
+ if (clib_per_numa_mheaps[w->numa_id] == 0)
+ {
+ /* If the user requested a NUMA heap, create it... */
+ if (tm->numa_heap_size)
+ {
+ numa_heap = clib_mem_init_thread_safe_numa
+ (0 /* DIY */ , tm->numa_heap_size);
+ clib_per_numa_mheaps[w->numa_id] = numa_heap;
+ }
+ else
+ {
+ /* Or, use the main heap */
+ clib_per_numa_mheaps[w->numa_id] = w->thread_mheap;
+ }
+ }
+
if (tm->cb.vlib_launch_thread_cb && !w->registration->use_pthreads)
return tm->cb.vlib_launch_thread_cb (fp, (void *) w, cpu_id);
else
;
else if (unformat (input, "skip-cores %u", &tm->skip_cores))
;
+ else if (unformat (input, "numa-heap-size %U",
+ unformat_memory_size, &tm->numa_heap_size))
+ ;
else if (unformat (input, "coremask-%s %U", &name,
unformat_bitmap_mask, &bitmap) ||
unformat (input, "corelist-%s %U", &name,
for (i = 1; i < vec_len (vlib_mains); i++)
max_vector_rate =
clib_max (max_vector_rate,
- vlib_last_vectors_per_main_loop_as_f64 (vlib_mains[i]));
+ (f64) vlib_last_vectors_per_main_loop (vlib_mains[i]));
vlib_worker_threads[0].barrier_sync_count++;
unformat_input_t * input, vlib_cli_command_t * cmd)
{
int i;
- f64 now;
+ int verbose = 0;
- now = vlib_time_now (vm);
+ (void) unformat (input, "verbose %=", &verbose, 1);
- vlib_cli_output (vm, "Time now %.9f", now);
+ vlib_cli_output (vm, "%U", format_clib_time, &vm->clib_time, verbose);
if (vec_len (vlib_mains) == 1)
return 0;
{
if (vlib_mains[i] == 0)
continue;
+
+ vlib_cli_output (vm, "%d: %U", i, format_clib_time,
+ &vlib_mains[i]->clib_time, verbose);
+
vlib_cli_output (vm, "Thread %d offset %.9f error %.9f", i,
vlib_mains[i]->time_offset,
vm->time_last_barrier_release -