28 #include <rte_config.h> 29 #include <rte_common.h> 31 #include <rte_launch.h> 32 #include <rte_lcore.h> 36 #define FRAME_QUEUE_NELTS 32 44 unsigned __thread __attribute__((weak)) RTE_PER_LCORE(_lcore_id);
45 struct lcore_config __attribute__((weak)) lcore_config[];
46 unsigned __attribute__((weak)) rte_socket_id();
47 int __attribute__((weak)) rte_eal_remote_launch();
87 int pthread_setname_np (pthread_t __target_thread,
const char *__name);
88 pthread_t thread = pthread_self();
91 pthread_setname_np(thread, name);
99 return ((
i32)((*tr0)->no_data_structure_clone)
100 - ((
i32)((*tr1)->no_data_structure_clone)));
109 fp = fopen (filename,
"r");
115 if (fgets ((
char *)buffer, 256, fp))
137 u32 n_vlib_mains = 1;
186 pthread_setaffinity_np(pthread_self(),
sizeof(cpu_set_t), &cpuset);
200 w->
lwp = syscall(SYS_gettid);
220 first_index += tr->
count;
231 if (clib_bitmap_get(avail_cpu, c) == 0)
232 return clib_error_return (0,
"cpu %u is not available to be used" 233 " for the '%s' thread",c, tr->name);
235 avail_cpu = clib_bitmap_set(avail_cpu, c, 0);
241 for (j=0; j < tr->
count; j++)
246 " the '%s' thread", tr->
name);
288 memset (fq, 0,
sizeof (*fq));
296 fformat(stderr,
"WARNING: fq->tail unaligned\n");
298 fformat(stderr,
"WARNING: fq->head unaligned\n");
300 fformat(stderr,
"WARNING: fq->elts unaligned\n");
303 fformat(stderr,
"WARNING: fq->elts[0] size %d\n",
304 sizeof (fq->
elts[0]));
305 if (nelts & (nelts -1))
307 fformat (stderr,
"FATAL: nelts MUST be a power of 2\n");
329 u32 node_runtime_index;
349 node_runtime_index = elt->node_runtime_index;
354 case VLIB_FRAME_QUEUE_ELT_FREE_BUFFERS:
357 case VLIB_FRAME_QUEUE_ELT_FREE_FRAME:
370 case VLIB_FRAME_QUEUE_ELT_API_MSG:
374 clib_warning (
"bogus frame queue message, type %d", msg_type);
407 new_tail = __sync_add_and_fetch (&fq->
tail, 1);
418 elt = fq->
elts + (new_tail & (fq->
nelts-1));
429 elt->node_runtime_index = node_runtime_index;
447 pthread_sigmask (SIG_SETMASK, &s, 0);
479 w->
lwp = syscall(SYS_gettid);
485 unsigned lcore = rte_lcore_id();
486 lcore = lcore < RTE_MAX_LCORE ? lcore : -1;
501 void *(*fp_arg)(
void *) = fp;
505 if (rte_eal_remote_launch)
506 return rte_eal_remote_launch (fp, (
void *)w, lcore_id);
516 CPU_SET(lcore_id, &cpuset);
518 ret = pthread_create (&worker,
NULL , fp_arg, (
void *)w);
520 return pthread_setaffinity_np(worker,
sizeof(cpu_set_t), &cpuset);
537 u32 worker_thread_index;
558 unsigned lcore = rte_lcore_id();
574 if (n_vlib_mains > 1)
594 worker_thread_index = 1;
609 for (k = 0; k < tr->
count; k++)
646 vm_clone->
cpu_index = worker_thread_index;
658 u32 save_node_runtime_index;
665 nf->
flags = save_flags;
721 ASSERT (fl_orig - orig_freelist_pool
724 fl_clone[0] = fl_orig[0];
730 worker_thread_index++;
741 for (j = 0; j < tr->
count; j++)
761 worker_thread_index = 1;
771 for (j = 0; j < tr->
count; j++)
782 w = vlib_worker_threads + worker_thread_index++;
783 if (vlib_launch_thread (vlib_worker_thread_bootstrap_fn, w, c) < 0)
784 clib_warning (
"Couldn't start DPDK lcore %d", c);
844 n = nm_clone->
nodes[j];
876 u32 save_node_runtime_index;
883 nf->
flags = save_flags;
886 old_nodes_clone = nm_clone->
nodes;
894 new_n = nm->
nodes[j];
895 old_n_clone = old_nodes_clone[j];
902 if (j >= vec_len (old_nodes_clone))
926 for (j = 0; j <
vec_len(old_nodes_clone); j++)
946 for (j=0; j <
vec_len(old_rt); j++)
986 if (
unformat (input,
"main-thread-io"))
988 else if (
unformat (input,
"use-pthreads"))
996 else if (
unformat (input,
"coremask-%s %llx", &name, &coremask))
1028 else if (
unformat (input,
"%s %u", &name, &count))
1037 (0,
"number of %s threads not configurable", tr->
name);
1062 #if !defined (__x86_64__) && !defined (__aarch64__) && !defined (__powerpc64__) && !defined(__arm__) 1063 void __sync_fetch_and_add_8 (
void)
1065 fformat(stderr,
"%s called\n", __FUNCTION__);
1068 void __sync_add_and_fetch_8 (
void)
1070 fformat(stderr,
"%s called\n", __FUNCTION__);
1125 fformat(stderr,
"%s: worker thread deadlock\n", __FUNCTION__);
1149 fformat(stderr,
"%s: worker thread deadlock\n", __FUNCTION__);
1164 "ID",
"Name",
"Type",
"LWP",
1165 "lcore",
"Core",
"Socket",
"State");
1167 #if !defined(__powerpc64__) 1173 line =
format(line,
"%-7d%-20s%-12s%-8d",
1183 line =
format(line,
"%-7u%-7u%-7u",
1185 lcore_config[lcore].core_id,
1186 lcore_config[lcore].socket_id);
1188 switch(lcore_config[lcore].
state)
1191 line =
format(line,
"wait");
1194 line =
format(line,
"running");
1197 line =
format(line,
"finished");
1200 line =
format(line,
"unknown");
1214 .path =
"show threads",
1215 .short_help =
"Show threads",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
#define VLIB_THREAD_STACK_SIZE
void * vlib_worker_thread_bootstrap_fn(void *arg)
always_inline vlib_thread_main_t * vlib_get_thread_main()
sll srl srl sll sra u16x4 i
vlib_process_t ** processes
always_inline uword clib_bitmap_count_set_bits(uword *ai)
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define VLIB_MAIN_LOOP_ENTER_FUNCTION(x)
word elog_track_register(elog_main_t *em, elog_track_t *t)
static void vlib_worker_thread_barrier_check(void)
#define VLIB_LOG2_THREAD_STACK_SIZE
always_inline void clib_mem_free(void *p)
void * mheap_alloc(void *memory, uword size)
static int sort_registrations_by_no_clone(void *a0, void *a1)
#define vec_add2_aligned(V, P, N, A)
Add N elements to end of vector V, return pointer to new elements in P.
void * thread_function_arg
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define VLIB_FRAME_NO_FREE_AFTER_DISPATCH
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
vlib_buffer_main_t * buffer_main
#define hash_set_mem(h, key, value)
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
struct vlib_thread_registration_ * next
#define MHEAP_FLAG_THREAD_SAFE
int vlib_frame_queue_enqueue(vlib_main_t *vm, u32 node_runtime_index, u32 frame_queue_index, vlib_frame_t *frame, vlib_frame_queue_msg_type_t type)
always_inline vlib_main_t * vlib_get_main(void)
#define clib_bitmap_dup(v)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
uword os_get_cpu_number(void)
u64 * counters_last_clear
#define VLIB_EFD_DEF_WORKER_HI_THRESH_PCT
vlib_thread_registration_t * next
vlib_node_stats_t stats_last_clear
#define clib_smp_atomic_add(addr, increment)
#define pool_foreach(VAR, POOL, BODY)
always_inline void * clib_mem_get_per_cpu_heap(void)
static int vlib_launch_thread(void *fp, vlib_worker_thread_t *w, unsigned lcore_id)
#define FRAME_QUEUE_NELTS
never_inline void vlib_node_runtime_sync_stats(vlib_main_t *vm, vlib_node_runtime_t *r, uword n_calls, uword n_vectors, uword n_clocks)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
always_inline uword clib_bitmap_first_set(uword *ai)
#define clib_warning(format, args...)
vlib_frame_queue_elt_t * elts
vlib_node_runtime_t * nodes_by_type[VLIB_N_NODE_TYPE]
always_inline mheap_t * mheap_header(u8 *v)
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
#define hash_create_string(elts, value_bytes)
always_inline void vlib_next_frame_init(vlib_next_frame_t *nf)
always_inline void * clib_mem_alloc_aligned(uword size, uword align)
#define clib_bitmap_foreach(i, ai, body)
vlib_node_stats_t stats_total
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
#define BARRIER_SYNC_TIMEOUT
vlib_error_main_t error_main
void vlib_frame_free(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_frame_t *f)
#define vec_dup(V)
Return copy of vector (no header, no alignment)
vlib_frame_queue_t * vlib_frame_queue_alloc(int nelts)
#define VLIB_FRAME_PENDING
always_inline void * clib_mem_set_heap(void *heap)
always_inline uword * clib_bitmap_set(uword *ai, uword i, uword value)
vlib_frame_queue_t ** vlib_frame_queues
u32 main_thread_is_io_node
void vlib_worker_thread_fork_fixup(vlib_fork_fixup_t which)
#define VLIB_FRAME_FREE_AFTER_DISPATCH
always_inline void * clib_mem_get_heap(void)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static clib_error_t * show_threads_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
void debug_hex_bytes(u8 *s, u32 n)
void(* thread_function)(void *)
#define pool_get_aligned(P, E, A)
always_inline uword clib_bitmap_get(uword *ai, uword i)
void vlib_worker_thread_node_runtime_update(void)
#define clib_mem_alloc_no_fail(size)
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
always_inline void * clib_mem_alloc(uword size)
vlib_pending_frame_t * pending_frames
vlib_thread_function_t * function
#define vec_free(V)
Free vector's memory (no header).
#define clib_memcpy(a, b, c)
void vnet_main_fixup(vlib_fork_fixup_t which)
always_inline u32 vlib_frame_index(vlib_main_t *vm, vlib_frame_t *f)
volatile u32 * wait_at_barrier
#define VLIB_CLI_COMMAND(x,...)
always_inline f64 vlib_time_now_ticks(vlib_main_t *vm, u64 n)
vlib_worker_thread_t * vlib_worker_threads
always_inline uword * clib_bitmap_set_multiple(uword *bitmap, uword i, uword value, uword n_bits)
void vlib_worker_thread_barrier_sync(vlib_main_t *vm)
vhost_vring_state_t state
#define clib_bitmap_free(v)
uword * thread_registrations_by_name
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
static clib_error_t * start_workers(vlib_main_t *vm)
clib_error_t * vlib_thread_init(vlib_main_t *vm)
vlib_worker_thread_t * vlib_alloc_thread(vlib_main_t *vm)
vlib_frame_queue_msg_type_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define VLIB_PENDING_FRAME_NO_NEXT_FRAME
#define VLIB_EFD_DISABLED
vlib_node_main_t node_main
static uword unformat_bitmap_list(unformat_input_t *input, va_list *va)
vlib_buffer_free_list_t * buffer_free_list_pool
vlib_next_frame_t * next_frames
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
int no_data_structure_clone
static uword * vlib_sysfs_list_to_bitmap(char *filename)
vlib_thread_main_t vlib_thread_main
static int vlib_frame_queue_dequeue_internal(vlib_main_t *vm)
vlib_frame_size_t * frame_sizes
void vlib_node_sync_stats(vlib_main_t *vm, vlib_node_t *n)
#define hash_get_mem(h, key)
volatile u32 * workers_at_barrier
uword clib_calljmp(uword(*func)(uword func_arg), uword func_arg, void *stack)
#define VLIB_INVALID_NODE_INDEX
always_inline vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
static clib_error_t * cpu_config(vlib_main_t *vm, unformat_input_t *input)
#define vec_foreach(var, vec)
Vector iterator.
void vlib_worker_thread_init(vlib_worker_thread_t *w)
always_inline f64 vlib_time_now(vlib_main_t *vm)
int vlib_frame_queue_dequeue(int thread_id, vlib_main_t *vm, vlib_node_main_t *nm)
#define CLIB_MEMORY_BARRIER()
void vl_msg_api_handler_no_free(void *)
uword * cpu_socket_bitmap
#define clib_error_return(e, args...)
vlib_thread_registration_t ** registrations
#define CLIB_CACHE_LINE_BYTES
void vlib_set_thread_name(char *name)
always_inline u64 clib_cpu_time_now(void)
vlib_thread_registration_t * registration
clib_random_buffer_t random_buffer
vlib_main_t ** vlib_mains