DPDK patches and discussions
 help / color / mirror / Atom feed
From: Jerin Jacob <jerinjacobk@gmail.com>
To: Shijith Thotton <sthotton@marvell.com>
Cc: erik.g.carrillo@intel.com, jerinj@marvell.com, dev@dpdk.org,
	 pbhagavatula@marvell.com, stable@dpdk.org
Subject: Re: [PATCH v2] eventdev/timer: fix timeout event wait behavior
Date: Tue, 4 Apr 2023 16:22:04 +0530	[thread overview]
Message-ID: <CALBAE1PsOOQBCtx84gEGgseBdYSmSy9U3J-AtqyP6zAYuWPiMw@mail.gmail.com> (raw)
In-Reply-To: <90fb5b328eda4c7f83cfb11998ba32a01935ff8e.1679375813.git.sthotton@marvell.com>

On Tue, Mar 21, 2023 at 10:51 AM Shijith Thotton <sthotton@marvell.com> wrote:
>
> Improved the accuracy and consistency of timeout event wait behavior by
> refactoring it. Previously, the delay function used for waiting could be
> inaccurate, leading to inconsistent results. This commit updates the
> wait behavior to use a timeout-based approach, enabling the wait for the
> exact number of timer ticks before proceeding.
>
> The new function timeout_event_dequeue mimics the behavior of the tested
> systems closely. It dequeues timer expiry events until either the
> expected number of events have been dequeued or the specified time has
> elapsed. The WAIT_TICKS macro defines the waiting behavior based on the
> type of timer being used (software or hardware).
>
> Fixes: d1f3385d0076 ("test: add event timer adapter auto-test")
>
> Signed-off-by: Shijith Thotton <sthotton@marvell.com>
> ---
> v2:
> - Updated commit message and added fixed tag.


Erik, Could you review this?


>
>  app/test/test_event_timer_adapter.c | 169 +++++++++++-----------------
>  1 file changed, 68 insertions(+), 101 deletions(-)
>
> diff --git a/app/test/test_event_timer_adapter.c b/app/test/test_event_timer_adapter.c
> index 5e7feec1c7..510bebcf86 100644
> --- a/app/test/test_event_timer_adapter.c
> +++ b/app/test/test_event_timer_adapter.c
> @@ -57,9 +57,10 @@ static uint64_t global_bkt_tck_ns;
>  static uint64_t global_info_bkt_tck_ns;
>  static volatile uint8_t arm_done;
>
> -#define CALC_TICKS(tks)                                        \
> -       ceil((double)(tks * global_bkt_tck_ns) / global_info_bkt_tck_ns)
> +#define CALC_TICKS(tks) ceil((double)((tks) * global_bkt_tck_ns) / global_info_bkt_tck_ns)
>
> +/* Wait double timeout ticks for software and an extra tick for hardware */
> +#define WAIT_TICKS(tks) (using_services ? 2 * (tks) : tks + 1)
>
>  static bool using_services;
>  static uint32_t test_lcore1;
> @@ -441,10 +442,31 @@ timdev_teardown(void)
>         rte_mempool_free(eventdev_test_mempool);
>  }
>
> +static inline uint16_t
> +timeout_event_dequeue(struct rte_event *evs, uint64_t nb_evs, uint64_t ticks)
> +{
> +       uint16_t ev_cnt = 0;
> +       uint64_t end_cycle;
> +
> +       if (using_services && nb_evs == MAX_TIMERS)
> +               ticks = 2 * ticks;
> +
> +       end_cycle = rte_rdtsc() + ticks * global_bkt_tck_ns * rte_get_tsc_hz() / 1E9;
> +
> +       while (ev_cnt < nb_evs && rte_rdtsc() < end_cycle) {
> +               ev_cnt += rte_event_dequeue_burst(evdev, TEST_PORT_ID, &evs[ev_cnt], nb_evs, 0);
> +               rte_pause();
> +       }
> +
> +       return ev_cnt;
> +}
> +
>  static inline int
>  test_timer_state(void)
>  {
>         struct rte_event_timer *ev_tim;
> +       const uint64_t max_ticks = 100;
> +       uint64_t ticks, wait_ticks;
>         struct rte_event ev;
>         const struct rte_event_timer tim = {
>                 .ev.op = RTE_EVENT_OP_NEW,
> @@ -455,11 +477,10 @@ test_timer_state(void)
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
>         };
>
> -
>         rte_mempool_get(eventdev_test_mempool, (void **)&ev_tim);
>         *ev_tim = tim;
>         ev_tim->ev.event_ptr = ev_tim;
> -       ev_tim->timeout_ticks = CALC_TICKS(120);
> +       ev_tim->timeout_ticks = CALC_TICKS(max_ticks + 20);
>
>         TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 0,
>                         "Armed timer exceeding max_timeout.");
> @@ -467,8 +488,9 @@ test_timer_state(void)
>                         "Improper timer state set expected %d returned %d",
>                         RTE_EVENT_TIMER_ERROR_TOOLATE, ev_tim->state);
>
> +       ticks = 10;
>         ev_tim->state = RTE_EVENT_TIMER_NOT_ARMED;
> -       ev_tim->timeout_ticks = CALC_TICKS(10);
> +       ev_tim->timeout_ticks = CALC_TICKS(ticks);
>
>         TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 1,
>                         "Failed to arm timer with proper timeout.");
> @@ -477,14 +499,15 @@ test_timer_state(void)
>                         RTE_EVENT_TIMER_ARMED, ev_tim->state);
>
>         if (!using_services)
> -               rte_delay_us(20);
> +               wait_ticks = 2 * ticks;
>         else
> -               rte_delay_us(1000 + 200);
> -       TEST_ASSERT_EQUAL(rte_event_dequeue_burst(evdev, 0, &ev, 1, 0), 1,
> -                       "Armed timer failed to trigger.");
> +               wait_ticks = ticks;
> +
> +       TEST_ASSERT_EQUAL(timeout_event_dequeue(&ev, 1, WAIT_TICKS(wait_ticks)), 1,
> +                         "Armed timer failed to trigger.");
>
>         ev_tim->state = RTE_EVENT_TIMER_NOT_ARMED;
> -       ev_tim->timeout_ticks = CALC_TICKS(90);
> +       ev_tim->timeout_ticks = CALC_TICKS(max_ticks - 10);
>         TEST_ASSERT_EQUAL(rte_event_timer_arm_burst(timdev, &ev_tim, 1), 1,
>                         "Failed to arm timer with proper timeout.");
>         TEST_ASSERT_EQUAL(rte_event_timer_cancel_burst(timdev, &ev_tim, 1),
> @@ -1208,8 +1231,9 @@ stat_inc_reset_ev_enq(void)
>         int ret, i, n;
>         int num_evtims = MAX_TIMERS;
>         struct rte_event_timer *evtims[num_evtims];
> -       struct rte_event evs[BATCH_SIZE];
> +       struct rte_event evs[num_evtims];
>         struct rte_event_timer_adapter_stats stats;
> +       uint64_t ticks = 5;
>         const struct rte_event_timer init_tim = {
>                 .ev.op = RTE_EVENT_OP_NEW,
>                 .ev.queue_id = TEST_QUEUE_ID,
> @@ -1217,7 +1241,7 @@ stat_inc_reset_ev_enq(void)
>                 .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>                 .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
> -               .timeout_ticks = CALC_TICKS(5), // expire in .5 sec
> +               .timeout_ticks = CALC_TICKS(ticks), /**< expire in .5 sec */
>         };
>
>         ret = rte_mempool_get_bulk(eventdev_test_mempool, (void **)evtims,
> @@ -1242,31 +1266,12 @@ stat_inc_reset_ev_enq(void)
>                           "succeeded = %d, rte_errno = %s",
>                           num_evtims, ret, rte_strerror(rte_errno));
>
> -       rte_delay_ms(1000);
> -
> -#define MAX_TRIES num_evtims
> -       int sum = 0;
> -       int tries = 0;
> -       bool done = false;
> -       while (!done) {
> -               sum += rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs,
> -                                              RTE_DIM(evs), 10);
> -               if (sum >= num_evtims || ++tries >= MAX_TRIES)
> -                       done = true;
> -
> -               rte_delay_ms(10);
> -       }
> -
> -       TEST_ASSERT_EQUAL(sum, num_evtims, "Expected %d timer expiry events, "
> -                         "got %d", num_evtims, sum);
> -
> -       TEST_ASSERT(tries < MAX_TRIES, "Exceeded max tries");
> -
> -       rte_delay_ms(100);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(ticks));
> +       TEST_ASSERT_EQUAL(n, num_evtims, "Expected %d timer expiry events, got %d",
> +                         num_evtims, n);
>
>         /* Make sure the eventdev is still empty */
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs),
> -                                     10);
> +       n = timeout_event_dequeue(evs, 1, WAIT_TICKS(1));
>
>         TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected number of timer expiry "
>                           "events from event device");
> @@ -1303,6 +1308,7 @@ event_timer_arm(void)
>         struct rte_event_timer_adapter *adapter = timdev;
>         struct rte_event_timer *evtim = NULL;
>         struct rte_event evs[BATCH_SIZE];
> +       uint64_t ticks = 5;
>         const struct rte_event_timer init_tim = {
>                 .ev.op = RTE_EVENT_OP_NEW,
>                 .ev.queue_id = TEST_QUEUE_ID,
> @@ -1310,7 +1316,7 @@ event_timer_arm(void)
>                 .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>                 .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
> -               .timeout_ticks = CALC_TICKS(5), // expire in .5 sec
> +               .timeout_ticks = CALC_TICKS(ticks), /**< expire in .5 sec */
>         };
>
>         rte_mempool_get(eventdev_test_mempool, (void **)&evtim);
> @@ -1337,10 +1343,7 @@ event_timer_arm(void)
>         TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value "
>                           "after arming already armed timer");
>
> -       /* Let timer expire */
> -       rte_delay_ms(1000);
> -
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(ticks));
>         TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry "
>                           "events from event device");
>
> @@ -1360,6 +1363,7 @@ event_timer_arm_double(void)
>         struct rte_event_timer_adapter *adapter = timdev;
>         struct rte_event_timer *evtim = NULL;
>         struct rte_event evs[BATCH_SIZE];
> +       uint64_t ticks = 5;
>         const struct rte_event_timer init_tim = {
>                 .ev.op = RTE_EVENT_OP_NEW,
>                 .ev.queue_id = TEST_QUEUE_ID,
> @@ -1367,7 +1371,7 @@ event_timer_arm_double(void)
>                 .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>                 .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
> -               .timeout_ticks = CALC_TICKS(5), // expire in .5 sec
> +               .timeout_ticks = CALC_TICKS(ticks), /**< expire in .5 sec */
>         };
>
>         rte_mempool_get(eventdev_test_mempool, (void **)&evtim);
> @@ -1387,10 +1391,7 @@ event_timer_arm_double(void)
>         TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value "
>                           "after double-arm");
>
> -       /* Let timer expire */
> -       rte_delay_ms(600);
> -
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(ticks));
>         TEST_ASSERT_EQUAL(n, 1, "Dequeued incorrect number of expiry events - "
>                           "expected: 1, actual: %d", n);
>
> @@ -1417,6 +1418,7 @@ event_timer_arm_expiry(void)
>                 .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
>         };
> +       uint64_t ticks = 30;
>
>         rte_mempool_get(eventdev_test_mempool, (void **)&evtim);
>         if (evtim == NULL) {
> @@ -1426,7 +1428,7 @@ event_timer_arm_expiry(void)
>
>         /* Set up an event timer */
>         *evtim = init_tim;
> -       evtim->timeout_ticks = CALC_TICKS(30),  // expire in 3 secs
> +       evtim->timeout_ticks = CALC_TICKS(ticks); /**< expire in 3 secs */
>         evtim->ev.event_ptr = evtim;
>
>         ret = rte_event_timer_arm_burst(adapter, &evtim, 1);
> @@ -1435,17 +1437,10 @@ event_timer_arm_expiry(void)
>         TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_ARMED, "Event "
>                           "timer in incorrect state");
>
> -       rte_delay_ms(2999);
> -
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), ticks - 1);
>         TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event");
>
> -       /* Delay 100 ms to account for the adapter tick window - should let us
> -        * dequeue one event
> -        */
> -       rte_delay_ms(100);
> -
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(1));
>         TEST_ASSERT_EQUAL(n, 1, "Dequeued incorrect number (%d) of timer "
>                           "expiry events", n);
>         TEST_ASSERT_EQUAL(evs[0].event_type, RTE_EVENT_TYPE_TIMER,
> @@ -1477,6 +1472,7 @@ event_timer_arm_rearm(void)
>                 .ev.event_type = RTE_EVENT_TYPE_TIMER,
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
>         };
> +       uint64_t ticks = 1;
>
>         rte_mempool_get(eventdev_test_mempool, (void **)&evtim);
>         if (evtim == NULL) {
> @@ -1486,7 +1482,7 @@ event_timer_arm_rearm(void)
>
>         /* Set up a timer */
>         *evtim = init_tim;
> -       evtim->timeout_ticks = CALC_TICKS(1);  // expire in 0.1 sec
> +       evtim->timeout_ticks = CALC_TICKS(ticks); /**< expire in 0.1 sec */
>         evtim->ev.event_ptr = evtim;
>
>         /* Arm it */
> @@ -1494,10 +1490,7 @@ event_timer_arm_rearm(void)
>         TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n",
>                           rte_strerror(rte_errno));
>
> -       /* Add 100ms to account for the adapter tick window */
> -       rte_delay_ms(100 + 100);
> -
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(ticks));
>         TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry "
>                           "events from event device");
>
> @@ -1514,10 +1507,7 @@ event_timer_arm_rearm(void)
>         TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n",
>                           rte_strerror(rte_errno));
>
> -       /* Add 100ms to account for the adapter tick window */
> -       rte_delay_ms(100 + 100);
> -
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(ticks));
>         TEST_ASSERT_EQUAL(n, 1, "Failed to dequeue expected number of expiry "
>                           "events from event device");
>
> @@ -1539,7 +1529,8 @@ event_timer_arm_max(void)
>         int ret, i, n;
>         int num_evtims = MAX_TIMERS;
>         struct rte_event_timer *evtims[num_evtims];
> -       struct rte_event evs[BATCH_SIZE];
> +       struct rte_event evs[num_evtims];
> +       uint64_t ticks = 5;
>         const struct rte_event_timer init_tim = {
>                 .ev.op = RTE_EVENT_OP_NEW,
>                 .ev.queue_id = TEST_QUEUE_ID,
> @@ -1547,7 +1538,7 @@ event_timer_arm_max(void)
>                 .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>                 .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
> -               .timeout_ticks = CALC_TICKS(5), // expire in .5 sec
> +               .timeout_ticks = CALC_TICKS(ticks), /**< expire in .5 sec */
>         };
>
>         ret = rte_mempool_get_bulk(eventdev_test_mempool, (void **)evtims,
> @@ -1567,31 +1558,12 @@ event_timer_arm_max(void)
>                           "succeeded = %d, rte_errno = %s",
>                           num_evtims, ret, rte_strerror(rte_errno));
>
> -       rte_delay_ms(1000);
> -
> -#define MAX_TRIES num_evtims
> -       int sum = 0;
> -       int tries = 0;
> -       bool done = false;
> -       while (!done) {
> -               sum += rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs,
> -                                              RTE_DIM(evs), 10);
> -               if (sum >= num_evtims || ++tries >= MAX_TRIES)
> -                       done = true;
> -
> -               rte_delay_ms(10);
> -       }
> -
> -       TEST_ASSERT_EQUAL(sum, num_evtims, "Expected %d timer expiry events, "
> -                         "got %d", num_evtims, sum);
> -
> -       TEST_ASSERT(tries < MAX_TRIES, "Exceeded max tries");
> -
> -       rte_delay_ms(100);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(ticks));
> +       TEST_ASSERT_EQUAL(n, num_evtims, "Expected %d timer expiry events, got %d",
> +                         num_evtims, n);
>
>         /* Make sure the eventdev is still empty */
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs),
> -                                   10);
> +       n = timeout_event_dequeue(evs, 1, WAIT_TICKS(1));
>
>         TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected number of timer expiry "
>                           "events from event device");
> @@ -1711,6 +1683,7 @@ event_timer_cancel(void)
>                 .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
>         };
> +       uint64_t ticks = 30;
>
>         rte_mempool_get(eventdev_test_mempool, (void **)&evtim);
>         if (evtim == NULL) {
> @@ -1728,7 +1701,7 @@ event_timer_cancel(void)
>         /* Set up a timer */
>         *evtim = init_tim;
>         evtim->ev.event_ptr = evtim;
> -       evtim->timeout_ticks = CALC_TICKS(30);  // expire in 3 sec
> +       evtim->timeout_ticks = CALC_TICKS(ticks); /**< expire in 3 sec */
>
>         /* Check that cancelling an inited but unarmed timer fails */
>         ret = rte_event_timer_cancel_burst(adapter, &evtim, 1);
> @@ -1752,10 +1725,8 @@ event_timer_cancel(void)
>         TEST_ASSERT_EQUAL(evtim->state, RTE_EVENT_TIMER_CANCELED,
>                           "evtim in incorrect state");
>
> -       rte_delay_ms(3000);
> -
>         /* Make sure that no expiry event was generated */
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(ticks));
>         TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event\n");
>
>         rte_mempool_put(eventdev_test_mempool, evtim);
> @@ -1778,8 +1749,8 @@ event_timer_cancel_double(void)
>                 .ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
>                 .ev.event_type =  RTE_EVENT_TYPE_TIMER,
>                 .state = RTE_EVENT_TIMER_NOT_ARMED,
> -               .timeout_ticks = CALC_TICKS(5), // expire in .5 sec
>         };
> +       uint64_t ticks = 30;
>
>         rte_mempool_get(eventdev_test_mempool, (void **)&evtim);
>         if (evtim == NULL) {
> @@ -1790,7 +1761,7 @@ event_timer_cancel_double(void)
>         /* Set up a timer */
>         *evtim = init_tim;
>         evtim->ev.event_ptr = evtim;
> -       evtim->timeout_ticks = CALC_TICKS(30);  // expire in 3 sec
> +       evtim->timeout_ticks = CALC_TICKS(ticks); /**< expire in 3 sec */
>
>         ret = rte_event_timer_arm_burst(adapter, &evtim, 1);
>         TEST_ASSERT_EQUAL(ret, 1, "Failed to arm event timer: %s\n",
> @@ -1812,10 +1783,8 @@ event_timer_cancel_double(void)
>         TEST_ASSERT_EQUAL(rte_errno, EALREADY, "Unexpected rte_errno value "
>                           "after double-cancel: rte_errno = %d", rte_errno);
>
> -       rte_delay_ms(3000);
> -
>         /* Still make sure that no expiry event was generated */
> -       n = rte_event_dequeue_burst(evdev, TEST_PORT_ID, evs, RTE_DIM(evs), 0);
> +       n = timeout_event_dequeue(evs, RTE_DIM(evs), WAIT_TICKS(ticks));
>         TEST_ASSERT_EQUAL(n, 0, "Dequeued unexpected timer expiry event\n");
>
>         rte_mempool_put(eventdev_test_mempool, evtim);
> @@ -1973,9 +1942,7 @@ test_timer_ticks_remaining(void)
>                 rte_delay_ms(100);
>         }
>
> -       rte_delay_ms(100);
> -
> -       TEST_ASSERT_EQUAL(rte_event_dequeue_burst(evdev, 0, &ev, 1, 0), 1,
> +       TEST_ASSERT_EQUAL(timeout_event_dequeue(&ev, 1, WAIT_TICKS(1)), 1,
>                           "Armed timer failed to trigger.");
>         TEST_ASSERT_EQUAL(ev_tim->state, RTE_EVENT_TIMER_NOT_ARMED,
>                           "Improper timer state set expected %d returned %d",
> --
> 2.25.1
>

  reply	other threads:[~2023-04-04 10:52 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-15  8:00 [PATCH v1] eventdev/timer: use loop to check for timeout events Shijith Thotton
2023-03-20 16:54 ` Jerin Jacob
2023-03-21  5:20 ` [PATCH v2] eventdev/timer: fix timeout event wait behavior Shijith Thotton
2023-04-04 10:52   ` Jerin Jacob [this message]
2023-04-12 20:00   ` Carrillo, Erik G
2023-04-21  5:50     ` Jerin Jacob

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CALBAE1PsOOQBCtx84gEGgseBdYSmSy9U3J-AtqyP6zAYuWPiMw@mail.gmail.com \
    --to=jerinjacobk@gmail.com \
    --cc=dev@dpdk.org \
    --cc=erik.g.carrillo@intel.com \
    --cc=jerinj@marvell.com \
    --cc=pbhagavatula@marvell.com \
    --cc=stable@dpdk.org \
    --cc=sthotton@marvell.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).