Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is mallctl arena.<i>.purge non-thread-safe? #2621

Open
sundb opened this issue Mar 25, 2024 · 2 comments
Open

is mallctl arena.<i>.purge non-thread-safe? #2621

sundb opened this issue Mar 25, 2024 · 2 comments

Comments

@sundb
Copy link
Contributor

sundb commented Mar 25, 2024

the following example will raise a race between main thread and thread with thread sanitizer.
reproduce:

void* free_memory(void* arg) {
    /* let main thread start pruge first */
    sleep(1);
    je_free(arg);
    pthread_exit(NULL);
}

int jemalloc_purge(void) {
    /* return all unused (reserved) pages to the OS */
    char tmp[32];
    unsigned narenas = 0;
    size_t sz = sizeof(unsigned);
    if (!je_mallctl("arenas.narenas", &narenas, &sz, NULL, 0)) {
        snprintf(tmp, sizeof(tmp), "arena.%d.purge", narenas);
        if (!je_mallctl(tmp, NULL, 0, NULL, 0))
            return 0;
    }
    return -1;
}

int main(int argc, char **argv) {
    pthread_t tid;
    void *ptr = je_malloc(100);
    int ret = pthread_create(&tid, NULL, free_memory, ptr);
    if (ret != 0) {
        exit(EXIT_FAILURE);
    }

    while (1) {
        jemalloc_purge();
    }

    return 0;
}
WARNING: ThreadSanitizer: data race (pid=597532)
  Atomic read of size 1 at 0x7ff6e4811f48 by main thread:
    #0 pthread_mutex_trylock ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1355 (libtsan.so.2+0x3d9bf) (BuildId: 28a9f70061dbb2dfa2cef661d3b23aff4ea13536)
    #1 malloc_mutex_trylock_final include/jemalloc/internal/mutex.h:157 (redis-server+0x30e39f) (BuildId: 3918d06d3a32b8ddf706575e764f110e97a246a3)
    #2 malloc_mutex_lock include/jemalloc/internal/mutex.h:216 (redis-server+0x30e39f)
    #3 arena_decay_impl src/arena.c:427 (redis-server+0x30e39f)
    #4 arena_decay_dirty src/arena.c:460 (redis-server+0x30e39f)
    #5 je_arena_decay src/arena.c:486 (redis-server+0x30e39f)
    #6 __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 (libc.so.6+0x2814f) (BuildId: 6a981b07a3731293c24c10a21397416d3c3d52ed)

  Previous write of size 1 at 0x7ff6e4811f48 by thread T1 (mutexes: write M0):
    #0 pthread_mutex_init ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1329 (libtsan.so.2+0x3d7a6) (BuildId: 28a9f70061dbb2dfa2cef661d3b23aff4ea13536)
    #1 je_malloc_mutex_init src/mutex.c:172 (redis-server+0x368136) (BuildId: 3918d06d3a32b8ddf706575e764f110e97a246a3)
    #2 free_memory /home/sundb/data/redis_fork_1/src/server.c:6881 (redis-server+0xc1d66) (BuildId: 3918d06d3a32b8ddf706575e764f110e97a246a3)

  Mutex M0 (0x564b6a7ae980) created at:
    #0 pthread_mutex_init ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1329 (libtsan.so.2+0x3d7a6) (BuildId: 28a9f70061dbb2dfa2cef661d3b23aff4ea13536)
    #1 je_malloc_mutex_init src/mutex.c:172 (redis-server+0x368136) (BuildId: 3918d06d3a32b8ddf706575e764f110e97a246a3)

  Thread T1 (tid=597534, running) created by main thread at:
    #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1036 (libtsan.so.2+0x3d179) (BuildId: 28a9f70061dbb2dfa2cef661d3b23aff4ea13536)
    #1 main /home/sundb/data/redis_fork_1/src/server.c:6900 (redis-server+0x8433b) (BuildId: 3918d06d3a32b8ddf706575e764f110e97a246a3)
@interwq
Copy link
Member

interwq commented Mar 30, 2024

Not following why this is a race. It looks that the main thread is doing pthread_mutex_trylock, in which case the mutex was created by T1 using pthread_mutex_init previously? Isn't that regular mutex operations?

@sundb
Copy link
Contributor Author

sundb commented Mar 31, 2024

@interwq thanks for your reply.
contrary to what you said, the main thread try lock the mutex which was initialized by main thread, but the thread may reinitialize the mutex again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants