Skip to content

Instantly share code, notes, and snippets.

@qrealka
Last active January 27, 2025 17:19
Show Gist options
  • Save qrealka/fa1ac83a1e5339bc2be1245c0309d794 to your computer and use it in GitHub Desktop.
Save qrealka/fa1ac83a1e5339bc2be1245c0309d794 to your computer and use it in GitHub Desktop.

Revisions

  1. qrealka revised this gist Jan 27, 2025. 1 changed file with 2448 additions and 0 deletions.
    2,448 changes: 2,448 additions & 0 deletions TSAN.txt
    2,448 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
  2. qrealka revised this gist Jan 27, 2025. 1 changed file with 11 additions and 5 deletions.
    16 changes: 11 additions & 5 deletions main.c
    Original file line number Diff line number Diff line change
    @@ -24,7 +24,7 @@
    #ifdef __SANITIZE_THREAD__

    const char TSANDefaultOptions[] =
    "halt_on_error=1:abort_on_error=1:"
    "halt_on_error=0:abort_on_error=0:verbosity=2:"
    "detect_deadlocks=1:second_deadlock_stack=1: report_signal_unsafe=0:"
    "report_thread_leaks=0:print_suppressions=1:"
    "force_seq_cst_atomics=0"; // do not enforce CST for atomic ops
    @@ -43,11 +43,12 @@ static int worker(void* __rte_unused args)
    {
    char name[64] = {0};
    RTE_SET_USED(snprintf(name, sizeof(name), "%u", rte_lcore_id()));
    struct rte_ring* r = rte_ring_create(name, 4, (int)rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);
    char* p = rte_zmalloc(NULL, sizeof(name), 0);
    //struct rte_ring* r = rte_ring_create(name, 4, (int)rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);
    char* p = rte_malloc(name, sizeof(name), 0);
    rte_pause();
    RTE_VERIFY(p != NULL);
    RTE_VERIFY(r != NULL);
    rte_ring_free(r);
    //RTE_VERIFY(r != NULL);
    //rte_ring_free(r);
    rte_free(p);
    return 0;

    @@ -60,6 +61,11 @@ int main(int argc, char* argv[]) {
    goto cleanup;
    }

    void* tmp = rte_malloc(NULL, 64, 0);
    RTE_VERIFY(tmp != NULL);
    RTE_SET_USED(tmp);
    rte_free(tmp);

    ret = rte_eal_mp_remote_launch(worker, NULL, SKIP_MAIN);
    if (ret < 0)
    {
  3. qrealka created this gist Jan 24, 2025.
    75 changes: 75 additions & 0 deletions main.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    /**
    * Tested on DPDK 21.11
    * DPDK has been build by the following options:
    * meson setup build --prefix ~/dpdk.tsan --prefer-static --buildtype debug --debug -Denable_driver_sdk=false -Denable_kmods=false -Dc_std=gnu17 -Ddefault_library=static -Db_sanitize=thread -Dplatform=native -Dtests=false -Denable_trace_fp=true -Dc_args="-DRTE_USE_C11_MEM_MODEL=1 -Wno-tsan" -Ddisable_libs=acl,bpf,compressdev,cryptodev,gpudev,security,regexdev,pdump,pcapng,power -Ddisable_drivers=compress/*,crypto/*,event/*,baseband/*,gpu/*,regex/*,net/bnx*,net/qed*,net/ena*,net/af_*,net/cp*,net/id*
    *
    * Repro steps:
    * 1. build & install DPDK (see above)
    * 2. init test project: meson setup buildDir --debug -Db_sanitize=thread --pkg-config-path ~/dpdk.tsan/lib/x86_64-linux-gnu/pkgconfig/
    * 3. build test project: meson compile -C buildDir
    * 4. run it: meson test -v -C buildDir
    */
    #include <rte_common.h>
    #include <rte_eal.h>
    #include <rte_errno.h>
    #include <rte_launch.h>
    #include <rte_malloc.h>
    #include <rte_ring.h>

    #include <stdio.h>

    #define VISIBLE __attribute__((visibility("default"), used))
    #define NO_SANITIZE __attribute__((no_sanitize_address, no_sanitize_thread, no_sanitize_thread))

    #ifdef __SANITIZE_THREAD__

    const char TSANDefaultOptions[] =
    "halt_on_error=1:abort_on_error=1:"
    "detect_deadlocks=1:second_deadlock_stack=1: report_signal_unsafe=0:"
    "report_thread_leaks=0:print_suppressions=1:"
    "force_seq_cst_atomics=0"; // do not enforce CST for atomic ops

    // The function isn't referenced from the executable itself. Make sure it isn't
    // stripped by the linker.
    extern NO_SANITIZE VISIBLE const char* __tsan_default_options(void); // NOLINT

    NO_SANITIZE VISIBLE const char* __tsan_default_options(void) {
    return TSANDefaultOptions;
    }

    #endif

    static int worker(void* __rte_unused args)
    {
    char name[64] = {0};
    RTE_SET_USED(snprintf(name, sizeof(name), "%u", rte_lcore_id()));
    struct rte_ring* r = rte_ring_create(name, 4, (int)rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);
    char* p = rte_zmalloc(NULL, sizeof(name), 0);
    RTE_VERIFY(p != NULL);
    RTE_VERIFY(r != NULL);
    rte_ring_free(r);
    rte_free(p);
    return 0;

    }

    int main(int argc, char* argv[]) {
    int ret = rte_eal_init(argc, argv);
    if (ret < 0) {
    puts(rte_strerror(rte_errno));
    goto cleanup;
    }

    ret = rte_eal_mp_remote_launch(worker, NULL, SKIP_MAIN);
    if (ret < 0)
    {
    puts(rte_strerror(rte_errno));
    goto cleanup;
    }

    rte_eal_mp_wait_lcore();

    cleanup:
    rte_eal_cleanup();
    return ret;
    }
    82 changes: 82 additions & 0 deletions meson.build
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    project('dpdk_ring_tsan', 'c',
    version : '1.0.0',
    default_options : [
    'default_library=static',
    'buildtype=debug',
    'b_ndebug=if-release',
    'c_std=gnu17',
    'warning_level=3',
    ],
    )

    c_project_args = [
    '-pipe',
    '-march=native',
    '-fno-strict-aliasing',
    '-Wmissing-prototypes',
    '-Wold-style-definition',
    '-Wstrict-prototypes',
    '-Wno-tsan',
    '-Wno-unused-parameter',
    '-D_GNU_SOURCE=1',
    '-DALLOW_EXPERIMENTAL_API',
    ]

    # DPDK libc version requirement
    ldd = find_program('ld', required: true, version: '>2.7')
    compiler = meson.get_compiler('c')

    if get_option('buildtype') == 'debug'
    c_project_args += [
    '-ggdb3',
    '-fno-inline',
    '-fno-omit-frame-pointer',
    '-DRTE_ENABLE_ASSERT',
    '-U_FORTIFY_SOURCE',
    '-fcf-protection=full',
    '-fno-sanitize=alignment',
    '-fno-common',
    ]
    else
    c_project_args += [
    '-ftree-vectorize',
    ]
    endif

    c_project_args = compiler.get_supported_arguments(c_project_args)
    add_project_arguments([c_project_args], language: ['c'])

    threads_dep = dependency('threads', static: true)
    libdpdk = dependency('libdpdk', include_type: 'system', method : 'pkg-config', static: true)
    librt = compiler.find_library('rt', required: true, static: true)

    main_dep = [
    librt,
    libdpdk,
    threads_dep,
    ]
    # on some OS maths functions like log, pow in a separate library
    if compiler.find_library('m', required : false).found()
    main_dep += [compiler.find_library('m', required: true, static: true)]
    endif


    summary({'DPDK': libdpdk.version()})
    dpdk_ring_tsan = executable('dpdk_ring_tsan', 'main.c',
    dependencies: main_dep,
    gnu_symbol_visibility: 'hidden',
    )

    test('rint_tst',
    dpdk_ring_tsan,
    args: [
    '--no-pci',
    '--no-hpet',
    '--no-huge',
    '--no-shconf',
    '--log-level=lib.eal:debug',
    '-m 1024'
    ],
    verbose: true,
    timeout: 30,
    )