From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9F529A04BC for ; Thu, 8 Oct 2020 07:24:06 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D2AFA1B875; Thu, 8 Oct 2020 07:23:56 +0200 (CEST) Received: from mailout2.w1.samsung.com (mailout2.w1.samsung.com [210.118.77.12]) by dpdk.org (Postfix) with ESMTP id 0EB481B6AB for ; Thu, 8 Oct 2020 07:23:42 +0200 (CEST) Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20201008052340euoutp02e2c7d23565cd56b7eb6d51b41e45b321~77PL-Idql0526205262euoutp02i for ; Thu, 8 Oct 2020 05:23:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20201008052340euoutp02e2c7d23565cd56b7eb6d51b41e45b321~77PL-Idql0526205262euoutp02i DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1602134620; bh=U6IhjXVsEwfcc7sBKu4x/L9REGeac99kbibJmzp3oL8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YRX9tI2tU6AispbGMOVKH+ol93WKcdw/a4mtRsSnYjyC85zAXbt3VKbyH4y1/SpQZ duGfbeEg5h8KNezYllCeigYYT3vKXJ6gafM6y5KHCAaCo9vHoGuxCEE8iepod+M1M0 UYqbOvwIHB6niQMQc9PyjkWRR+tN8ue+ert9DIyQ= Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20201008052340eucas1p10cb8072eb07f2c87267171a191fd9331~77PLwv-wH1098510985eucas1p1Q; Thu, 8 Oct 2020 05:23:40 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id 92.01.05997.C52AE7F5; Thu, 8 Oct 2020 06:23:40 +0100 (BST) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20201008052339eucas1p15697f457b8b96809d04f737e041af08a~77PK626JD1295112951eucas1p1D; Thu, 8 Oct 2020 05:23:39 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20201008052339eusmtrp19605251bfa4ef0c90d79102e8718e681~77PK6Uat32941629416eusmtrp1P; Thu, 8 Oct 2020 05:23:39 +0000 (GMT) X-AuditID: cbfec7f4-677ff7000000176d-68-5f7ea25c12d0 Received: from eusmtip1.samsung.com ( [203.254.199.221]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 8C.F0.06017.B52AE7F5; Thu, 8 Oct 2020 06:23:39 +0100 (BST) Received: from Padamandas.fritz.box (unknown [106.210.88.70]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20201008052338eusmtip1b7ed02f4cfa5cfd0e1e9898bceacdd79~77PKOiL802484324843eusmtip1j; Thu, 8 Oct 2020 05:23:38 +0000 (GMT) From: Lukasz Wojciechowski To: David Hunt , Bruce Richardson Cc: dev@dpdk.org, l.wojciechow@partner.samsung.com, stable@dpdk.org Date: Thu, 8 Oct 2020 07:23:12 +0200 Message-Id: <20201008052323.11547-5-l.wojciechow@partner.samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201008052323.11547-1-l.wojciechow@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrGIsWRmVeSWpSXmKPExsWy7djP87oxi+riDaZPVbW4screom/SRyaL d5+2M1k861nHaPGv4w+7A6vHrwVLWT0W73nJ5HHw3R6mAOYoLpuU1JzMstQifbsEroyDZ/qY CmbnV5w4eoulgXFjRBcjJ4eEgInE7fXr2LsYuTiEBFYwSnT9fcgM4XxhlFi7+C5U5jOjxKFf K1i7GDnAWi59yoaIL2eUWL/vMwuE84lRounkNiaQuWwCthJHZn5lBbFFBMIkmpv3soA0Mws4 Szz5ygYSFhbwljjbd5YZJMwioCrx86sySJhXwFVi7uxWJojr5CVWbzjADGJzCrhJnP1/lxVk lYTAdTaJ/bNmsEMUuUis3/oDyhaWeHV8C5QtI3F6cg8LRMM2Romrv38yQjj7GSWu966AqrKW OPzvNxvEcZoS63fpQ4QdJW7PvckM8TCfxI23giBhZiBz0rbpUGFeiY42IYhqPYmnPVMZYdb+ WfuEBcL2kNh97QA0DK8ySny9tZplAqP8LIRlCxgZVzGKp5YW56anFhvlpZbrFSfmFpfmpesl 5+duYgTG/ul/x7/sYNz1J+kQowAHoxIPr8HR2ngh1sSy4srcQ4wSHMxKIrxOZ0/HCfGmJFZW pRblxxeV5qQWH2KU5mBREuc1XvQyVkggPbEkNTs1tSC1CCbLxMEp1cAo0GIj+jIs971Q3lcn OSWGRY568s9OXotQk4w59D9ZoXXn1P0en/zq13w9VSp0bd8exfKYD91MvV1C3EsExeYVzdkx wTg1fsHzfpuPoc6/jXsml/5/rxLeYCPEp7JFymzpMcWcWFbGy0FnoyvbRF47lD2TDzAxuFR7 IieUWbxtUd7N+zdtXiixFGckGmoxFxUnAgCazUkI+QIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrGLMWRmVeSWpSXmKPExsVy+t/xu7rRi+riDbZvVLO4screom/SRyaL d5+2M1k861nHaPGv4w+7A6vHrwVLWT0W73nJ5HHw3R6mAOYoPZui/NKSVIWM/OISW6VoQwsj PUNLCz0jE0s9Q2PzWCsjUyV9O5uU1JzMstQifbsEvYyDZ/qYCmbnV5w4eoulgXFjRBcjB4eE gInEpU/ZXYxcHEICSxklnh7/xwQRl5H4cEmgi5ETyBSW+HOtiw2i5gOjxJMJl9hBEmwCthJH Zn5lBakXEQiTOLHSHyTMLOAusWXxVGYQW1jAW+Js31lmkBIWAVWJn1+VQcK8Aq4Sc2e3MkGM l5dYveEAWDmngJvE2f93WSFWNTJK3Dw/k20CI98CRoZVjCKppcW56bnFRnrFibnFpXnpesn5 uZsYgWG47djPLTsYu94FH2IU4GBU4uE1OFobL8SaWFZcmXuIUYKDWUmE1+ns6Tgh3pTEyqrU ovz4otKc1OJDjKZAR01klhJNzgfGSF5JvKGpobmFpaG5sbmxmYWSOG+HwMEYIYH0xJLU7NTU gtQimD4mDk6pBkatZNlDvwJ2hZbcaTb5v+bAjv3hHjdY5obMkHpeLprSYJG7+8+1IG1Lt9UO /SsKn81b2sg275Z9Sugf/kXtPRb2zTa9G1kXzLNfEr5nZ6OyUqxn2+fCts/fSpv+crazG+84 OsmrVuOfrrBh+1f/43qlm/81p+x5snLJ2i4e19VFE6wCBecbbVViKc5INNRiLipOBACvKCvM WQIAAA== X-CMS-MailID: 20201008052339eucas1p15697f457b8b96809d04f737e041af08a X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20201008052339eucas1p15697f457b8b96809d04f737e041af08a X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20201008052339eucas1p15697f457b8b96809d04f737e041af08a References: <20200925224209.12173-1-l.wojciechow@partner.samsung.com> <20201008052323.11547-1-l.wojciechow@partner.samsung.com> Subject: [dpdk-stable] [PATCH v5 04/15] distributor: handle worker shutdown in burst mode X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" The burst version of distributor implementation was missing proper handling of worker shutdown. A worker processing packets received from distributor can call rte_distributor_return_pkt() function informing distributor that it want no more packets. Further calls to rte_distributor_request_pkt() or rte_distributor_get_pkt() however should inform distributor that new packets are requested again. Lack of the proper implementation has caused that even after worker informed about returning last packets, new packets were still sent from distributor causing deadlocks as no one could get them on worker side. This patch adds handling shutdown of the worker in following way: 1) It fixes usage of RTE_DISTRIB_VALID_BUF handshake flag. This flag was formerly unused in burst implementation and now it is used for marking valid packets in retptr64 replacing invalid use of RTE_DISTRIB_RETURN_BUF flag. 2) Uses RTE_DISTRIB_RETURN_BUF as a worker to distributor handshake in retptr64 to indicate that worker has shutdown. 3) Worker that shuts down blocks also bufptr for itself with RTE_DISTRIB_RETURN_BUF flag allowing distributor to retrieve any in flight packets. 4) When distributor receives information about shutdown of a worker, it: marks worker as not active; retrieves any in flight and backlog packets and process them to different workers; unlocks bufptr64 by clearing RTE_DISTRIB_RETURN_BUF flag and allowing use in the future if worker requests any new packages. 5) Do not allow to: send or add to backlog any packets for not active workers. Such workers are also ignored if matched. 6) Adjust calls to handle_returns() and tags matching procedure to react for possible activation deactivation of workers. Fixes: 775003ad2f96 ("distributor: add new burst-capable library") Cc: david.hunt@intel.com Cc: stable@dpdk.org Signed-off-by: Lukasz Wojciechowski --- lib/librte_distributor/distributor_private.h | 3 + lib/librte_distributor/rte_distributor.c | 175 +++++++++++++++---- 2 files changed, 146 insertions(+), 32 deletions(-) diff --git a/lib/librte_distributor/distributor_private.h b/lib/librte_distributor/distributor_private.h index 489aef2ac..689fe3e18 100644 --- a/lib/librte_distributor/distributor_private.h +++ b/lib/librte_distributor/distributor_private.h @@ -155,6 +155,9 @@ struct rte_distributor { enum rte_distributor_match_function dist_match_fn; struct rte_distributor_single *d_single; + + uint8_t active[RTE_DISTRIB_MAX_WORKERS]; + uint8_t activesum; }; void diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c index b720abe03..115443fc0 100644 --- a/lib/librte_distributor/rte_distributor.c +++ b/lib/librte_distributor/rte_distributor.c @@ -51,7 +51,7 @@ rte_distributor_request_pkt(struct rte_distributor *d, * Sync with worker on GET_BUF flag. */ while (unlikely(__atomic_load_n(retptr64, __ATOMIC_ACQUIRE) - & RTE_DISTRIB_GET_BUF)) { + & (RTE_DISTRIB_GET_BUF | RTE_DISTRIB_RETURN_BUF))) { rte_pause(); uint64_t t = rte_rdtsc()+100; @@ -67,11 +67,11 @@ rte_distributor_request_pkt(struct rte_distributor *d, for (i = count; i < RTE_DIST_BURST_SIZE; i++) buf->retptr64[i] = 0; - /* Set Return bit for each packet returned */ + /* Set VALID_BUF bit for each packet returned */ for (i = count; i-- > 0; ) buf->retptr64[i] = (((int64_t)(uintptr_t)(oldpkt[i])) << - RTE_DISTRIB_FLAG_BITS) | RTE_DISTRIB_RETURN_BUF; + RTE_DISTRIB_FLAG_BITS) | RTE_DISTRIB_VALID_BUF; /* * Finally, set the GET_BUF to signal to distributor that cache @@ -97,11 +97,13 @@ rte_distributor_poll_pkt(struct rte_distributor *d, return (pkts[0]) ? 1 : 0; } - /* If bit is set, return + /* If any of below bits is set, return. + * GET_BUF is set when distributor hasn't sent any packets yet + * RETURN_BUF is set when distributor must retrieve in-flight packets * Sync with distributor to acquire bufptrs */ if (__atomic_load_n(&(buf->bufptr64[0]), __ATOMIC_ACQUIRE) - & RTE_DISTRIB_GET_BUF) + & (RTE_DISTRIB_GET_BUF | RTE_DISTRIB_RETURN_BUF)) return -1; /* since bufptr64 is signed, this should be an arithmetic shift */ @@ -113,7 +115,7 @@ rte_distributor_poll_pkt(struct rte_distributor *d, } /* - * so now we've got the contents of the cacheline into an array of + * so now we've got the contents of the cacheline into an array of * mbuf pointers, so toggle the bit so scheduler can start working * on the next cacheline while we're working. * Sync with distributor on GET_BUF flag. Release bufptrs. @@ -175,7 +177,7 @@ rte_distributor_return_pkt(struct rte_distributor *d, * Sync with worker on GET_BUF flag. */ while (unlikely(__atomic_load_n(retptr64, __ATOMIC_ACQUIRE) - & RTE_DISTRIB_GET_BUF)) { + & (RTE_DISTRIB_GET_BUF | RTE_DISTRIB_RETURN_BUF))) { rte_pause(); uint64_t t = rte_rdtsc()+100; @@ -187,17 +189,25 @@ rte_distributor_return_pkt(struct rte_distributor *d, __atomic_thread_fence(__ATOMIC_ACQUIRE); for (i = 0; i < RTE_DIST_BURST_SIZE; i++) /* Switch off the return bit first */ - buf->retptr64[i] &= ~RTE_DISTRIB_RETURN_BUF; + buf->retptr64[i] = 0; for (i = num; i-- > 0; ) buf->retptr64[i] = (((int64_t)(uintptr_t)oldpkt[i]) << - RTE_DISTRIB_FLAG_BITS) | RTE_DISTRIB_RETURN_BUF; + RTE_DISTRIB_FLAG_BITS) | RTE_DISTRIB_VALID_BUF; + + /* Use RETURN_BUF on bufptr64 to notify distributor that + * we won't read any mbufs from there even if GET_BUF is set. + * This allows distributor to retrieve in-flight already sent packets. + */ + __atomic_or_fetch(&(buf->bufptr64[0]), RTE_DISTRIB_RETURN_BUF, + __ATOMIC_ACQ_REL); - /* set the GET_BUF but even if we got no returns. - * Sync with distributor on GET_BUF flag. Release retptrs. + /* set the RETURN_BUF on retptr64 even if we got no returns. + * Sync with distributor on RETURN_BUF flag. Release retptrs. + * Notify distributor that we don't request more packets any more. */ __atomic_store_n(&(buf->retptr64[0]), - buf->retptr64[0] | RTE_DISTRIB_GET_BUF, __ATOMIC_RELEASE); + buf->retptr64[0] | RTE_DISTRIB_RETURN_BUF, __ATOMIC_RELEASE); return 0; } @@ -267,6 +277,59 @@ find_match_scalar(struct rte_distributor *d, */ } +/* + * When worker called rte_distributor_return_pkt() + * and passed RTE_DISTRIB_RETURN_BUF handshake through retptr64, + * distributor must retrieve both inflight and backlog packets assigned + * to the worker and reprocess them to another worker. + */ +static void +handle_worker_shutdown(struct rte_distributor *d, unsigned int wkr) +{ + struct rte_distributor_buffer *buf = &(d->bufs[wkr]); + /* double BURST size for storing both inflights and backlog */ + struct rte_mbuf *pkts[RTE_DIST_BURST_SIZE * 2]; + unsigned int pkts_count = 0; + unsigned int i; + + /* If GET_BUF is cleared there are in-flight packets sent + * to worker which does not require new packets. + * They must be retrieved and assigned to another worker. + */ + if (!(__atomic_load_n(&(buf->bufptr64[0]), __ATOMIC_ACQUIRE) + & RTE_DISTRIB_GET_BUF)) + for (i = 0; i < RTE_DIST_BURST_SIZE; i++) + if (buf->bufptr64[i] & RTE_DISTRIB_VALID_BUF) + pkts[pkts_count++] = (void *)((uintptr_t) + (buf->bufptr64[i] + >> RTE_DISTRIB_FLAG_BITS)); + + /* Make following operations on handshake flags on bufptr64: + * - set GET_BUF to indicate that distributor can overwrite buffer + * with new packets if worker will make a new request. + * - clear RETURN_BUF to unlock reads on worker side. + */ + __atomic_store_n(&(buf->bufptr64[0]), RTE_DISTRIB_GET_BUF, + __ATOMIC_RELEASE); + + /* Collect backlog packets from worker */ + for (i = 0; i < d->backlog[wkr].count; i++) + pkts[pkts_count++] = (void *)((uintptr_t) + (d->backlog[wkr].pkts[i] >> RTE_DISTRIB_FLAG_BITS)); + + d->backlog[wkr].count = 0; + + /* Clear both inflight and backlog tags */ + for (i = 0; i < RTE_DIST_BURST_SIZE; i++) { + d->in_flight_tags[wkr][i] = 0; + d->backlog[wkr].tags[i] = 0; + } + + /* Recursive call */ + if (pkts_count > 0) + rte_distributor_process(d, pkts, pkts_count); +} + /* * When the handshake bits indicate that there are packets coming @@ -285,19 +348,33 @@ handle_returns(struct rte_distributor *d, unsigned int wkr) /* Sync on GET_BUF flag. Acquire retptrs. */ if (__atomic_load_n(&(buf->retptr64[0]), __ATOMIC_ACQUIRE) - & RTE_DISTRIB_GET_BUF) { + & (RTE_DISTRIB_GET_BUF | RTE_DISTRIB_RETURN_BUF)) { for (i = 0; i < RTE_DIST_BURST_SIZE; i++) { - if (buf->retptr64[i] & RTE_DISTRIB_RETURN_BUF) { + if (buf->retptr64[i] & RTE_DISTRIB_VALID_BUF) { oldbuf = ((uintptr_t)(buf->retptr64[i] >> RTE_DISTRIB_FLAG_BITS)); /* store returns in a circular buffer */ store_return(oldbuf, d, &ret_start, &ret_count); count++; - buf->retptr64[i] &= ~RTE_DISTRIB_RETURN_BUF; + buf->retptr64[i] &= ~RTE_DISTRIB_VALID_BUF; } } d->returns.start = ret_start; d->returns.count = ret_count; + + /* If worker requested packets with GET_BUF, set it to active + * otherwise (RETURN_BUF), set it to not active. + */ + d->activesum -= d->active[wkr]; + d->active[wkr] = !!(buf->retptr64[0] & RTE_DISTRIB_GET_BUF); + d->activesum += d->active[wkr]; + + /* If worker returned packets without requesting new ones, + * handle all in-flights and backlog packets assigned to it. + */ + if (unlikely(buf->retptr64[0] & RTE_DISTRIB_RETURN_BUF)) + handle_worker_shutdown(d, wkr); + /* Clear for the worker to populate with more returns. * Sync with distributor on GET_BUF flag. Release retptrs. */ @@ -322,11 +399,15 @@ release(struct rte_distributor *d, unsigned int wkr) unsigned int i; handle_returns(d, wkr); + if (unlikely(!d->active[wkr])) + return 0; /* Sync with worker on GET_BUF flag */ while (!(__atomic_load_n(&(d->bufs[wkr].bufptr64[0]), __ATOMIC_ACQUIRE) & RTE_DISTRIB_GET_BUF)) { handle_returns(d, wkr); + if (unlikely(!d->active[wkr])) + return 0; rte_pause(); } @@ -366,7 +447,7 @@ rte_distributor_process(struct rte_distributor *d, int64_t next_value = 0; uint16_t new_tag = 0; uint16_t flows[RTE_DIST_BURST_SIZE] __rte_cache_aligned; - unsigned int i, j, w, wid; + unsigned int i, j, w, wid, matching_required; if (d->alg_type == RTE_DIST_ALG_SINGLE) { /* Call the old API */ @@ -374,11 +455,13 @@ rte_distributor_process(struct rte_distributor *d, mbufs, num_mbufs); } + for (wid = 0 ; wid < d->num_workers; wid++) + handle_returns(d, wid); + if (unlikely(num_mbufs == 0)) { /* Flush out all non-full cache-lines to workers. */ for (wid = 0 ; wid < d->num_workers; wid++) { /* Sync with worker on GET_BUF flag. */ - handle_returns(d, wid); if (__atomic_load_n(&(d->bufs[wid].bufptr64[0]), __ATOMIC_ACQUIRE) & RTE_DISTRIB_GET_BUF) { release(d, wid); @@ -388,6 +471,9 @@ rte_distributor_process(struct rte_distributor *d, return 0; } + if (unlikely(!d->activesum)) + return 0; + while (next_idx < num_mbufs) { uint16_t matches[RTE_DIST_BURST_SIZE]; unsigned int pkts; @@ -412,22 +498,30 @@ rte_distributor_process(struct rte_distributor *d, for (; i < RTE_DIST_BURST_SIZE; i++) flows[i] = 0; - switch (d->dist_match_fn) { - case RTE_DIST_MATCH_VECTOR: - find_match_vec(d, &flows[0], &matches[0]); - break; - default: - find_match_scalar(d, &flows[0], &matches[0]); - } + matching_required = 1; + for (j = 0; j < pkts; j++) { + if (unlikely(!d->activesum)) + return next_idx; + + if (unlikely(matching_required)) { + switch (d->dist_match_fn) { + case RTE_DIST_MATCH_VECTOR: + find_match_vec(d, &flows[0], + &matches[0]); + break; + default: + find_match_scalar(d, &flows[0], + &matches[0]); + } + matching_required = 0; + } /* * Matches array now contain the intended worker ID (+1) of * the incoming packets. Any zeroes need to be assigned * workers. */ - for (j = 0; j < pkts; j++) { - next_mb = mbufs[next_idx++]; next_value = (((int64_t)(uintptr_t)next_mb) << RTE_DISTRIB_FLAG_BITS); @@ -447,12 +541,18 @@ rte_distributor_process(struct rte_distributor *d, */ /* matches[j] = 0; */ - if (matches[j]) { + if (matches[j] && d->active[matches[j]-1]) { struct rte_distributor_backlog *bl = &d->backlog[matches[j]-1]; if (unlikely(bl->count == RTE_DIST_BURST_SIZE)) { release(d, matches[j]-1); + if (!d->active[matches[j]-1]) { + j--; + next_idx--; + matching_required = 1; + continue; + } } /* Add to worker that already has flow */ @@ -462,11 +562,21 @@ rte_distributor_process(struct rte_distributor *d, bl->pkts[idx] = next_value; } else { - struct rte_distributor_backlog *bl = - &d->backlog[wkr]; + struct rte_distributor_backlog *bl; + + while (unlikely(!d->active[wkr])) + wkr = (wkr + 1) % d->num_workers; + bl = &d->backlog[wkr]; + if (unlikely(bl->count == RTE_DIST_BURST_SIZE)) { release(d, wkr); + if (!d->active[wkr]) { + j--; + next_idx--; + matching_required = 1; + continue; + } } /* Add to current worker worker */ @@ -485,9 +595,7 @@ rte_distributor_process(struct rte_distributor *d, matches[w] = wkr+1; } } - wkr++; - if (wkr >= d->num_workers) - wkr = 0; + wkr = (wkr + 1) % d->num_workers; } /* Flush out all non-full cache-lines to workers. */ @@ -663,6 +771,9 @@ rte_distributor_create(const char *name, for (i = 0 ; i < num_workers ; i++) d->backlog[i].tags = &d->in_flight_tags[i][RTE_DIST_BURST_SIZE]; + memset(d->active, 0, sizeof(d->active)); + d->activesum = 0; + dist_burst_list = RTE_TAILQ_CAST(rte_dist_burst_tailq.head, rte_dist_burst_list); -- 2.17.1