void clib_smp_init (void) { clib_smp_main_t * m = &clib_smp_main; uword cpu; m->vm_base = clib_mem_vm_alloc ((uword) (m->n_cpus + 1) << m->log2_n_per_cpu_vm_bytes); if (! m->vm_base) clib_error ("error allocating virtual memory"); for (cpu = 0; cpu < m->n_cpus; cpu++) clib_calljmp (allocate_per_cpu_mheap, cpu, clib_smp_stack_top_for_cpu (m, cpu)); }
static int nsim_configure (nsim_main_t * nsm, f64 bandwidth, f64 delay, f64 packet_size, f64 drop_fraction) { u64 total_buffer_size_in_bytes, per_worker_buffer_size; u64 wheel_slots_per_worker; int i; int num_workers = vlib_num_workers (); u32 pagesize = getpagesize (); vlib_main_t *vm = nsm->vlib_main; if (bandwidth == 0.0) return VNET_API_ERROR_INVALID_VALUE; if (delay == 0.0) return VNET_API_ERROR_INVALID_VALUE_2; if (packet_size < 64.0 || packet_size > 9000.0) return VNET_API_ERROR_INVALID_VALUE_3; /* Toss the old wheel(s)... */ if (nsm->is_configured) { for (i = 0; i < vec_len (nsm->wheel_by_thread); i++) { nsim_wheel_t *wp = nsm->wheel_by_thread[i]; munmap (wp, nsm->mmap_size); nsm->wheel_by_thread[i] = 0; } } nsm->delay = delay; nsm->drop_fraction = drop_fraction; /* delay in seconds, bandwidth in bits/sec */ total_buffer_size_in_bytes = (u32) ((delay * bandwidth) / 8.0) + 0.5; /* * Work out how much buffering each worker needs, assuming decent * RSS behavior. */ if (num_workers) per_worker_buffer_size = total_buffer_size_in_bytes / num_workers; else per_worker_buffer_size = total_buffer_size_in_bytes; wheel_slots_per_worker = per_worker_buffer_size / packet_size; wheel_slots_per_worker++; /* Save these for the show command */ nsm->bandwidth = bandwidth; nsm->packet_size = packet_size; vec_validate (nsm->wheel_by_thread, num_workers); /* Initialize the output scheduler wheels */ for (i = num_workers ? 1 : 0; i < num_workers + 1; i++) { nsim_wheel_t *wp; nsm->mmap_size = sizeof (nsim_wheel_t) + wheel_slots_per_worker * sizeof (nsim_wheel_entry_t); nsm->mmap_size += pagesize - 1; nsm->mmap_size &= ~(pagesize - 1); wp = clib_mem_vm_alloc (nsm->mmap_size); ASSERT (wp != 0); wp->wheel_size = wheel_slots_per_worker; wp->cursize = 0; wp->head = 0; wp->tail = 0; wp->entries = (void *) (wp + 1); nsm->wheel_by_thread[i] = wp; } vlib_worker_thread_barrier_sync (vm); /* turn on the ring scrapers */ for (i = num_workers ? 1 : 0; i < num_workers + 1; i++) { vlib_main_t *this_vm = vlib_mains[i]; vlib_node_set_state (this_vm, nsim_input_node.index, VLIB_NODE_STATE_POLLING); } vlib_worker_thread_barrier_release (vm); nsm->is_configured = 1; return 0; }