From patchwork Mon Oct 23 16:22:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: andrey.konovalov@linux.dev X-Patchwork-Id: 13433196 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07E71C25B43 for ; Mon, 23 Oct 2023 16:25:19 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 92A256B0110; Mon, 23 Oct 2023 12:25:14 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 8D99B6B0112; Mon, 23 Oct 2023 12:25:14 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6696E6B0111; Mon, 23 Oct 2023 12:25:14 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 4D89D6B010F for ; Mon, 23 Oct 2023 12:25:14 -0400 (EDT) Received: from smtpin04.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id EA593A0A94 for ; Mon, 23 Oct 2023 16:25:13 +0000 (UTC) X-FDA: 81377250906.04.B72D3D3 Received: from out-203.mta0.migadu.com (out-203.mta0.migadu.com [91.218.175.203]) by imf16.hostedemail.com (Postfix) with ESMTP id 013B4180030 for ; Mon, 23 Oct 2023 16:25:11 +0000 (UTC) Authentication-Results: imf16.hostedemail.com; dkim=pass header.d=linux.dev header.s=key1 header.b="oyH/s4RT"; spf=pass (imf16.hostedemail.com: domain of andrey.konovalov@linux.dev designates 91.218.175.203 as permitted sender) smtp.mailfrom=andrey.konovalov@linux.dev; dmarc=pass (policy=none) header.from=linux.dev ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1698078312; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=KyQaV2ck0CZBTZjrz6rGoXlFfvUUwlefDCsA1d1OnDI=; b=bEjGHZewFqIG1GmPbnksuH+0OVJ7jqtgDlSxM9lwLOJlaDQVZGhzvFZNJ/kyJFenY5xoUI zSSYPg+JZ0GAHiyvKFDRXXxUjr9pIsc0tjIVnyd587wOWzUrYbtPUeJvQWhvawmE2fuoK6 VbtLtZYgF4aBzaOq6gLR79BaONT4jgQ= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1698078312; a=rsa-sha256; cv=none; b=n+uuxy9uPkDA5lx3A1SeUoLY1K+LJ3zmV6aoIzQXT/HqooHfpuNfgFzKePCiFXD6vc5ji/ 1/K3OmVipxBd6fm3FymF4tAGEpVlHw59Czl01nUU+asyp9uY9o72PFUkHQjxCHjw9sAwJd jTgITmJs/VdCBA1dp0GIDMht9lOU9Jo= ARC-Authentication-Results: i=1; imf16.hostedemail.com; dkim=pass header.d=linux.dev header.s=key1 header.b="oyH/s4RT"; spf=pass (imf16.hostedemail.com: domain of andrey.konovalov@linux.dev designates 91.218.175.203 as permitted sender) smtp.mailfrom=andrey.konovalov@linux.dev; dmarc=pass (policy=none) header.from=linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1698078310; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KyQaV2ck0CZBTZjrz6rGoXlFfvUUwlefDCsA1d1OnDI=; b=oyH/s4RTev5TTn2tx92NM3vkXg6oUk6Kpicty1qVqAfYRd+524Z47P2qCKhvUIRV4y3uiL rlsDYYtewCtLkLPB0dG2UOn/EJuLBsAiSUiToU+oaYgXFZHxJ+CthWgKW++yb5No2yIg9Y u1Z8kAH4ZHqywmyABUdVN11IBWKHboo= From: andrey.konovalov@linux.dev To: Marco Elver , Alexander Potapenko Cc: Andrey Konovalov , Dmitry Vyukov , Vlastimil Babka , kasan-dev@googlegroups.com, Evgenii Stepanov , Oscar Salvador , Andrew Morton , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrey Konovalov Subject: [PATCH v3 16/19] lib/stackdepot: allow users to evict stack traces Date: Mon, 23 Oct 2023 18:22:47 +0200 Message-Id: <8ba201688d0e4b8f3ec56b426bb350965a30c8fd.1698077459.git.andreyknvl@google.com> In-Reply-To: References: MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-Stat-Signature: zridzokxsxs13crb41kbu4ua5gbxz8hs X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 013B4180030 X-Rspam-User: X-HE-Tag: 1698078311-735068 X-HE-Meta: U2FsdGVkX189F02R6fhdfmqANDKUM5pk5mMgnJIlqh05QB/7Mo8RVea1whHac6fe2FA1Brf2uTsTTbw7ANPKgp0phsKqC/ruhD0+6hKsgqeVte3Dllu1rYE97wSG50o0F7xvomjx4fS63lkBlAL8/p85Dl7+DRcHOEw+okhCkSEi8W8GojrTHE/t12k2RDcnqo8Vd6pw7aVSAc7Kf/lDTfDVLv5/zi4aKYBJV+5Svii1fRPvNepAfoaTH/pISsdSFTRxvYsWT8opW5akNDFLRftzS3dd1h338J/YAo6oOV3schu2T4Imk2vKZPezMk19PnCSeFRI88N5gahHX1E1v147t6UDiOcFTsLW9L26+FCTpZPh68JR/59KQee3wPHITotKSBVFfo+C104VmVRs62UwuAsYEZSsxhWNdH1AI2UrUgyeEKKSvLi/N6oUtzznTiB3qIbSu00UcaRUaWO6kxticEIi3zvWACcmu9wrxguTe23gmMEmYpAGR0004NTZHdH+YKQ2WuZ7/nRnfPhI2AEbDMfKsiSNMnVma02AYBYgG3VHtOBFj8VwiUQ6t+79owtRmQSQiQQW6QV20X8f14es7Z9cPgMU4O0+ont3d3jKlVbpd31IsR7KCwg28enINVeEctYW9UO1NGG5cYelwoTu0FWbXv5G3oN9MWHr9wgle0cNEbBLIpEAr42aeS78nkNFZrF3BrIAMKdd01z6ASCB32ydTjtsQ8gYSaNqVTIePqGEyP9HiqKPXW6WO8UEvjngoXghwxuzuplkwVwZc0JFWCRwKLKDoHIgk7c0dyjg3H1XsLUAboASpHxmNPAY37nNEfH6+q+F/KBH9IbGnpQk1ajz6Dv57KMNndP9YZRVJ8hCgSaxnR9beBP9Wg9e4JyIvCsuGzgCW625Ji5tP/HUYSmUsmKMLyH3mowpE19PBsSypGmvY8n6OmRX+it3dHAfHLq5dOG/2s0njki bGmPhhtL etl/hB+i6lOrx/mn/p3iDs/ltwFsfv2uRRA8LT73kNtBUILGEcxNFxJEoqIScHy/kuAS8deoLdi7sv2cX9xKN1wljfg== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: Andrey Konovalov Add stack_depot_put, a function that decrements the reference counter on a stack record and removes it from the stack depot once the counter reaches 0. Internally, when removing a stack record, the function unlinks it from the hash table bucket and returns to the freelist. With this change, the users of stack depot can call stack_depot_put when keeping a stack trace in the stack depot is not needed anymore. This allows avoiding polluting the stack depot with irrelevant stack traces and thus have more space to store the relevant ones before the stack depot reaches its capacity. Signed-off-by: Andrey Konovalov --- Changes v1->v2: - Comments fixes as suggested by Marco. - Add lockdep_assert annotation. - Adapt to using list_head's. - Rename stack_depot_evict to stack_depot_put. --- include/linux/stackdepot.h | 14 ++++++++++++++ lib/stackdepot.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h index 611716702d73..a6796f178913 100644 --- a/include/linux/stackdepot.h +++ b/include/linux/stackdepot.h @@ -97,6 +97,8 @@ static inline int stack_depot_early_init(void) { return 0; } * * If STACK_DEPOT_FLAG_GET is set in @depot_flags, stack depot will increment * the refcount on the saved stack trace if it already exists in stack depot. + * Users of this flag must also call stack_depot_put() when keeping the stack + * trace is no longer required to avoid overflowing the refcount. * * If the provided stack trace comes from the interrupt context, only the part * up to the interrupt entry is saved. @@ -162,6 +164,18 @@ void stack_depot_print(depot_stack_handle_t stack); int stack_depot_snprint(depot_stack_handle_t handle, char *buf, size_t size, int spaces); +/** + * stack_depot_put - Drop a reference to a stack trace from stack depot + * + * @handle: Stack depot handle returned from stack_depot_save() + * + * The stack trace is evicted from stack depot once all references to it have + * been dropped (once the number of stack_depot_evict() calls matches the + * number of stack_depot_save_flags() calls with STACK_DEPOT_FLAG_GET set for + * this stack trace). + */ +void stack_depot_put(depot_stack_handle_t handle); + /** * stack_depot_set_extra_bits - Set extra bits in a stack depot handle * diff --git a/lib/stackdepot.c b/lib/stackdepot.c index 278ed646e418..3a8f045696fd 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -404,6 +404,14 @@ static struct stack_record *depot_fetch_stack(depot_stack_handle_t handle) return stack; } +/* Links stack into the freelist. */ +static void depot_free_stack(struct stack_record *stack) +{ + lockdep_assert_held_write(&pool_rwlock); + + list_add(&stack->list, &free_stacks); +} + /* Calculates the hash for a stack. */ static inline u32 hash_stack(unsigned long *entries, unsigned int size) { @@ -586,6 +594,33 @@ unsigned int stack_depot_fetch(depot_stack_handle_t handle, } EXPORT_SYMBOL_GPL(stack_depot_fetch); +void stack_depot_put(depot_stack_handle_t handle) +{ + struct stack_record *stack; + unsigned long flags; + + if (!handle || stack_depot_disabled) + return; + + write_lock_irqsave(&pool_rwlock, flags); + + stack = depot_fetch_stack(handle); + if (WARN_ON(!stack)) + goto out; + + if (refcount_dec_and_test(&stack->count)) { + /* Unlink stack from the hash table. */ + list_del(&stack->list); + + /* Free stack. */ + depot_free_stack(stack); + } + +out: + write_unlock_irqrestore(&pool_rwlock, flags); +} +EXPORT_SYMBOL_GPL(stack_depot_put); + void stack_depot_print(depot_stack_handle_t stack) { unsigned long *entries;