Received: by 2002:ab2:7903:0:b0:1fb:b500:807b with SMTP id a3csp271244lqj; Sat, 1 Jun 2024 19:40:50 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCX9VdFYpBD/JLF9tw9cN/0HBJfjuF5Yg8+H3IkCo+98zZ+oNKh3dpSviNM7PX0OBNiUmRT54uGCuicDRc0eM0gE94iQgT2Da0VhbZ7lzw== X-Google-Smtp-Source: AGHT+IG9+mPIKx4N3Atc/APRA/qxE70gvEr999ieBmZ8AJWGq1TkL73pP6q3aIKfJPLWeo2h1Eo7 X-Received: by 2002:a67:e2cd:0:b0:48b:8f32:825e with SMTP id ada2fe7eead31-48bc23466b6mr6141890137.22.1717296049911; Sat, 01 Jun 2024 19:40:49 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1717296049; cv=pass; d=google.com; s=arc-20160816; b=Uh3vIYz94CZwDV+zmoETgfkgGcFN1oN+fqwhHvJLP8zTmpK5Jm86fv1Sy62IMy+3jm AQMprYZiImt906wyGWAaZ6hK5usWMjHL6rhkkjybZ4qhKX15kW53m3clqEvX94kxZsjQ K+5OG/ZaHFoc5E6LQ5p9fvGBsqxvvlGcE0YUrrdQ1VrhPEKobIcU1hMY4N+VPqfw6Jaw TLRQ/ONHGQbCQOOABxZeNwvPK+MmS/XpW9sPmFPHXKMvgr3ccjjrFEd4gAN+LbWsVoCG rQDMq9LPzP0sxT70AFxVIJ8eFAsE3dHirr84q5wKbrJF0eEkL/y0OuBFFWC2Vy2TKQMN s5Gg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :subject:cc:to:from:date:dkim-signature; bh=MPQqqWX/oqHXbvgq8KDQSFUvREqV2cAaQsIqfnpfuFQ=; fh=NSnYj6tpGinFvTJElM5X+45jOrnS9GbogdcRlOg2Gnw=; b=0EmL6HYQMIKj1T5iNRXeDydOigLdykipwAOWaSxSm58SHz9GvBXwwznHd4wS87K84j YBtIFmRdPbZX+hXG1JOsVXsZgfjmohHGtdK/c05OUToD80Zkd+wF66IhzPuurWGc7pdk hpDrXbZa2kUy+DM1Q0/5HL9wA/pvqRYZZfDwgG66q6iSpD4SjDXKnn05sp1MtPhWy7wz Izh6Sl6r5UeFKD7pJILKrpALcvZVZapKoACo9QV712QaGHIPmXLXo7YXJkeYd/lvTuYh HxVjbPwfOOWjNrNcYKqGR7oXwQ+L3y+IdMt6QZ5oZO0j1Owg3g862BThJ2BE7+TLcy/Q +EmA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=jMastWbO; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-198073-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-198073-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id d75a77b69052e-43ff257efffsi56140531cf.486.2024.06.01.19.40.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Jun 2024 19:40:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-198073-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=jMastWbO; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-198073-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-198073-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 883021C20AF4 for ; Sun, 2 Jun 2024 02:40:49 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D3F28749C; Sun, 2 Jun 2024 02:40:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jMastWbO" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B7A6329AB; Sun, 2 Jun 2024 02:40:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717296038; cv=none; b=W4XE3Lv0i7gEjVdKvTVk1km9JDfCijGjZtBLZYXfMSEkWa1nUwk3J29E2rNCCEV7QZh6SLU32qbRVNk6WPnnny40qwR9bu/G0cIDaE3YKcZmp0gBgKVPble4JpMnsQbDbaKmAM9SX0U9MHqj16us2luQx8i2r/4Zjn/asluaiUo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717296038; c=relaxed/simple; bh=HjXslGwuZEP5SHfHzgJFnxRlmo7xENWL4U5sjQfH5QU=; h=Date:From:To:Cc:Subject:Message-Id:In-Reply-To:References: Mime-Version:Content-Type; b=XAoaoI+vuv0dSXUfae46RoW4Ckx+gKtL+79tDEdeLXSq8P6FmFDV8fN/7+o6wLIlWWpfVPdJ56zTCoe/0C6GTtf+gqK4K6xGLLFh0gCQmFVYWjF6riqu3lPPsNxHmvpijLXVeA0psHP+p492VsOk/u2isfG9psXMq3dO7WtQpLw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jMastWbO; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 38557C116B1; Sun, 2 Jun 2024 02:40:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717296038; bh=HjXslGwuZEP5SHfHzgJFnxRlmo7xENWL4U5sjQfH5QU=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=jMastWbORhu1JcTSXlVOWPzVOl4um/E/VS1GKZjzGBPBfaBXJH9DyYUVulcADig52 BSoQKU5dojVdVJLVJGTCD8u0GrmCcXsszmqFq3DMAOzydwq6X3UeBDUvPhj+onh2qt R4e+ZsqmYwGfz+P8MIU9/k2p5yyeOfQlTHWhbx5kqsE/KoNcbCxRyoTSGI93xZTKx6 G11dH9UPCLERhwk6Yv5QknfyXD0lZ6UzLmGY3LExi8yMIE0Vi3gCHNH8UyOpK1GIu8 cthpvELaWbq2wS6VAEZAoRhThwPsdgMI5/1AvgqcWMZKU0kXOEC6L317ftuDekyvif 57XP0qjE3yN4g== Date: Sun, 2 Jun 2024 11:40:32 +0900 From: Masami Hiramatsu (Google) To: Steven Rostedt Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, Mark Rutland , Mathieu Desnoyers , Andrew Morton , Alexei Starovoitov , Florent Revest , Martin KaFai Lau , bpf , Sven Schnelle , Alexei Starovoitov , Jiri Olsa , Arnaldo Carvalho de Melo , Daniel Borkmann , Alan Maguire , Peter Zijlstra , Thomas Gleixner , Guo Ren Subject: Re: [PATCH 10/20] function_graph: Have the instances use their own ftrace_ops for filtering Message-Id: <20240602114032.fefbbbfdc8e743b3a148a919@kernel.org> In-Reply-To: <20240531184910.799635e8@rorschach.local.home> References: <20240525023652.903909489@goodmis.org> <20240525023742.786834257@goodmis.org> <20240530223057.21c2a779@rorschach.local.home> <20240531121241.c586189caad8d31d597f614d@kernel.org> <20240531020346.6c13e2d4@rorschach.local.home> <20240531235023.a0b2b207362eba2f8b5c16f7@kernel.org> <20240531184910.799635e8@rorschach.local.home> X-Mailer: Sylpheed 3.7.0 (GTK+ 2.24.33; x86_64-pc-linux-gnu) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Fri, 31 May 2024 18:49:10 -0400 Steven Rostedt wrote: > On Fri, 31 May 2024 23:50:23 +0900 > Masami Hiramatsu (Google) wrote: > > > So is it similar to the fprobe/kprobe, use shared signle ftrace_ops, > > but keep each fgraph has own hash table? > > Sort of. > > I created helper functions in ftrace that lets you have a "manager > ftrace_ops" that will be used to assign to ftrace (with the function > that will demultiplex), and then you can have "subops" that can be > assigned that is per user. Here's a glimpse of the code: > > /** > * ftrace_startup_subops - enable tracing for subops of an ops > * @ops: Manager ops (used to pick all the functions of its subops) > * @subops: A new ops to add to @ops > * @command: Extra commands to use to enable tracing > * > * The @ops is a manager @ops that has the filter that includes all the functions > * that its list of subops are tracing. Adding a new @subops will add the > * functions of @subops to @ops. > */ > int ftrace_startup_subops(struct ftrace_ops *ops, struct ftrace_ops *subops, int command) > { > struct ftrace_hash *filter_hash; > struct ftrace_hash *notrace_hash; > struct ftrace_hash *save_filter_hash; > struct ftrace_hash *save_notrace_hash; > int size_bits; > int ret; > > if (unlikely(ftrace_disabled)) > return -ENODEV; > > ftrace_ops_init(ops); > ftrace_ops_init(subops); > > /* Make everything canonical (Just in case!) */ > if (!ops->func_hash->filter_hash) > ops->func_hash->filter_hash = EMPTY_HASH; > if (!ops->func_hash->notrace_hash) > ops->func_hash->notrace_hash = EMPTY_HASH; > if (!subops->func_hash->filter_hash) > subops->func_hash->filter_hash = EMPTY_HASH; > if (!subops->func_hash->notrace_hash) > subops->func_hash->notrace_hash = EMPTY_HASH; > > /* For the first subops to ops just enable it normally */ > if (list_empty(&ops->subop_list)) { May above ftrace_ops_init() clear this list up always? > /* Just use the subops hashes */ > filter_hash = copy_hash(subops->func_hash->filter_hash); > notrace_hash = copy_hash(subops->func_hash->notrace_hash); > if (!filter_hash || !notrace_hash) { > free_ftrace_hash(filter_hash); > free_ftrace_hash(notrace_hash); > return -ENOMEM; > } > > save_filter_hash = ops->func_hash->filter_hash; > save_notrace_hash = ops->func_hash->notrace_hash; > > ops->func_hash->filter_hash = filter_hash; > ops->func_hash->notrace_hash = notrace_hash; > list_add(&subops->list, &ops->subop_list); > ret = ftrace_startup(ops, command); > if (ret < 0) { > list_del(&subops->list); > ops->func_hash->filter_hash = save_filter_hash; > ops->func_hash->notrace_hash = save_notrace_hash; > free_ftrace_hash(filter_hash); > free_ftrace_hash(notrace_hash); > } else { > free_ftrace_hash(save_filter_hash); > free_ftrace_hash(save_notrace_hash); > subops->flags |= FTRACE_OPS_FL_ENABLED; > } > return ret; > } > > /* > * Here there's already something attached. Here are the rules: > * o If either filter_hash is empty then the final stays empty > * o Otherwise, the final is a superset of both hashes > * o If either notrace_hash is empty then the final stays empty > * o Otherwise, the final is an intersection between the hashes Yeah, filter_hash |= subops_filter_hash and notrace_hash &= subops_notrace_hash. The complicated point is filter's EMPTY_HASH means FULLSET_HASH. :) > */ > if (ops->func_hash->filter_hash == EMPTY_HASH || > subops->func_hash->filter_hash == EMPTY_HASH) { > filter_hash = EMPTY_HASH; > } else { > size_bits = max(ops->func_hash->filter_hash->size_bits, > subops->func_hash->filter_hash->size_bits); Don't we need to expand the size_bits? In the worst case, both hash does not share any entry, then it should be expanded. > filter_hash = alloc_and_copy_ftrace_hash(size_bits, ops->func_hash->filter_hash); > if (!filter_hash) > return -ENOMEM; > ret = append_hash(&filter_hash, subops->func_hash->filter_hash); > if (ret < 0) { > free_ftrace_hash(filter_hash); > return ret; > } > } > > if (ops->func_hash->notrace_hash == EMPTY_HASH || > subops->func_hash->notrace_hash == EMPTY_HASH) { > notrace_hash = EMPTY_HASH; > } else { > size_bits = max(ops->func_hash->filter_hash->size_bits, > subops->func_hash->filter_hash->size_bits); > notrace_hash = alloc_ftrace_hash(size_bits); > if (!notrace_hash) { > free_ftrace_hash(filter_hash); > return -ENOMEM; > } > > ret = intersect_hash(¬race_hash, ops->func_hash->filter_hash, > subops->func_hash->filter_hash); > if (ret < 0) { > free_ftrace_hash(filter_hash); > free_ftrace_hash(notrace_hash); > return ret; > } > } > > list_add(&subops->list, &ops->subop_list); > > ret = ftrace_update_ops(ops, filter_hash, notrace_hash); > free_ftrace_hash(filter_hash); > free_ftrace_hash(notrace_hash); > if (ret < 0) > list_del(&subops->list); > return ret; > } > > /** > * ftrace_shutdown_subops - Remove a subops from a manager ops > * @ops: A manager ops to remove @subops from > * @subops: The subops to remove from @ops > * @command: Any extra command flags to add to modifying the text > * > * Removes the functions being traced by the @subops from @ops. Note, it > * will not affect functions that are being traced by other subops that > * still exist in @ops. > * > * If the last subops is removed from @ops, then @ops is shutdown normally. > */ > int ftrace_shutdown_subops(struct ftrace_ops *ops, struct ftrace_ops *subops, int command) > { > struct ftrace_hash *filter_hash; > struct ftrace_hash *notrace_hash; > int ret; > > if (unlikely(ftrace_disabled)) > return -ENODEV; > > list_del(&subops->list); > > if (list_empty(&ops->subop_list)) { > /* Last one, just disable the current ops */ > > ret = ftrace_shutdown(ops, command); > if (ret < 0) { > list_add(&subops->list, &ops->subop_list); > return ret; > } > > subops->flags &= ~FTRACE_OPS_FL_ENABLED; > > free_ftrace_hash(ops->func_hash->filter_hash); > free_ftrace_hash(ops->func_hash->notrace_hash); > ops->func_hash->filter_hash = EMPTY_HASH; > ops->func_hash->notrace_hash = EMPTY_HASH; > > return 0; > } > > /* Rebuild the hashes without subops */ > filter_hash = append_hashes(ops); > notrace_hash = intersect_hashes(ops); > if (!filter_hash || !notrace_hash) { > free_ftrace_hash(filter_hash); > free_ftrace_hash(notrace_hash); > list_add(&subops->list, &ops->subop_list); > return -ENOMEM; > } > > ret = ftrace_update_ops(ops, filter_hash, notrace_hash); > if (ret < 0) > list_add(&subops->list, &ops->subop_list); > free_ftrace_hash(filter_hash); > free_ftrace_hash(notrace_hash); > return ret; > } OK, so if the list_is_singlar(ops->subop_list), ftrace_graph_enter_ops() is called and if not, ftrace_graph_enter() is called, right? Thank you, > > > > > > > This removes the need to touch the architecture code. It can also be > > > used by fprobes to handle the attachments to functions for several > > > different sets of callbacks. > > > > > > I'll send out patches soon. > > > > OK, I'll wait for that. > > I'm just cleaning it up. I'll post it tomorrow (your today). > > -- Steve -- Masami Hiramatsu (Google)