Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp1754896pxb; Thu, 16 Sep 2021 14:58:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy3q5yULL/zRpd2EbMMdIFhgOYkq3oWmL1e1M1T1VpeGTpcBF4A292+fhg7vNl1/LsQioCe X-Received: by 2002:a92:cd4d:: with SMTP id v13mr5352335ilq.45.1631829515446; Thu, 16 Sep 2021 14:58:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631829515; cv=none; d=google.com; s=arc-20160816; b=Y6Jdn7PzHFs4p0/VJMP87xaLwOcKK9CsscECpbdqyBtt9FrEuIfzwI7lcp7XepgKqH XgipbITy5LF413/CpRvwjsIsbd3WTeQBfRJLi+GTwz43Wam34McWw5BXz7XkQOIOt/xO Oof8RA6Ki9ItIQm1LyVmv7nayTiSrghzLsXJ+bBZcLYHzLwLEJNIK8Alrw3LH9+4dToC XPVa3MerYYLfurOzxImiLqw5hUj+D+wV/qN/MTn273zl720u46x8XTbKHAtareGHT0nN 3q2llU+xh/8q0IZvbnTKsWIfen5e+qiddnUgqzYYw2qaYU5mkqnSQ6SgKMxOgC5Y+96x vsTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=tnNSmwiejDlvqLQhMs+2eYdSp9PeIV9bpchya0Q+ikU=; b=wX1e0tg3voK5ONc+jymzwQ+Vf2m5JyyMPi3zbOXTYCtt2d3ShzjgQ+H6ftvadma42v 17WsTw+jd/HaQQIaXnrgH/Y7gqYCkjftsjTQ422UEvdh0TJvOUQmOhbvtNirB+uPnA0w Br33rzzYeJnmMtuqyAg5xHSmuD4mjgpV/0zLMv+jSAhu27KfvLqxOlltRo1OeCI7XgpZ joajiGvkMdneavKhkrv+8Oa38vtvbLidGXQAZs1Qp8sz2seJoUIhrjx9jpA2suQIPHGu Swvf+B4p1iMKZfD5VTc1TG0go0EEOAQiiJUL4d4+oFVMUwQ2Xe43F0wmWMABDs91aVge cFZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=tXkIU5Vl; 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=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y10si3921235ion.41.2021.09.16.14.58.21; Thu, 16 Sep 2021 14:58:35 -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=@linuxfoundation.org header.s=korg header.b=tXkIU5Vl; 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=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244951AbhIPQj5 (ORCPT + 99 others); Thu, 16 Sep 2021 12:39:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:44348 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239649AbhIPQdM (ORCPT ); Thu, 16 Sep 2021 12:33:12 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 61BC06139F; Thu, 16 Sep 2021 16:20:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1631809211; bh=8gg7AK441555JIJ//7xJtZMyg3TqeqWKgaUCit8Uwqs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tXkIU5VlT2iROM6+Di4EHCjpQB98UALQaRhedV6vCqeziBwbyZoc1/fdo0fgDut74 1brJKgus5NcXdjHW1JwGpFG86HOWVtGU5f8en0i0IRWxSCwFotaWllnP/jRxtIq7E8 PrgQ2iUUEU6qikrk8ZIA951YG9usBFwWXwf9WhVI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, DJ Gregor , Mikulas Patocka , Arne Welzel , Mike Snitzer Subject: [PATCH 5.13 040/380] dm crypt: Avoid percpu_counter spinlock contention in crypt_page_alloc() Date: Thu, 16 Sep 2021 17:56:37 +0200 Message-Id: <20210916155805.337531130@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210916155803.966362085@linuxfoundation.org> References: <20210916155803.966362085@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Arne Welzel commit 528b16bfc3ae5f11638e71b3b63a81f9999df727 upstream. On systems with many cores using dm-crypt, heavy spinlock contention in percpu_counter_compare() can be observed when the page allocation limit for a given device is reached or close to be reached. This is due to percpu_counter_compare() taking a spinlock to compute an exact result on potentially many CPUs at the same time. Switch to non-exact comparison of allocated and allowed pages by using the value returned by percpu_counter_read_positive() to avoid taking the percpu_counter spinlock. This may over/under estimate the actual number of allocated pages by at most (batch-1) * num_online_cpus(). Currently, batch is bounded by 32. The system on which this issue was first observed has 256 CPUs and 512GB of RAM. With a 4k page size, this change may over/under estimate by 31MB. With ~10G (2%) allowed dm-crypt allocations, this seems an acceptable error. Certainly preferred over running into the spinlock contention. This behavior was reproduced on an EC2 c5.24xlarge instance with 96 CPUs and 192GB RAM as follows, but can be provoked on systems with less CPUs as well. * Disable swap * Tune vm settings to promote regular writeback $ echo 50 > /proc/sys/vm/dirty_expire_centisecs $ echo 25 > /proc/sys/vm/dirty_writeback_centisecs $ echo $((128 * 1024 * 1024)) > /proc/sys/vm/dirty_background_bytes * Create 8 dmcrypt devices based on files on a tmpfs * Create and mount an ext4 filesystem on each crypt devices * Run stress-ng --hdd 8 within one of above filesystems Total %system usage collected from sysstat goes to ~35%. Write throughput on the underlying loop device is ~2GB/s. perf profiling an individual kworker kcryptd thread shows the following profile, indicating spinlock contention in percpu_counter_compare(): 99.98% 0.00% kworker/u193:46 [kernel.kallsyms] [k] ret_from_fork | --ret_from_fork kthread worker_thread | --99.92%--process_one_work | |--80.52%--kcryptd_crypt | | | |--62.58%--mempool_alloc | | | | | --62.24%--crypt_page_alloc | | | | | --61.51%--__percpu_counter_compare | | | | | --61.34%--__percpu_counter_sum | | | | | |--58.68%--_raw_spin_lock_irqsave | | | | | | | --58.30%--native_queued_spin_lock_slowpath | | | | | --0.69%--cpumask_next | | | | | --0.51%--_find_next_bit | | | |--10.61%--crypt_convert | | | | | |--6.05%--xts_crypt ... After applying this patch and running the same test, %system usage is lowered to ~7% and write throughput on the loop device increases to ~2.7GB/s. perf report shows mempool_alloc() as ~8% rather than ~62% in the profile and not hitting the percpu_counter() spinlock anymore. |--8.15%--mempool_alloc | | | |--3.93%--crypt_page_alloc | | | | | --3.75%--__alloc_pages | | | | | --3.62%--get_page_from_freelist | | | | | --3.22%--rmqueue_bulk | | | | | --2.59%--_raw_spin_lock | | | | | --2.57%--native_queued_spin_lock_slowpath | | | --3.05%--_raw_spin_lock_irqsave | | | --2.49%--native_queued_spin_lock_slowpath Suggested-by: DJ Gregor Reviewed-by: Mikulas Patocka Signed-off-by: Arne Welzel Fixes: 5059353df86e ("dm crypt: limit the number of allocated pages") Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-crypt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -2661,7 +2661,12 @@ static void *crypt_page_alloc(gfp_t gfp_ struct crypt_config *cc = pool_data; struct page *page; - if (unlikely(percpu_counter_compare(&cc->n_allocated_pages, dm_crypt_pages_per_client) >= 0) && + /* + * Note, percpu_counter_read_positive() may over (and under) estimate + * the current usage by at most (batch - 1) * num_online_cpus() pages, + * but avoids potential spinlock contention of an exact result. + */ + if (unlikely(percpu_counter_read_positive(&cc->n_allocated_pages) >= dm_crypt_pages_per_client) && likely(gfp_mask & __GFP_NORETRY)) return NULL;