From 64f450da8f375e000f139fe1c8f7071dac37af29 Mon Sep 17 00:00:00 2001 From: Mohsin KAZMI Date: Wed, 6 Jul 2016 03:17:50 +0200 Subject: Netmap: Fix Netmap Polling Issue Previously, netmap node switched from interrupt to polling if worker threads are enabled even if there was no netmap interface running. Netmap input node consumed CPU cycles because of input node calls but these cycles were wasted as input node did not have any packet to process. This patch fixes issue stated above using more intelligent way of enabling or disabling polling based on interfaces count. But the pre-requisite condition for polling is, worker thread(s) should be enabled. Change-Id: I3a901823c7b040cce3393958981f439b9f290fe5 Signed-off-by: Mohsin KAZMI --- vnet/vnet/devices/netmap/netmap.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/vnet/vnet/devices/netmap/netmap.c b/vnet/vnet/devices/netmap/netmap.c index 653ebc20..7f1cadd7 100644 --- a/vnet/vnet/devices/netmap/netmap.c +++ b/vnet/vnet/devices/netmap/netmap.c @@ -78,6 +78,29 @@ close_netmap_if(netmap_main_t * nm, netmap_if_t * nif) pool_put(nm->interfaces, nif); } +int +netmap_worker_thread_enable() +{ + /* if worker threads are enabled, switch to polling mode */ + foreach_vlib_main ( + ({ + vlib_node_set_state(this_vlib_main, netmap_input_node.index, VLIB_NODE_STATE_POLLING); + })); + + return 0; +} + +int +netmap_worker_thread_disable() +{ + foreach_vlib_main ( + ({ + vlib_node_set_state(this_vlib_main, netmap_input_node.index, VLIB_NODE_STATE_INTERRUPT); + })); + + return 0; +} + int netmap_create_if(vlib_main_t * vm, u8 * if_name, u8 * hw_addr_set, u8 is_pipe, u8 is_master, u32 *sw_if_index) @@ -202,6 +225,9 @@ netmap_create_if(vlib_main_t * vm, u8 * if_name, u8 * hw_addr_set, if (sw_if_index) *sw_if_index = nif->sw_if_index; + if (tm->n_vlib_mains > 1 && pool_elts(nm->interfaces) == 1) + netmap_worker_thread_enable(); + return 0; error: @@ -216,6 +242,7 @@ netmap_delete_if(vlib_main_t *vm, u8 *host_if_name) netmap_main_t *nm = &netmap_main; netmap_if_t *nif; uword *p; + vlib_thread_main_t * tm = vlib_get_thread_main(); p = mhash_get(&nm->if_index_by_host_if_name, host_if_name); if (p == NULL) { @@ -230,6 +257,10 @@ netmap_delete_if(vlib_main_t *vm, u8 *host_if_name) ethernet_delete_interface(vnm, nif->hw_if_index); close_netmap_if(nm, nif); + + if (tm->n_vlib_mains > 1 && pool_elts(nm->interfaces) == 0) + netmap_worker_thread_disable(); + return 0; } @@ -256,13 +287,6 @@ netmap_init (vlib_main_t * vm) nm->input_cpu_count = tr->count; } - /* if worker threads are enabled, switch to polling mode */ - if (tm->n_vlib_mains > 1) - foreach_vlib_main ( - ({ - vlib_node_set_state(this_vlib_main, netmap_input_node.index, VLIB_NODE_STATE_POLLING); - })); - mhash_init_vec_string (&nm->if_index_by_host_if_name, sizeof (uword)); vec_validate_aligned (nm->rx_buffers, tm->n_vlib_mains - 1, -- cgit 1.2.3-korg