From patchwork Wed Sep 13 17:14:41 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: 139188 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp30085vqi; Wed, 13 Sep 2023 17:51:41 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEPXCdEiJXuek6Q2BivV9BAZCvW3Z9p60J29bs48RgbJzte8sCkpzM1qQmCsoMXpJ2eeOe6 X-Received: by 2002:a17:902:7446:b0:1bc:9794:22ef with SMTP id e6-20020a170902744600b001bc979422efmr3952991plt.1.1694652701448; Wed, 13 Sep 2023 17:51:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694652701; cv=none; d=google.com; s=arc-20160816; b=JjOnRuAT27Yhbd2/GiNgv2YhZ+MSYXcMgwulgrhisRcSvB2HrNUmkqM/D1alclvbLi Fwzo7E7WE8JUwX/F6ivgG82LbL4bm1cAEc+wO0c3jQxAC5mc8kge6jZTeKb6fMkgAFfK eMRpYxt7/KGkZ5EWxDT0HaJeO0b9o2YqZduH6sSt2bUkFSvbhzXnqotfeDFUN53Nl451 eLFFIGNYScdGZ+tHGstHuhYq7v2uvMj16SAZ9KD09XOX8bAlYALpfsV4y0dOy7zMZUqC QJHnDuhVDpz7LJfd2d6pUIoxlcWJ2bLjemZ8qmutxztbD8+1xnvSOhh0ge1QAlT0vPjS fHqQ== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=AuXPIx9M1sa3aovsp0XdlaM599Z45TGxV3EusWHlaB4=; fh=nfQSbTp1dWHt2Ier1Up8UhVNdXOqoJJLNvTrpT3jJEk=; b=VBatGnqIJAzMLaXpi1K3Ba6TgUA7lC+VTswGZqMpKuv4ermDiBdnWrZhZgGOP8PiX0 4nbv8IEht75a5UJOhUpzhC3Eqsjss6e9utquBAQuyIiAQL9YtB0ux71MJiqUNN8jDCxN LLiXj4CeCNG5HJk20no68P7jI9mToL7J1D1SGlsSoahgAzV95Dv5uExFTVhruUjyhA7v CZ8jMNN+OJGSXHIITYojN0baYo7kGpkwloXdgBDMWcDGKwX548bstRZX1FuVaY4oK4QA 0xcEQ1B7JokB81o7SUs57o2LaMtIxsNJU5wlZDR0iKzi1yB47/hAJx3Laee/7uJRJ1L0 WrlQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=F2Ii6+s+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from howler.vger.email (howler.vger.email. [2620:137:e000::3:4]) by mx.google.com with ESMTPS id h8-20020a170902f54800b001b8a2774d60si505135plf.486.2023.09.13.17.51.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Sep 2023 17:51:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) client-ip=2620:137:e000::3:4; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=F2Ii6+s+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id 7096C823367F; Wed, 13 Sep 2023 10:17:39 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230451AbjIMRRi (ORCPT + 34 others); Wed, 13 Sep 2023 13:17:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231577AbjIMRRO (ORCPT ); Wed, 13 Sep 2023 13:17:14 -0400 Received: from out-220.mta1.migadu.com (out-220.mta1.migadu.com [IPv6:2001:41d0:203:375::dc]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C95EA213F for ; Wed, 13 Sep 2023 10:17:03 -0700 (PDT) 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=1694625422; 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=AuXPIx9M1sa3aovsp0XdlaM599Z45TGxV3EusWHlaB4=; b=F2Ii6+s+cdiC4H7z0xYGquHm32HzsvJdDEssh13Gmfxh6dgxf0ImSZW90i2I0Ul8XHXFZN EabRGGiqHKx8/fjEiRgDu0SjJmNsgtQaiOLP1FFmQ02FkMsAmcJU65Zs5fSzoSf3rveOpt b+/xe3k7MacpwOlBvRZDIYPeX/d3pF0= 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 v2 16/19] lib/stackdepot: allow users to evict stack traces Date: Wed, 13 Sep 2023 19:14:41 +0200 Message-Id: <1a3ea1e6b82f95eea644875756e12daba6c4cc7f.1694625260.git.andreyknvl@google.com> In-Reply-To: References: MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Wed, 13 Sep 2023 10:17:39 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776972151120190874 X-GMAIL-MSGID: 1776972151120190874 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 e2c622054265..56f2abc03717 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -398,6 +398,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) { @@ -580,6 +588,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;