Received: by 2002:a05:6a10:9e8c:0:0:0:0 with SMTP id y12csp319123pxx; Thu, 29 Oct 2020 03:32:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyaWblfTg9m5fteyKT2yfkDGPRb3jckwkJ1WeRuft4fGTe7mpBrOzpruI800IuotiGj1JFl X-Received: by 2002:a17:907:2084:: with SMTP id pv4mr3472337ejb.315.1603967527311; Thu, 29 Oct 2020 03:32:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1603967527; cv=none; d=google.com; s=arc-20160816; b=X2xnlEWZQL/7uKaN8rI+9o1UbG0kCaRfa8BzUFlcoSnsNx+QjeUU/9ZG2QXTsJPrxZ cOnZQFjZ5+mPmqmG2lHYqLCcStMw4b3YzmpqKOD/rxRGb1bWiK7P/p3fpMLl7dh9RNhA 4Cl61NY42ilVq3lCwLBBJ8dwgIeGrjY+Fd5jl3maMJFhCvWlehp0tS/oJlvqHHy7HuR5 TzqW/iiD7RfH5qHIUhDO+q0PpIqKtqFfa6I9ar1t6bGH2Ar216pDk3ryBSPECxpdyig1 +dBrew1UVmWlFiOKTiGowHE3GQphtr3N0/LLr3iKlu+Hux3lkZjx1hhMpdOB+62pLdkI E01A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=pOcKyS6kIsTPqIIHQEn2Hhp8q5MDg5N59RncFe0JbI4=; b=yg+JycUOUNn3KrImN7Y3IwW7573iI1s681KnSC4/ZOcQH+LIfLQsQ0IM83Y8GlA7Ww 24i+9l5lgOZn2lMwkpwM37FF438i6J9WvaVswDAW391ZvsImEFGwEvyDR2RNkwzByNJr q77sn/bhcaQeBwsONC9aGEG1XUB/ZfRlOY6xI3TC/pkyeJOo9YM8aPV739fwer4B3xeh sWUZoCLfw803bF0+uMCHzF2hc903x+zw+IO3PkuT3QY4rRja4m4deaEBKqL363FRbG0r RiAC7hrgVpbRjfL214kDhHs0mIEHhaugN4tExx2eHtJ5QWdoPX7QJv7BtP5wlCJPz7cI Bb8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=cRSeCEyS; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d7si1440672ejk.598.2020.10.29.03.31.44; Thu, 29 Oct 2020 03:32:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=cRSeCEyS; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726653AbgJ2KaN (ORCPT + 99 others); Thu, 29 Oct 2020 06:30:13 -0400 Received: from Galois.linutronix.de ([193.142.43.55]:60548 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725920AbgJ2KaN (ORCPT ); Thu, 29 Oct 2020 06:30:13 -0400 Date: Thu, 29 Oct 2020 10:30:09 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1603967410; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pOcKyS6kIsTPqIIHQEn2Hhp8q5MDg5N59RncFe0JbI4=; b=cRSeCEySrWwinX6SAejhDtQXRaCsZ1aXwO26ovzeLMGbS280tDe/fzM6iIINtLq3zUs1Q3 xs7it+MujosuK2zQkEGXMBf6en2gynmzPspdn4lt1TmQWG7Y9TNHoZVHgIUf1JCSesGrKb RKSwWfvbGB3DVeFbj6AbhffcyMykpbGK840qqREYITJ5AJ98YHXxLZaBtB7S3dNSVlbmO1 FtufwvD+wHuQp45dJYCs0WV0vI93nJjbqdEttTBDQ/cby9rJfwP6HAuu9KaoTQNIq/yOvA 9nxu47zVxyODtT/HAIFJemAaZfRxKZ1TNF3mPlWVuHIzmRuRQ08uXfPL632AXw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1603967410; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pOcKyS6kIsTPqIIHQEn2Hhp8q5MDg5N59RncFe0JbI4=; b=1ZqqdA5FvcYhGPAHVihd1TT3HEHm2rclYLQHdY9wTDqSuKH63/gxIwnQ84DYkmtLAa/TCJ h+mRWmE6SM6K+hCw== From: "tip-bot2 for Jens Axboe" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: core/entry] task_work: Use TIF_NOTIFY_SIGNAL if available Cc: Roman Gershman , Jens Axboe , Thomas Gleixner , Oleg Nesterov , x86 , LKML In-Reply-To: <20201026203230.386348-5-axboe@kernel.dk> References: <20201026203230.386348-5-axboe@kernel.dk> MIME-Version: 1.0 Message-ID: <160396740917.397.14144812059422147901.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the core/entry branch of tip: Commit-ID: 114518eb6430b832d2f9f5a008043b913ccf0e24 Gitweb: https://git.kernel.org/tip/114518eb6430b832d2f9f5a008043b913ccf0e24 Author: Jens Axboe AuthorDate: Mon, 26 Oct 2020 14:32:30 -06:00 Committer: Thomas Gleixner CommitterDate: Thu, 29 Oct 2020 09:37:37 +01:00 task_work: Use TIF_NOTIFY_SIGNAL if available If the arch supports TIF_NOTIFY_SIGNAL, then use that for TWA_SIGNAL as it's more efficient than using the signal delivery method. This is especially true on threaded applications, where ->sighand is shared across threads, but it's also lighter weight on non-shared cases. io_uring is a heavy consumer of TWA_SIGNAL based task_work. A test with threads shows a nice improvement running an io_uring based echo server. stock kernel: 0.01% <= 0.1 milliseconds 95.86% <= 0.2 milliseconds 98.27% <= 0.3 milliseconds 99.71% <= 0.4 milliseconds 100.00% <= 0.5 milliseconds 100.00% <= 0.6 milliseconds 100.00% <= 0.7 milliseconds 100.00% <= 0.8 milliseconds 100.00% <= 0.9 milliseconds 100.00% <= 1.0 milliseconds 100.00% <= 1.1 milliseconds 100.00% <= 2 milliseconds 100.00% <= 3 milliseconds 100.00% <= 3 milliseconds 1378930.00 requests per second ~1600% CPU 1.38M requests/second, and all 16 CPUs are maxed out. patched kernel: 0.01% <= 0.1 milliseconds 98.24% <= 0.2 milliseconds 99.47% <= 0.3 milliseconds 99.99% <= 0.4 milliseconds 100.00% <= 0.5 milliseconds 100.00% <= 0.6 milliseconds 100.00% <= 0.7 milliseconds 100.00% <= 0.8 milliseconds 100.00% <= 0.9 milliseconds 100.00% <= 1.2 milliseconds 1666111.38 requests per second ~1450% CPU 1.67M requests/second, and we're no longer just hammering on the sighand lock. The original reporter states: "For 5.7.15 my benchmark achieves 1.6M qps and system cpu is at ~80%. for 5.7.16 or later it achieves only 1M qps and the system cpu is is at ~100%" with the only difference there being that TWA_SIGNAL is used unconditionally in 5.7.16, since it's required to be able to handle the inability to run task_work if the application is waiting in the kernel already on an event that needs task_work run to be satisfied. Also see commit 0ba9c9edcd15. Reported-by: Roman Gershman Signed-off-by: Jens Axboe Signed-off-by: Thomas Gleixner Reviewed-by: Oleg Nesterov Link: https://lore.kernel.org/r/20201026203230.386348-5-axboe@kernel.dk --- kernel/task_work.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/kernel/task_work.c b/kernel/task_work.c index 613b2d6..ae05889 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -5,6 +5,34 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */ +/* + * TWA_SIGNAL signaling - use TIF_NOTIFY_SIGNAL, if available, as it's faster + * than TIF_SIGPENDING as there's no dependency on ->sighand. The latter is + * shared for threads, and can cause contention on sighand->lock. Even for + * the non-threaded case TIF_NOTIFY_SIGNAL is more efficient, as no locking + * or IRQ disabling is involved for notification (or running) purposes. + */ +static void task_work_notify_signal(struct task_struct *task) +{ +#if defined(TIF_NOTIFY_SIGNAL) + set_notify_signal(task); +#else + unsigned long flags; + + /* + * Only grab the sighand lock if we don't already have some + * task_work pending. This pairs with the smp_store_mb() + * in get_signal(), see comment there. + */ + if (!(READ_ONCE(task->jobctl) & JOBCTL_TASK_WORK) && + lock_task_sighand(task, &flags)) { + task->jobctl |= JOBCTL_TASK_WORK; + signal_wake_up(task, 0); + unlock_task_sighand(task, &flags); + } +#endif +} + /** * task_work_add - ask the @task to execute @work->func() * @task: the task which should run the callback @@ -28,7 +56,6 @@ int task_work_add(struct task_struct *task, struct callback_head *work, int notify) { struct callback_head *head; - unsigned long flags; do { head = READ_ONCE(task->task_works); @@ -42,17 +69,7 @@ task_work_add(struct task_struct *task, struct callback_head *work, int notify) set_notify_resume(task); break; case TWA_SIGNAL: - /* - * Only grab the sighand lock if we don't already have some - * task_work pending. This pairs with the smp_store_mb() - * in get_signal(), see comment there. - */ - if (!(READ_ONCE(task->jobctl) & JOBCTL_TASK_WORK) && - lock_task_sighand(task, &flags)) { - task->jobctl |= JOBCTL_TASK_WORK; - signal_wake_up(task, 0); - unlock_task_sighand(task, &flags); - } + task_work_notify_signal(task); break; }