[dpdk-dev] [PATCH v3 0/8] fix distributor synchronization issues

David Marchand david.marchand at redhat.com
Fri Sep 25 14:31:30 CEST 2020


Hello Lukasz,

On Wed, Sep 23, 2020 at 3:25 PM Lukasz Wojciechowski
<l.wojciechow at partner.samsung.com> wrote:
>
> During review and verification of the patch created by Sarosh Arif:
> "test_distributor: prevent memory leakages from the pool" I found out
> that running distributor unit tests multiple times in a row causes fails.
> So I investigated all the issues I found.
>
> There are few synchronization issues that might cause deadlocks
> or corrupted data. They are fixed with this set of patches for both tests
> and librte_distributor library.
>
> ---
> v3:
> * add missing acked and tested by statements from v1
>
> v2:
> * assign NULL to freed mbufs in distributor test
> * fix handshake check on legacy single distributor
>      rte_distributor_return_pkt_single()
> * add patch 7 passing NULL to legacy API calls if no bufs are returned
> * add patch 8 fixing API documentation
>
> Lukasz Wojciechowski (8):
>   app/test: fix deadlock in distributor test
>   app/test: synchronize statistics between lcores
>   app/test: fix freeing mbufs in distributor tests
>   app/test: collect return mbufs in distributor test

For these patches, we can use the "test/distributor: " prefix, and we
then avoid repeating "in distributor test"


>   distributor: fix missing handshake synchronization
>   distributor: fix handshake deadlock
>   distributor: do not use oldpkt when not needed
>   distributor: align API documentation with code

Thanks for working on those fixes !

Here is a suggestion:

- we can move this new patch 7 before patch 3 in the series, and
update the unit test:
 * by passing NULL to the first call to rte_distributor_get_pkt(),
there is no need for buf[] array init in handle_work(),
handle_work_with_free_mbufs() and handle_work_for_shutdown_test(),
 * at all points of those functions the buf[] array then contains only
[0, num[ valid entries,
 * bonus point, this makes the UT check passing NULL oldpkt,

- the former patch 3 is then easier to do since there is no need for
buf[] array clearing,

This gives the following diff, wdyt?

diff --git a/app/test/test_distributor.c b/app/test/test_distributor.c
index f31b54edf3..b7ab93ecbe 100644
--- a/app/test/test_distributor.c
+++ b/app/test/test_distributor.c
@@ -65,13 +65,10 @@ handle_work(void *arg)
        struct rte_mbuf *buf[8] __rte_cache_aligned;
        struct worker_params *wp = arg;
        struct rte_distributor *db = wp->dist;
-       unsigned int count = 0, num = 0;
+       unsigned int count = 0, num;
        unsigned int id = __atomic_fetch_add(&worker_idx, 1, __ATOMIC_RELAXED);
-       int i;

-       for (i = 0; i < 8; i++)
-               buf[i] = NULL;
-       num = rte_distributor_get_pkt(db, id, buf, buf, num);
+       num = rte_distributor_get_pkt(db, id, buf, NULL, 0);
        while (!quit) {
                __atomic_fetch_add(&worker_stats[id].handled_packets, num,
                                __ATOMIC_ACQ_REL);
@@ -277,22 +274,17 @@ handle_work_with_free_mbufs(void *arg)
        struct rte_mbuf *buf[8] __rte_cache_aligned;
        struct worker_params *wp = arg;
        struct rte_distributor *d = wp->dist;
+       unsigned int num;
        unsigned int i;
-       unsigned int num = 0;
        unsigned int id = __atomic_fetch_add(&worker_idx, 1, __ATOMIC_RELAXED);

-       for (i = 0; i < 8; i++)
-               buf[i] = NULL;
-       num = rte_distributor_get_pkt(d, id, buf, buf, 0);
+       num = rte_distributor_get_pkt(d, id, buf, NULL, 0);
        while (!quit) {
                __atomic_fetch_add(&worker_stats[id].handled_packets, num,
                                __ATOMIC_ACQ_REL);
-               for (i = 0; i < num; i++) {
+               for (i = 0; i < num; i++)
                        rte_pktmbuf_free(buf[i]);
-                       buf[i] = NULL;
-               }
-               num = rte_distributor_get_pkt(d,
-                               id, buf, buf, 0);
+               num = rte_distributor_get_pkt(d, id, buf, NULL, 0);
        }
        __atomic_fetch_add(&worker_stats[id].handled_packets, num,
                        __ATOMIC_ACQ_REL);
@@ -347,15 +339,13 @@ handle_work_for_shutdown_test(void *arg)
        struct rte_mbuf *buf[8] __rte_cache_aligned;
        struct worker_params *wp = arg;
        struct rte_distributor *d = wp->dist;
-       unsigned int num = 0;
+       unsigned int num;
        unsigned int i;
        unsigned int zero_id = 0;
        const unsigned int id = __atomic_fetch_add(&worker_idx, 1,
                        __ATOMIC_RELAXED);
-       for (i = 0; i < 8; i++)
-               buf[i] = NULL;

-       num = rte_distributor_get_pkt(d, id, buf, buf, 0);
+       num = rte_distributor_get_pkt(d, id, buf, NULL, 0);

        zero_id = __atomic_load_n(&zero_idx, __ATOMIC_ACQUIRE);
        if (id == zero_id && num > 0) {
@@ -369,12 +359,9 @@ handle_work_for_shutdown_test(void *arg)
        while (!quit && !(id == zero_id && zero_quit)) {
                __atomic_fetch_add(&worker_stats[id].handled_packets, num,
                                __ATOMIC_ACQ_REL);
-               for (i = 0; i < num; i++) {
+               for (i = 0; i < num; i++)
                        rte_pktmbuf_free(buf[i]);
-                       buf[i] = NULL;
-               }
-               num = rte_distributor_get_pkt(d,
-                               id, buf, buf, 0);
+               num = rte_distributor_get_pkt(d, id, buf, NULL, 0);

                zero_id = __atomic_load_n(&zero_idx, __ATOMIC_ACQUIRE);
                if (id == zero_id && num > 0) {
@@ -392,21 +379,16 @@ handle_work_for_shutdown_test(void *arg)
                while (zero_quit)
                        usleep(100);

-               for (i = 0; i < num; i++) {
+               for (i = 0; i < num; i++)
                        rte_pktmbuf_free(buf[i]);
-                       buf[i] = NULL;
-               }
-               num = rte_distributor_get_pkt(d,
-                               id, buf, buf, 0);
+               num = rte_distributor_get_pkt(d, id, buf, NULL, 0);

                while (!quit) {
                        __atomic_fetch_add(&worker_stats[id].handled_packets,
                                        num, __ATOMIC_ACQ_REL);
-                       for (i = 0; i < num; i++) {
+                       for (i = 0; i < num; i++)
                                rte_pktmbuf_free(buf[i]);
-                               buf[i] = NULL;
-                       }
-                       num = rte_distributor_get_pkt(d, id, buf, buf, 0);
+                       num = rte_distributor_get_pkt(d, id, buf, NULL, 0);
                }
        }
        rte_distributor_return_pkt(d, id, buf, num);


-- 
David Marchand



More information about the dev mailing list