summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2018-10-13 12:20:01 -0700
committerMarco Varlese <marco.varlese@suse.de>2018-10-16 10:05:33 +0000
commitaa27eb95b7ee3bb69b62166d5e418e973cbbdcfa (patch)
treebd0bd4a71417ac33c0bf271db5df85081f8d56ff
parent97748cae2e6261d8fdc7c331a4d82828ac51ed81 (diff)
vcl: fix bidirectional tests (VPP-1455)
- add epoll dequeued events beyond maxevents to unhandled - filter multiple epoll rx events Change-Id: I618f5f02b19581473de891b3b59bb6a0faad10b5 Signed-off-by: Florin Coras <fcoras@cisco.com>
-rw-r--r--src/vcl/vcl_private.h1
-rw-r--r--src/vcl/vcl_test.h2
-rw-r--r--src/vcl/vppcom.c27
-rwxr-xr-xsrc/vnet/session/session_api.c48
4 files changed, 41 insertions, 37 deletions
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index 5975f15ac4f..d1a40b933a7 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -153,6 +153,7 @@ typedef struct
/* Socket configuration state */
u8 is_vep;
u8 is_vep_session;
+ u8 has_rx_evt;
u32 attr;
u32 wait_cont_idx;
vppcom_epoll_t vep;
diff --git a/src/vcl/vcl_test.h b/src/vcl/vcl_test.h
index 927110f55d2..9d28b262e3a 100644
--- a/src/vcl/vcl_test.h
+++ b/src/vcl/vcl_test.h
@@ -438,7 +438,7 @@ vcl_test_write (int fd, uint8_t * buf, uint32_t nbytes,
{
if (stats)
stats->tx_eagain++;
- continue;
+ break;
}
else
break;
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index df4ebde72eb..fad2ac98538 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -1293,13 +1293,14 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
is_ct = vcl_session_is_ct (s);
mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
rx_fifo = s->rx_fifo;
+ s->has_rx_evt = 0;
if (svm_fifo_is_empty (rx_fifo))
{
if (is_nonblocking)
{
svm_fifo_unset_event (rx_fifo);
- return VPPCOM_OK;
+ return VPPCOM_EWOULDBLOCK;
}
while (svm_fifo_is_empty (rx_fifo))
{
@@ -1385,13 +1386,14 @@ vppcom_session_read_segments (uint32_t session_handle,
is_ct = vcl_session_is_ct (s);
mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
rx_fifo = s->rx_fifo;
+ s->has_rx_evt = 0;
if (svm_fifo_is_empty (rx_fifo))
{
if (is_nonblocking)
{
svm_fifo_unset_event (rx_fifo);
- return VPPCOM_OK;
+ return VPPCOM_EWOULDBLOCK;
}
while (svm_fifo_is_empty (rx_fifo))
{
@@ -1551,7 +1553,8 @@ vppcom_session_write (uint32_t session_handle, void *buf, size_t n)
{
svm_fifo_set_want_tx_evt (tx_fifo, 1);
svm_msg_q_lock (mq);
- svm_msg_q_wait (mq);
+ if (svm_msg_q_is_empty (mq))
+ svm_msg_q_wait (mq);
svm_msg_q_sub_w_lock (mq, &msg);
e = svm_msg_q_msg_data (mq, &msg);
@@ -2303,11 +2306,12 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
sid = e->fifo->client_session_index;
session = vcl_session_get (wrk, sid);
session_events = session->vep.ev.events;
- if (!(EPOLLIN & session->vep.ev.events))
+ if (!(EPOLLIN & session->vep.ev.events) || session->has_rx_evt)
break;
add_event = 1;
events[*num_ev].events |= EPOLLIN;
session_evt_data = session->vep.ev.data.u64;
+ session->has_rx_evt = 1;
break;
case FIFO_EVENT_APP_TX:
sid = e->fifo->client_session_index;
@@ -2324,11 +2328,12 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0);
sid = session->session_index;
session_events = session->vep.ev.events;
- if (!(EPOLLIN & session->vep.ev.events))
+ if (!(EPOLLIN & session->vep.ev.events) || session->has_rx_evt)
break;
add_event = 1;
events[*num_ev].events |= EPOLLIN;
session_evt_data = session->vep.ev.data.u64;
+ session->has_rx_evt = 1;
break;
case SESSION_IO_EVT_CT_RX:
session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1);
@@ -2452,15 +2457,13 @@ handle_dequeued:
{
msg = vec_elt_at_index (wrk->mq_msg_vector, i);
e = svm_msg_q_msg_data (mq, msg);
- vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
+ if (*num_ev < maxevents)
+ vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
+ else
+ vec_add1 (wrk->unhandled_evts_vector, *e);
svm_msg_q_free_msg (mq, msg);
- if (*num_ev == maxevents)
- {
- i += 1;
- break;
- }
}
- vec_delete (wrk->mq_msg_vector, i, 0);
+ vec_reset_length (wrk->mq_msg_vector);
return *num_ev;
}
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index e82be560b1f..56593865381 100755
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -278,30 +278,6 @@ send_session_accept_callback (stream_session_t * s)
return 0;
}
-void
-mq_send_local_session_disconnected_cb (u32 app_wrk_index,
- local_session_t * ls)
-{
- app_worker_t *app_wrk = app_worker_get (app_wrk_index);
- svm_msg_q_msg_t _msg, *msg = &_msg;
- session_disconnected_msg_t *mp;
- svm_msg_q_t *app_mq;
- session_event_t *evt;
- application_t *app;
-
- app = application_get (app_wrk->app_index);
- app_mq = app_wrk->event_queue;
- svm_msg_q_lock_and_alloc_msg_w_ring (app_mq, SESSION_MQ_CTRL_EVT_RING,
- SVM_Q_WAIT, msg);
- evt = svm_msg_q_msg_data (app_mq, msg);
- memset (evt, 0, sizeof (*evt));
- evt->event_type = SESSION_CTRL_EVT_DISCONNECTED;
- mp = (session_disconnected_msg_t *) evt->data;
- mp->handle = application_local_session_handle (ls);
- mp->context = app->api_client_index;
- svm_msg_q_add_and_unlock (app_mq, msg);
-}
-
static void
send_session_disconnect_callback (stream_session_t * s)
{
@@ -551,6 +527,30 @@ mq_send_session_disconnected_cb (stream_session_t * s)
svm_msg_q_add_and_unlock (app_mq, msg);
}
+void
+mq_send_local_session_disconnected_cb (u32 app_wrk_index,
+ local_session_t * ls)
+{
+ app_worker_t *app_wrk = app_worker_get (app_wrk_index);
+ svm_msg_q_msg_t _msg, *msg = &_msg;
+ session_disconnected_msg_t *mp;
+ svm_msg_q_t *app_mq;
+ session_event_t *evt;
+ application_t *app;
+
+ app = application_get (app_wrk->app_index);
+ app_mq = app_wrk->event_queue;
+ if (mq_try_lock_and_alloc_msg (app_mq, msg))
+ return;
+ evt = svm_msg_q_msg_data (app_mq, msg);
+ memset (evt, 0, sizeof (*evt));
+ evt->event_type = SESSION_CTRL_EVT_DISCONNECTED;
+ mp = (session_disconnected_msg_t *) evt->data;
+ mp->handle = application_local_session_handle (ls);
+ mp->context = app->api_client_index;
+ svm_msg_q_add_and_unlock (app_mq, msg);
+}
+
static void
mq_send_session_reset_cb (stream_session_t * s)
{
highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
# Copyright (c) 2019 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""TCP util library.
"""

from resources.libraries.python.PapiExecutor import PapiSocketExecutor
from resources.libraries.python.Constants import Constants


class TCPUtils(object):
    """Implementation of the TCP utilities.
    """
    www_root_dir = '{rmt_fw_dir}/{wrk_www}'\
        .format(rmt_fw_dir=Constants.REMOTE_FW_DIR,
                wrk_www=Constants.RESOURCES_TP_WRK_WWW)

    def __init__(self):
        pass

    @classmethod
    def start_vpp_http_server_params(cls, node, http_static_plugin,
                                     prealloc_fifos, fifo_size,
                                     private_segment_size):
        """Start the test HTTP server internal application or
           the HTTP static server plugin internal applicatoin on the given node.

        http static server www-root <www-root-dir> prealloc-fifos <N>
        fifo-size <size in kB>
        private-segment-size <seg_size expressed as number + unit, e.g. 100m>
                                -- or --
        test http server static prealloc-fifos <N> fifo-size <size in kB>
        private-segment-size <seg_size expressed as number + unit, e.g. 100m>


        Where N is the max number of connections you expect to handle at one
        time and <size> should be small if you test for CPS and exchange few
        bytes, say 4, if each connection just exchanges few packets. Or it
        should be much larger, up to 1024/4096 (i.e. 1-4MB) if you have only
        one connection and exchange a lot of packets, i.e., when you test for
        RPS. If you need to allocate lots of FIFOs, so you test for CPS, make
        private-segment-size something like 4g.

        Example:

        For CPS
        http static server www-root <www-root-dir> prealloc-fifos 10000
        fifo-size 64 private-segment-size 4000m

        For RPS
        test http server static prealloc-fifos 500000 fifo-size 4
        private-segment-size 4000m

        :param node: Node to start HTTP server on.
        :param http_static_plugin: Run HTTP static server plugin
        :param prealloc_fifos: Max number of connections you expect to handle at
            one time.
        :param fifo_size: FIFO size in kB.
        :param private_segment_size: Private segment size. Number + unit.
        :type node: dict
        :type http_static_plugin: boolean
        :type prealloc_fifos: str
        :type fifo_size: str
        :type private_segment_size: str
        """
        if http_static_plugin == True:
            cmd='http static server www-root {www_root} '\
                'prealloc-fifos {prealloc_fifos} fifo-size {fifo_size}'\
                ' private-segment-size {pvt_seg_size}'\
                .format(www_root=cls.www_root_dir,
                        prealloc_fifos=prealloc_fifos, fifo_size=fifo_size,
                        pvt_seg_size=private_segment_size)
        else:
            cmd='test http server static prealloc-fifos {prealloc_fifos} '\
                'fifo-size {fifo_size} private-segment-size {pvt_seg_size}'\
                .format(prealloc_fifos=prealloc_fifos, fifo_size=fifo_size,
                        pvt_seg_size=private_segment_size)
        PapiSocketExecutor.run_cli_cmd(node, cmd)