- for (i = 0; i < vec_len(tm->registrations); i++)
- {
- vlib_node_main_t *nm, *nm_clone;
- vlib_buffer_main_t *bm_clone;
- vlib_buffer_free_list_t *fl_clone, *fl_orig;
- vlib_buffer_free_list_t *orig_freelist_pool;
- int k;
-
- tr = tm->registrations[i];
-
- if (tr->count == 0)
- continue;
-
- for (k = 0; k < tr->count; k++)
- {
- vec_add2 (vlib_worker_threads, w, 1);
- /*
- * Share the main heap which is now thread-safe.
- *
- * To allocate separate heaps, code:
- * mheap_alloc (0 / * use VM * /, tr->mheap_size);
- */
- w->thread_mheap = heap;
- w->thread_stack = vlib_thread_stacks[w - vlib_worker_threads];
- w->thread_function = tr->function;
- w->thread_function_arg = w;
- w->instance_id = k;
- w->registration = tr;
-
- w->elog_track.name =
- (char *) format (0, "%s %d", tr->name, k+1);
- vec_add1 (w->elog_track.name, 0);
- elog_track_register (&vm->elog_main, &w->elog_track);
-
- if (tr->no_data_structure_clone)
- continue;
-
- /* Allocate "to-worker-N" frame queue */
- fq = vlib_frame_queue_alloc (FRAME_QUEUE_NELTS);
- vec_validate (vlib_frame_queues, worker_thread_index);
- vlib_frame_queues[worker_thread_index] = fq;
-
- /* Fork vlib_global_main et al. Look for bugs here */
- oldheap = clib_mem_set_heap (w->thread_mheap);
-
- vm_clone = clib_mem_alloc (sizeof (*vm_clone));
- memcpy (vm_clone, vlib_mains[0], sizeof (*vm_clone));
-
- vm_clone->cpu_index = worker_thread_index;
- vm_clone->heap_base = w->thread_mheap;
- vm_clone->mbuf_alloc_list = 0;
- memset (&vm_clone->random_buffer, 0, sizeof (vm_clone->random_buffer));
-
- nm = &vlib_mains[0]->node_main;
- nm_clone = &vm_clone->node_main;
- /* fork next frames array, preserving node runtime indices */
- nm_clone->next_frames = vec_dup (nm->next_frames);
- for (j = 0; j < vec_len (nm_clone->next_frames); j++)
- {
- vlib_next_frame_t *nf = &nm_clone->next_frames[j];
- u32 save_node_runtime_index;
- u32 save_flags;
-
- save_node_runtime_index = nf->node_runtime_index;
- save_flags = nf->flags & VLIB_FRAME_NO_FREE_AFTER_DISPATCH;
- vlib_next_frame_init (nf);
- nf->node_runtime_index = save_node_runtime_index;
- nf->flags = save_flags;
- }
-
- /* fork the frame dispatch queue */
- nm_clone->pending_frames = 0;
- vec_validate (nm_clone->pending_frames, 10); /* $$$$$?????? */
- _vec_len (nm_clone->pending_frames) = 0;
-
- /* fork nodes */
- nm_clone->nodes = 0;
- for (j = 0; j < vec_len (nm->nodes); j++)
- {
- vlib_node_t *n;
- n = clib_mem_alloc_no_fail (sizeof(*n));
- memcpy (n, nm->nodes[j], sizeof (*n));
- /* none of the copied nodes have enqueue rights given out */
- n->owner_node_index = VLIB_INVALID_NODE_INDEX;
- memset (&n->stats_total, 0, sizeof (n->stats_total));
- memset (&n->stats_last_clear, 0, sizeof (n->stats_last_clear));
- vec_add1 (nm_clone->nodes, n);
- }
- nm_clone->nodes_by_type[VLIB_NODE_TYPE_INTERNAL] =
- vec_dup (nm->nodes_by_type[VLIB_NODE_TYPE_INTERNAL]);
-
- nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT] =
- vec_dup (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT]);
- vec_foreach(rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT])
- rt->cpu_index = vm_clone->cpu_index;
-
- nm_clone->processes = vec_dup (nm->processes);
-
- /* zap the (per worker) frame freelists, etc */
- nm_clone->frame_sizes = 0;
- nm_clone->frame_size_hash = 0;
-
- /* Packet trace buffers are guaranteed to be empty, nothing to do here */
-
- clib_mem_set_heap (oldheap);
- vec_add1 (vlib_mains, vm_clone);
-
- vm_clone->error_main.counters =
- vec_dup(vlib_mains[0]->error_main.counters);
- vm_clone->error_main.counters_last_clear =
- vec_dup(vlib_mains[0]->error_main.counters_last_clear);
-
- /* Fork the vlib_buffer_main_t free lists, etc. */
- bm_clone = vec_dup (vm_clone->buffer_main);
- vm_clone->buffer_main = bm_clone;
-
- orig_freelist_pool = bm_clone->buffer_free_list_pool;
- bm_clone->buffer_free_list_pool = 0;
-
+ for (i = 0; i < vec_len (tm->registrations); i++)
+ {
+ vlib_node_main_t *nm, *nm_clone;
+ vlib_buffer_main_t *bm_clone;
+ vlib_buffer_free_list_t *fl_clone, *fl_orig;
+ vlib_buffer_free_list_t *orig_freelist_pool;
+ int k;
+
+ tr = tm->registrations[i];
+
+ if (tr->count == 0)
+ continue;
+
+ for (k = 0; k < tr->count; k++)
+ {
+ vec_add2 (vlib_worker_threads, w, 1);
+ if (tr->mheap_size)
+ w->thread_mheap =
+ mheap_alloc (0 /* use VM */ , tr->mheap_size);
+ else
+ w->thread_mheap = main_heap;
+ w->thread_stack = vlib_thread_stacks[w - vlib_worker_threads];
+ w->thread_function = tr->function;
+ w->thread_function_arg = w;
+ w->instance_id = k;
+ w->registration = tr;
+
+ w->elog_track.name =
+ (char *) format (0, "%s %d", tr->name, k + 1);
+ vec_add1 (w->elog_track.name, 0);
+ elog_track_register (&vm->elog_main, &w->elog_track);
+
+ if (tr->no_data_structure_clone)
+ continue;
+
+ /* Allocate "to-worker-N" frame queue */
+ if (tr->frame_queue_nelts)
+ {
+ fq = vlib_frame_queue_alloc (tr->frame_queue_nelts);
+ }
+ else
+ {
+ fq = vlib_frame_queue_alloc (FRAME_QUEUE_NELTS);
+ }
+
+ vec_validate (vlib_frame_queues, worker_thread_index);
+ vlib_frame_queues[worker_thread_index] = fq;
+
+ /* Fork vlib_global_main et al. Look for bugs here */
+ oldheap = clib_mem_set_heap (w->thread_mheap);
+
+ vm_clone = clib_mem_alloc (sizeof (*vm_clone));
+ clib_memcpy (vm_clone, vlib_mains[0], sizeof (*vm_clone));
+
+ vm_clone->cpu_index = worker_thread_index;
+ vm_clone->heap_base = w->thread_mheap;
+ vm_clone->mbuf_alloc_list = 0;
+ memset (&vm_clone->random_buffer, 0,
+ sizeof (vm_clone->random_buffer));
+
+ nm = &vlib_mains[0]->node_main;
+ nm_clone = &vm_clone->node_main;
+ /* fork next frames array, preserving node runtime indices */
+ nm_clone->next_frames = vec_dup (nm->next_frames);
+ for (j = 0; j < vec_len (nm_clone->next_frames); j++)
+ {
+ vlib_next_frame_t *nf = &nm_clone->next_frames[j];
+ u32 save_node_runtime_index;
+ u32 save_flags;
+
+ save_node_runtime_index = nf->node_runtime_index;
+ save_flags = nf->flags & VLIB_FRAME_NO_FREE_AFTER_DISPATCH;
+ vlib_next_frame_init (nf);
+ nf->node_runtime_index = save_node_runtime_index;
+ nf->flags = save_flags;
+ }
+
+ /* fork the frame dispatch queue */
+ nm_clone->pending_frames = 0;
+ vec_validate (nm_clone->pending_frames, 10); /* $$$$$?????? */
+ _vec_len (nm_clone->pending_frames) = 0;
+
+ /* fork nodes */
+ nm_clone->nodes = 0;
+ for (j = 0; j < vec_len (nm->nodes); j++)
+ {
+ vlib_node_t *n;
+ n = clib_mem_alloc_no_fail (sizeof (*n));
+ clib_memcpy (n, nm->nodes[j], sizeof (*n));
+ /* none of the copied nodes have enqueue rights given out */
+ n->owner_node_index = VLIB_INVALID_NODE_INDEX;
+ memset (&n->stats_total, 0, sizeof (n->stats_total));
+ memset (&n->stats_last_clear, 0,
+ sizeof (n->stats_last_clear));
+ vec_add1 (nm_clone->nodes, n);
+ }
+ nm_clone->nodes_by_type[VLIB_NODE_TYPE_INTERNAL] =
+ vec_dup (nm->nodes_by_type[VLIB_NODE_TYPE_INTERNAL]);
+
+ nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT] =
+ vec_dup (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT]);
+ vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT])
+ rt->cpu_index = vm_clone->cpu_index;
+
+ nm_clone->processes = vec_dup (nm->processes);
+
+ /* zap the (per worker) frame freelists, etc */
+ nm_clone->frame_sizes = 0;
+ nm_clone->frame_size_hash = 0;
+
+ /* Packet trace buffers are guaranteed to be empty, nothing to do here */
+
+ clib_mem_set_heap (oldheap);
+ vec_add1 (vlib_mains, vm_clone);
+
+ vm_clone->error_main.counters =
+ vec_dup (vlib_mains[0]->error_main.counters);
+ vm_clone->error_main.counters_last_clear =
+ vec_dup (vlib_mains[0]->error_main.counters_last_clear);
+
+ /* Fork the vlib_buffer_main_t free lists, etc. */
+ bm_clone = vec_dup (vm_clone->buffer_main);
+ vm_clone->buffer_main = bm_clone;
+
+ orig_freelist_pool = bm_clone->buffer_free_list_pool;
+ bm_clone->buffer_free_list_pool = 0;
+
+ /* *INDENT-OFF* */