From nobody Tue Jul 28 19:29:26 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4h8ls32VlBz6n9m9 for ; Tue, 28 Jul 2026 19:29:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4h8ls25MLCz43s9 for ; Tue, 28 Jul 2026 19:29:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785266966; h=from:from: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; bh=NMhFDtpivUkJ+OvLB/zwiB+QEc0Wsxpy4uatflKioAk=; b=GX2HezMAXRiJQrskGflyGWkkwHSHXI4/Uwtrsa821nEqUwCqUkBYRSIfmnrcgN5iP/p6Lg g8llT0kDhG2tEJRtTpDkGUVraUflVVcUKEozbLNp/9FvW/6XHW3NSrL7llC3tmptYTDwR9 6dB3X+ekOqd+1jBu4UuxXuReOUXtNzr2Ml32zPgvEFmi9IsgsBfYiVOMiUE5L3B9OYYDqx LwesVjuogD/1HwclwI1eXZNdevhAht0zQn9oHttnGZKCqmTtytjcxFDPTYeTyeFevFB4VB Hz6CuPF2v5Ymham1vGtabPhjQTazA+QfPhmuKOq5ODAZyYLn6U4RvQoIb1kolQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785266966; a=rsa-sha256; cv=none; b=JvEA/fWGtbStND7I3ws/rAToSvx3wCL3rZocUn+C3wyGBYJuEjFVQpXz8tS7zTgfa+NVA7 V8RXMEgJfnPy/OpOfEW+TYyQUJg2a1mPQFFC81lBO/25TKJiTGotmypOpk2zg1YF0GHPL9 WPticBWHX+bJk7JzM5BtrvLULUTKEo2vqvwT9v8pODKwHZYUXX2gcxEoU6e/VCadrh/xDO 5tfPz/ltFwmob3Ln2wEGfmEn31mMrH3nESlKe3W+7iSj3knf9c7ZgzG/IuBrUSRwJl0Zv5 Y9asFxg/MtY1IznKFpgDhVLLZTUh0+HnWE/2S/Q77Apvdzlkrhs4OzsnkHN2pA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785266966; h=from:from: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; bh=NMhFDtpivUkJ+OvLB/zwiB+QEc0Wsxpy4uatflKioAk=; b=IqMOI+P6qRM7Y44izC5ypv/ezIsjjakiDTjHagfvcNxjdGQWRMqnrRdXpCFJKFp53bLaZz klVteR24RK0UYq4nwW9xAwt42SyVUptKfrjuv7le9/Jj7DOgcIpp0vgGSjumVZma4/pwhP gpYGDYH2db98Du/HIJ4ZmwxMnziHGPsRGcmRPo+StcjApOTQXMh/fSK5h/rPbTjYp442e3 dGaxyfAf1K9ayLytiIQjtKXbcc7fYwktayZxf6eRrw9nr4IiZsnYfkfsfDZ71DyT+iivcO RwsBikvIdiJ/b2wz8NEwypossl70EDg+g5/QMuAGcYNzz6L9e8I3hmR9zm7+nw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h8ls23XDxzsdM for ; Tue, 28 Jul 2026 19:29:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 43c88 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 28 Jul 2026 19:29:26 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Ali Mashtizadeh From: Warner Losh Subject: git: cc94d1bd7414 - main - pmc: pmc frontend stall analysis based on IBS List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: cc94d1bd7414b309a62a379a8e614e3a3f9cd6d9 Auto-Submitted: auto-generated Date: Tue, 28 Jul 2026 19:29:26 +0000 Message-Id: <6a690316.43c88.4582d0dc@gitrepo.freebsd.org> The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=cc94d1bd7414b309a62a379a8e614e3a3f9cd6d9 commit cc94d1bd7414b309a62a379a8e614e3a3f9cd6d9 Author: Ali Mashtizadeh AuthorDate: 2026-07-28 17:46:48 +0000 Commit: Warner Losh CommitDate: 2026-07-28 19:27:45 +0000 pmc: pmc frontend stall analysis based on IBS The frontend command uses AMD IBS frontend events to analyze the major sources of frontend stalls. It displays a table breakind down the major causes of front end stalls. This is a simple demonstration of the tools as you can use the filtering tools to limit the analysis to a subset of the samples including filtering by fetch latencies. Sponsored by: Netflix Reviewed by: adrian, imp Differential Revision: https://reviews.freebsd.org/D57779 --- usr.sbin/pmc/cmd_pmc_frontend.cc | 242 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) diff --git a/usr.sbin/pmc/cmd_pmc_frontend.cc b/usr.sbin/pmc/cmd_pmc_frontend.cc new file mode 100644 index 000000000000..18ffd607bf21 --- /dev/null +++ b/usr.sbin/pmc/cmd_pmc_frontend.cc @@ -0,0 +1,242 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026, Netflix, Inc. + * + * This software was developed by Ali Mashtizadeh under the sponsorship from + * Netflix, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "cmd_pmc.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "display.hh" +#include "view.hh" + +struct frontend { + syminfo func; + int64_t ocmiss; + int64_t l2miss; + int64_t l3miss; + int64_t l1tlbmiss; + int64_t l2tlbmiss; + int64_t latency; + int64_t samples; +}; + +static int sortcol = 2; + +class frontend_view : public pmcview +{ +public: + frontend_view() : pmcview(), samples() { } + ~frontend_view() { } + + virtual void + callchain(struct pmclog_ev_callchain &p, + ibsfetchinfo &f, __unused uintfptr_t *cc, __unused int len) + { + int usermode = PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(p.pl_cpuflags); + + /* Ignore zeros */ + if (IBS_FETCH_CTL_TO_LAT(f.ctl) == 0) + return; + + auto inst = samples.find(f.linaddr); + if (inst == samples.end()) { + syminfo sym = addrtosymbol(usermode ? p.pl_pid : 0, f.linaddr); + if (sym.name == "") + return; + + samples[f.linaddr] = frontend(); + inst = samples.find(f.linaddr); + inst->second.func = sym; + } + + /* + * Save fetch cache and TLB miss counts + */ + if (f.ctl & IBS_FETCH_CTL_OPCACHEMISS) + inst->second.ocmiss += 1; + if (f.ctl & IBS_FETCH_CTL_L2MISS) + inst->second.l2miss += 1; + if (f.ctl & IBS_FETCH_CTL_L3MISS) + inst->second.l3miss += 1; + + if (f.ctl & IBS_FETCH_CTL_L1TLBMISS) + inst->second.l1tlbmiss += 1; + if (f.ctl & IBS_FETCH_CTL_L2TLBMISS) + inst->second.l2tlbmiss += 1; + + inst->second.latency += IBS_FETCH_CTL_TO_LAT(f.ctl); + inst->second.samples += 1; + } + + virtual void + print() + { + title("IBS Frontend Analysis"); + + // Print header + table t = table(); + t.addcolumn("Image", true); + t.addcolumn("Function", true); + t.addcolumn("Latency"); + t.addcolumn("Samples"); + t.addcolumn("OC Miss"); + t.addcolumn("L2 Miss"); + t.addcolumn("L3 Miss"); + t.addcolumn("L1 TLB Miss"); + t.addcolumn("L2 TLB Miss"); + + for (auto &kv : samples) { + std::vector r; + + r.emplace_back(kv.second.func.binary); + r.emplace_back(kv.second.func.to_string()); + r.emplace_back(kv.second.latency); + r.emplace_back(kv.second.samples); + r.emplace_back(kv.second.ocmiss, kv.second.samples, true); + r.emplace_back(kv.second.l2miss, kv.second.samples, true); + r.emplace_back(kv.second.l3miss, kv.second.samples, true); + r.emplace_back(kv.second.l1tlbmiss, kv.second.samples, true); + r.emplace_back(kv.second.l2tlbmiss, kv.second.samples, true); + + t.addrow(r); + } + + t.sort(sortcol); + t.print(); + } +protected: + std::unordered_map samples; +}; + + +static struct option longopts[] = { + PMCFILTER_LOPTS, + { "sort", required_argument, NULL, 's' }, + { NULL, 0, NULL, 0 } +}; + +static void +usage(void) +{ + printf("Usage: pmc frontend [options] [pmclog]\n\n"); + printf("Analyze frontend bottlenecks\n\n"); + printf("Options:\n"); + printf("\t-s,--sort Sort by event\n\n"); + PMCFILTER_PRINTOPTS(); +} + +int +cmd_pmc_frontend(int argc, char **argv) +{ + pmcfilter filter = pmcfilter(); + const char *logfile = "default.log"; + int option, logfd; + + while ((option = getopt_long(argc, argv, PMCFILTER_SOPTS, longopts, NULL)) != -1) { + switch (option) { + PMCFILTER_CASE(filter) + case 's': + sortcol = atoi(optarg); + break; + case '?': + default: + usage(); + exit(EX_USAGE); + } + } + argc -= optind; + argv += optind; + if (argc != 0 && argc != 1) { + usage(); + exit(EX_USAGE); + } + if (argc == 1) + logfile = argv[0]; + + setup_screen(); + + if ((logfd = open(logfile, O_RDONLY)) < 0) { + errx(EX_OSERR, "ERROR: Cannot open \"%s\" for reading: %s.", logfile, + strerror(errno)); + } + + frontend_view v = frontend_view(); + v.setfilter(filter); + v.process(logfd); + v.print(); + + close(logfd); + + return (0); +}