From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.1 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id CF8A21F852 for ; Mon, 19 Dec 2022 22:57:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1671490657; bh=+hAmJSEjzFICGYzlZa38xeuOOeo1Fo4ABbgPqCFsafc=; h=Date:From:To:Subject:References:In-Reply-To:From; b=QRzEtOyBMFGOtfv46kQnovCiqF+rM+SguPm72RA2oaHoVuD4ZsD7vGD5Sn6v7r2Bl JiWCf51qQ6q654fLzetZWlS+SpYYPdhm/Ko1e0Yph83dhQ6tkDs2grqkek5rEOb3tP jLZJ933Xs5xv26vvYDuCvpe9zvHSfoRTeOKo++Hg= Date: Mon, 19 Dec 2022 22:57:37 +0000 From: Eric Wong To: mwrap-perl@80x24.org Subject: [WIP] attempt to workaround older URCU for signalfd Message-ID: <20221219225737.M672846@dcvr> References: <20221219111922.1079128-1-e@80x24.org> <20221219111922.1079128-8-e@80x24.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20221219111922.1079128-8-e@80x24.org> List-Id: Eric Wong wrote: > Fortunately, there aren't a lot of signalfd users right now > (except me :x). In any case, this problem should sort itself > out in a few years when new URCU releases replace old ones. > +* signalfd(2)-reliant code will need latest URCU with commit > + ea3a28a3f71dd02f (Disable signals in URCU background threads, 2022-09-23) Fwiw, this was my attempt to workaround current (released) URCU for fork() users. Maybe I missed something, but I was still getting one thread with signals unmasked after forking. Not sure it's worth my time to check since I can easily backport URCU commit ea3a28a3f71dd02f for my own use. (URCU is fairly small and fast to build) diff --git a/mwrap_core.h b/mwrap_core.h index b014f5d..6d3d474 100644 --- a/mwrap_core.h +++ b/mwrap_core.h @@ -963,17 +963,32 @@ static struct src_loc *mwrap_get_bin(const char *buf, size_t len) static const char *mwrap_env; #include "httpd.h" +/* force call_rcu to start background thread while signals are blocked */ +static void start_call_rcu(void) +{ + struct alloc_hdr *h = real_malloc(sizeof(struct alloc_hdr)); + if (h) { + h->real = h; + call_rcu(&h->as.dead, free_hdr_rcu); + } else + fprintf(stderr, "malloc: %m\n"); + struct cds_lfht *ht = lfht_new(1); + if (ht) + cds_lfht_destroy(ht, NULL); + else + fprintf(stderr, "cds_lfht_new: %m\n"); +} + __attribute__((constructor)) static void mwrap_ctor(void) { - sigset_t set, old; - struct alloc_hdr *h; mwrap_env = getenv("MWRAP"); ++locating; /* block signals */ - CHECK(int, 0, sigfillset(&set)); - CHECK(int, 0, pthread_sigmask(SIG_SETMASK, &set, &old)); + sigset_t blk, old; + CHECK(int, 0, sigfillset(&blk)); + CHECK(int, 0, pthread_sigmask(SIG_BLOCK, &blk, &old)); ensure_initialization(); CHECK(int, 0, pthread_key_create(&tlskey, mstate_tsd_dtor)); @@ -984,13 +999,7 @@ __attribute__((constructor)) static void mwrap_ctor(void) CMM_STORE_SHARED(totals, lfht_new(16384)); if (!CMM_LOAD_SHARED(totals)) fprintf(stderr, "failed to allocate totals table\n"); - h = real_malloc(sizeof(struct alloc_hdr)); - if (h) { /* force call_rcu to start background thread */ - h->real = h; - call_rcu(&h->as.dead, free_hdr_rcu); - } else - fprintf(stderr, "malloc: %m\n"); - + start_call_rcu(); h1d_start(); CHECK(int, 0, pthread_sigmask(SIG_SETMASK, &old, NULL)); CHECK(int, 0, pthread_atfork(atfork_prepare, atfork_parent, diff --git a/mymalloc.h b/mymalloc.h index 518cce3..e611485 100644 --- a/mymalloc.h +++ b/mymalloc.h @@ -41,6 +41,7 @@ #include #include #include +#include /* this is fine on most x86-64, especially with file-backed mmap(2) */ #define DEFAULT_GRANULARITY (64U * 1024U * 1024U) @@ -126,6 +127,7 @@ ATTR_COLD static void mstate_tsd_dtor(void *p) CHECK(int, 0, pthread_mutex_unlock(&global_mtx)); } +static void start_call_rcu(void); /* see httpd.h */ static void h1d_atfork_prepare(void); static void h1d_atfork_parent(void); @@ -141,9 +143,14 @@ ATTR_COLD static void atfork_prepare(void) ATTR_COLD static void atfork_parent(void) { CHECK(int, 0, pthread_mutex_unlock(&global_mtx)); + sigset_t blk, old; + CHECK(int, 0, sigfillset(&blk)); + CHECK(int, 0, pthread_sigmask(SIG_BLOCK, &blk, &old)); call_rcu_after_fork_parent(); CHECK(int, 0, pthread_mutex_lock(&global_mtx)); h1d_atfork_parent(); + start_call_rcu(); + CHECK(int, 0, pthread_sigmask(SIG_SETMASK, &old, NULL)); CHECK(int, 0, pthread_mutex_unlock(&global_mtx)); } @@ -166,8 +173,13 @@ ATTR_COLD static void atfork_child(void) cds_list_add(&ms_tsd->arena_node, &arenas_active); } reset_mutexes(); + sigset_t blk, old; + CHECK(int, 0, sigfillset(&blk)); + CHECK(int, 0, pthread_sigmask(SIG_BLOCK, &blk, &old)); call_rcu_after_fork_child(); h1d_start(); + start_call_rcu(); + CHECK(int, 0, pthread_sigmask(SIG_SETMASK, &old, NULL)); } #if defined(__GLIBC__)