From patchwork Tue Sep 7 12:22:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44884 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 96FC8385E823 for ; Tue, 7 Sep 2021 12:25:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 96FC8385E823 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1631017532; bh=zEHpoVo0KK9UfNWAQE99bwIKZBikAJMSSDGIaozFS88=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=B1CVMOi8iTe/qqSAIlHuOpU3701yvSb8MexKLpKVQaDBrNZgoquGN1OfEiLOoMzaw fh6t/x5FTazYBvmry6WvwOy+BHzMMzedjFXloVn6gsrEYJCSQhThZ/tycNUpINzUVj EgrHmeY0N7+QVFERBAMt6URyAwI7Rtm8D7nlK80c= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by sourceware.org (Postfix) with ESMTPS id 64FF1385780D for ; Tue, 7 Sep 2021 12:23:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 64FF1385780D Received: by mail-qk1-x72a.google.com with SMTP id f22so9821927qkm.5 for ; Tue, 07 Sep 2021 05:23:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zEHpoVo0KK9UfNWAQE99bwIKZBikAJMSSDGIaozFS88=; b=CFcxYXCkMT0yQ9Lf/iNqPtMlUzU5OVz8TUOhug3jXUoXDo1xJQRG+GXJQI1Qjlbg+X C3sS/5pmO+z8qT+SYVqWMBw2X7YzoHQepUg1POeK6H86vJZwtM9/7ii3Ypef01Q5x2+1 kf6te4uXtB2vmNeZlc1XO+X/cYb/KOhQW4vOYXzznnxjVkciinkLu3Xxgi2sAecfFDhU nkR55tUlh+WRFsuJ7iv8VowiClasUx7+v1ZA63eRxSYge92xKRHRMPvDDfpdV34SWgk3 pqhNogd1Sny8YL8BwZCc694A/9jW83lsM0tFVpKBkOlTipBBWGN2hGzDVzvvFyzGeibE m7rQ== X-Gm-Message-State: AOAM5335WV/Y5q4Z6r7Ckq2dIePVMA47/II/YFuRjPrKYvuiqSxf9qNZ vlYSyhVCa3RL1p3FxiPdSCJzGlW+7UlGGg== X-Google-Smtp-Source: ABdhPJxeBvMODRZd0yvfy+7ciDPJgeUBPWbCky/MmvrzeotQ4l8/6DpPgChb21kH/PXOwXAjhv3CVA== X-Received: by 2002:a37:ea05:: with SMTP id t5mr14920671qkj.515.1631017386844; Tue, 07 Sep 2021 05:23:06 -0700 (PDT) Received: from birita.. ([2804:431:c7cb:733d:f360:5bf3:9813:d8f5]) by smtp.gmail.com with ESMTPSA id r18sm6902148qtm.96.2021.09.07.05.23.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Sep 2021 05:23:06 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v2 3/3] linux: Revert the use of sched_getaffinity on get_nproc (BZ #28310) Date: Tue, 7 Sep 2021 09:22:59 -0300 Message-Id: <20210907122259.79800-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210907122259.79800-1-adhemerval.zanella@linaro.org> References: <20210907122259.79800-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: Florian Weimer , Nicolas Saenz Julienne Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The use of sched_getaffinity on get_nproc and sysconf (_SC_NPROCESSORS_ONLN) done in 903bc7dcc2acafc40 (BZ #27645) breaks the top command in common hypervisor configurations and also other monitoring tools. The main issue using sched_getaffinity changed the symbols semantic from system-wide scope of online CPUs to per-process one (which can be changed with kernel cpusets or book parameters in VM). This patch reverts mostly of the 903bc7dcc2acafc40, with the exceptions: * No more cached values and atomic updates, since they are inherent racy. * No /proc/cpuinfo fallback, since /proc/stat is already used and it would require to revert more arch-specific code. * The alloca is replace with a static buffer of 1024 bytes. So the implementation first consult the sysfs, and fallbacks to procfs. Checked on x86_64-linux-gnu. Reviewed-by: Florian Weimer --- sysdeps/unix/sysv/linux/getsysstats.c | 139 +++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 5 deletions(-) diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c index 1e3d88676d..15ad91cf2f 100644 --- a/sysdeps/unix/sysv/linux/getsysstats.c +++ b/sysdeps/unix/sysv/linux/getsysstats.c @@ -17,6 +17,8 @@ . */ #include +#include +#include #include #include #include @@ -29,7 +31,7 @@ #include int -__get_nprocs (void) +__get_nprocs_sched (void) { enum { @@ -52,14 +54,141 @@ __get_nprocs (void) atomics are needed). */ return 2; } -libc_hidden_def (__get_nprocs) -weak_alias (__get_nprocs, get_nprocs) + +static char * +next_line (int fd, char *const buffer, char **cp, char **re, + char *const buffer_end) +{ + char *res = *cp; + char *nl = memchr (*cp, '\n', *re - *cp); + if (nl == NULL) + { + if (*cp != buffer) + { + if (*re == buffer_end) + { + memmove (buffer, *cp, *re - *cp); + *re = buffer + (*re - *cp); + *cp = buffer; + + ssize_t n = __read_nocancel (fd, *re, buffer_end - *re); + if (n < 0) + return NULL; + + *re += n; + + nl = memchr (*cp, '\n', *re - *cp); + while (nl == NULL && *re == buffer_end) + { + /* Truncate too long lines. */ + *re = buffer + 3 * (buffer_end - buffer) / 4; + n = __read_nocancel (fd, *re, buffer_end - *re); + if (n < 0) + return NULL; + + nl = memchr (*re, '\n', n); + **re = '\n'; + *re += n; + } + } + else + nl = memchr (*cp, '\n', *re - *cp); + + res = *cp; + } + + if (nl == NULL) + nl = *re - 1; + } + + *cp = nl + 1; + assert (*cp <= *re); + + return res == *re ? NULL : res; +} + int -__get_nprocs_sched (void) +__get_nprocs (void) { - return __get_nprocs (); + enum { buffer_size = 1024 }; + char buffer[buffer_size]; + char *buffer_end = buffer + buffer_size; + char *cp = buffer_end; + char *re = buffer_end; + + const int flags = O_RDONLY | O_CLOEXEC; + /* This file contains comma-separated ranges. */ + int fd = __open_nocancel ("/sys/devices/system/cpu/online", flags); + char *l; + int result = 0; + if (fd != -1) + { + l = next_line (fd, buffer, &cp, &re, buffer_end); + if (l != NULL) + do + { + char *endp; + unsigned long int n = strtoul (l, &endp, 10); + if (l == endp) + { + result = 0; + break; + } + + unsigned long int m = n; + if (*endp == '-') + { + l = endp + 1; + m = strtoul (l, &endp, 10); + if (l == endp) + { + result = 0; + break; + } + } + + result += m - n + 1; + + l = endp; + if (l < re && *l == ',') + ++l; + } + while (l < re && *l != '\n'); + + __close_nocancel_nostatus (fd); + + if (result > 0) + return result; + } + + cp = buffer_end; + re = buffer_end; + + /* Default to an SMP system in case we cannot obtain an accurate + number. */ + result = 2; + + fd = __open_nocancel ("/proc/stat", flags); + if (fd != -1) + { + result = 0; + + while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) + /* The current format of /proc/stat has all the cpu* entries + at the front. We assume here that stays this way. */ + if (strncmp (l, "cpu", 3) != 0) + break; + else if (isdigit (l[3])) + ++result; + + __close_nocancel_nostatus (fd); + } + + return result; } +libc_hidden_def (__get_nprocs) +weak_alias (__get_nprocs, get_nprocs) /* On some architectures it is possible to distinguish between configured