From patchwork Tue May 11 18:50:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Cromie X-Patchwork-Id: 12251829 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.5 required=3.0 tests=BAYES_00,DIET_1, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD036C433B4 for ; Tue, 11 May 2021 18:51:22 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 57B636100A for ; Tue, 11 May 2021 18:51:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 57B636100A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id A30586B006E; Tue, 11 May 2021 14:51:21 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 9DEF06B0070; Tue, 11 May 2021 14:51:21 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 87EB06B0072; Tue, 11 May 2021 14:51:21 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0199.hostedemail.com [216.40.44.199]) by kanga.kvack.org (Postfix) with ESMTP id 6C0E06B006E for ; Tue, 11 May 2021 14:51:21 -0400 (EDT) Received: from smtpin28.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id 2947A8249980 for ; Tue, 11 May 2021 18:51:21 +0000 (UTC) X-FDA: 78129843162.28.58DF14F Received: from mail-io1-f41.google.com (mail-io1-f41.google.com [209.85.166.41]) by imf17.hostedemail.com (Postfix) with ESMTP id 725BA407F8ED for ; Tue, 11 May 2021 18:51:15 +0000 (UTC) Received: by mail-io1-f41.google.com with SMTP id k16so5078562ios.10 for ; Tue, 11 May 2021 11:51:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=0kvh7bXSwE3N9sBZlQxAqu55ei7RwBEem3VOTVc0Iss=; b=jaarEJDxlhCURQHFlH3RO2MA6QZh1xFAn7DbgFRE7T/hJ+kg3bhjDUhiAhsubFe0Q4 jOw407r/gavRLAz3C2VfsO9HgRyjZCXtkGwyyQI1GzWNbUGN1acYn6aru+Ud3CqCaoup 7s2ves+ERil4W00iezhd7i7j6Fd4qkboXl2TfEijCHBmM4bYexRnUqHQdfelhRBV8nS2 BJZDR3WZnzPDDW0EXalinNPiHcs0W+tp7ldIMsTBp91x1gG2GZmhnWZyfaYCTwxY/s76 hZmNsW5d137xWVRJ9vitLgMib6iY/fJYhNZQLflmkFLd/u9lFKbrJlv/P0fhd2EhzimO eQCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=0kvh7bXSwE3N9sBZlQxAqu55ei7RwBEem3VOTVc0Iss=; b=eAGdwaIXyuSznck0KSuFMTk1Fmj8mB/tg1bSUxGrVBkwFUcJHMj8H1Vj9ZdyHMtCYw Ori/0x0GsPeB567TboG3O4WOKTye70z/T0ulYPKGweZdQhjHmbGb93F7fSrlrm7vra/x 3LPzGYI8/vF0yQRb3mVd4icJrlrMq0fNFISaJLI+Konk7dqi56KzztzIrg0yZSVm4KWR Dy/P7+R1kxjCebdsewED7kD/cPUxan9PmTXM0xgRl/xlOdKebTO+Qvvih41H0jcKbBNw C9L4UsfSB6sYupX3Q966bHWP/JXcaTL6FQ0gNI/4rksIXRr0TYA8t3j7+6XmdDgE5LzT /lBA== X-Gm-Message-State: AOAM533WFfspQduUdc5rGEI03ESZ6mjC3uxvHe90hYzRZSiRZhpUxPRv DUAkzkH+WqN+AupWNSbF6A8GIctnXXbIig== X-Google-Smtp-Source: ABdhPJwt6kpFWrF+gtORQAvB6CqRuLre3tW4cpy2s+2UVlOOXKdF4thPy/jof42DeBCZzi1WYhGHWg== X-Received: by 2002:a05:6602:2596:: with SMTP id p22mr1765071ioo.184.1620759079584; Tue, 11 May 2021 11:51:19 -0700 (PDT) Received: from frodo.mearth (c-24-9-77-57.hsd1.co.comcast.net. [24.9.77.57]) by smtp.googlemail.com with ESMTPSA id t10sm405096ils.36.2021.05.11.11.51.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 May 2021 11:51:19 -0700 (PDT) From: Jim Cromie To: Cc: linux-mm@kvack.org, Jim Cromie Subject: [RFC PATCH v5 00/28] dynamic debug diet plan Date: Tue, 11 May 2021 12:50:29 -0600 Message-Id: <20210511185057.3815777-1-jim.cromie@gmail.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 Authentication-Results: imf17.hostedemail.com; dkim=pass header.d=gmail.com header.s=20161025 header.b=jaarEJDx; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf17.hostedemail.com: domain of jimcromie@gmail.com designates 209.85.166.41 as permitted sender) smtp.mailfrom=jimcromie@gmail.com X-Rspamd-Server: rspam05 X-Rspamd-Queue-Id: 725BA407F8ED X-Stat-Signature: qpfusaz433145b8g9byamc99zc6oszws Received-SPF: none (gmail.com>: No applicable sender policy available) receiver=imf17; identity=mailfrom; envelope-from=""; helo=mail-io1-f41.google.com; client-ip=209.85.166.41 X-HE-DKIM-Result: pass/pass X-HE-Tag: 1620759075-102354 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: DYNAMIC_DEBUG has extra weight/memory in its data table/section; its (module,filename,function) columns have ordered, repeating data (90%,55%,45%), and is highly compressible (~110/300) with simple RLE. On my i7 laptop, the compressible chunk is ~70kb, This patchset prepares for compression, but doesn't try it; RFC. Using that RLE compression estimate, we could save ~45kb; Id hope for better with ZSTD. Series Overview: 1st, split the struct _ddebug & __dyndbg elf section into 2, moving compressible fields into their own section/array/block. A temporary site pointer connects the 2 halves of the composite callsite, it will be obsoleted later, after we verify our replacement against it, we can drop the .site pointer. table change: from: [ key,mod,func,filenm,fmt,ln,flg ] into: [ key,fmt,ln,flg,site-> ] [ mod,func,filenm ] 2nd, make the 'site' data optional. The "module:function:line" log-message prefix is fundamentally an optional decoration, if we can do without it, we simplify codepath, and we could drop the storage in those cases, possibly reducing memory footprint. into: [ key,fmt,ln,flg,site->? ] 0 Then things get more interesting: 3rd, make kernel/module handle "__dyndbg_sites" ELF section (which was added in 1) as is already done for "__dyndbg". Hide/replace ->site with site_get/_put api this will let us retrieve site info from compressed storage. Add _index. gives us the fixed offset from __dyndbg[N] to __dyndbg[0]. into: [ key,fmt,ln,flg,_index,site->? ] 0 Add table/header record-pair. These 2 records are created into ".gnu.linkonce.dyndbg*" sections. The linker script places these 2 sections in front of their respective "__dyndbg*" sections. So this header-pair becomes __dyndbg[0], __dyndbg_sites[0]. we can use __dyndbg[0]->site[N] to get the site info. module.lds.h - insert ".gnu.linkonce.dyndbg*" sections into "__dyndbg*". Without this, headers arent part of the sections that kernel/module loads. validate ddebug_site_get() invariants. prove that our indirection to ->site[N] is correct. BUG_ON uses survived 0-day tests. they go away with !SITE_CHK into: 0: [ ...,_index,site-> ] ---> 0:[ ... ] ^ ..N: [ key,fmt,ln,flg,_index ] N:[ ... ] specialize header from _ddebug, keep header.site, drop _ddebug.site RFC: needs refinement, better type choices? Status: recent revs passed 0day compile grind, including BUG_ONs I got one KASAN report, quick reproduction failed, none more recently memory footprint is same as master. Whats Next ? Compression: RFC !!! POC: could compress during __init, decompress on-demand. Doing this would give something to decompress, to build out that code. ISTM Compression during build is best, but targets are unclear: initrd, initramfs, cpio, FW-blob all seem suitable at some level, but so does (ro) zram & zswap. How should I think about this ? Also, I understand that support exists for compressed elf sections, I dunno if/how kernel uses it currently, which would considerably ease this. Builtin __dyndbg_site data is in .data, probably needs to be moved to a separate elf section to get generic tool support for compressed sections. It would be nice if a compressed "__dyndbg_sites" elf section could be loaded by unchanged kernel/module.c. A magic number in the attached memory block could distinguish it from the current elf block. There is room in the 2 header records for new private data; we could store decompression contexts there while iterating thru a block. Decompression - a few use-cases: = for builtins, each loadable module: 1- stream, for `cat control` etc. these are 1 visit and forget 2- `module foo +mfp > control` - enable contiguous blocks w decorations 3- pr_debug - semi-random access - by (ptr - _index) [0-5k] for builtin pr-debugs, [0-20] for most loadable modules _index is 16 bit currently Simplest, minimum-memory strategy is late-fetch; to wait until a pr_debug is actually called, then check flags before fetching the site-rec, and save it to a hash on modname+_index (and delete on -p). Without the save, it works for (1) too. The only downside with late-fetch is that during pr_debug, a 1st fetch of site-info maybe cant come from io/zswap without locking/latency concerns. A forced-prefetch ala (2) with a new flag '!' could work around this, but might look like a wart. So thats it. I hope its clear and concise. Jim Cromie (28): trivial cleanup: dyndbg: avoid calling dyndbg_emit_prefix when it has no work dyndbg: drop uninformative vpr_info split to 2 vectors of callsite: dyndbg: split struct _ddebug's display fields to new _ddebug_site dyndbg: __init iterate over __dyndbg & __dyndbg_site in parallel make site info optional: dyndbg: refactor part of ddebug_change to ddebug_match_site dyndbg: accept null site in ddebug_match_site dyndbg: hoist ->site out of ddebug_match_site dyndbg: accept null site in ddebug_change dyndbg: accept null site in dynamic_emit_prefix dyndbg: accept null site in ddebug_proc_show dyndbg: refactor ddebug_alter_site out of ddebug_change dyndbg: allow deleting site info via control interface interesting: dyndbg+module: expose ddebug_sites to modules dyndbg: add ddebug_site(_get|_put) abstraction dyndbg: ddebug_add_module avoid adding empty modules dyndbg: add _index to struct _ddebug dyndbg: prevent build bugs via -DNO_DYNAMIC_DEBUG_TABLE dyndbg: RFC - DEFINE_DYNAMIC_DEBUG_TABLE dyndbg: RFC handle __dyndbg* sections in module.lds.h dyndbg: ddebug_add_module() handle headers. dyndbg: validate ddebug_site_get invariants dyndbg: fix NULL deref after deleting sites dyndbg: dont show header records in control dyndbg: make site pointer and checks on it optional (not quite) dyndbg: swap WARN_ON for BUG_ON see what 0-day says dyndbg: fixup protect header when deleting site dyndbg: unionize _ddebug*_headers with struct _ddebug* dyndbg: drop _ddebug.site pointer arch/arm/boot/compressed/Makefile | 2 + arch/sparc/vdso/Makefile | 2 + arch/x86/boot/compressed/Makefile | 1 + arch/x86/entry/vdso/Makefile | 3 + arch/x86/purgatory/Makefile | 1 + drivers/firmware/efi/libstub/Makefile | 3 +- include/asm-generic/module.lds.h | 12 +- include/asm-generic/vmlinux.lds.h | 24 +- include/linux/dynamic_debug.h | 135 ++++++++-- kernel/module-internal.h | 1 + kernel/module.c | 9 +- lib/dynamic_debug.c | 363 +++++++++++++++++++------- 12 files changed, 437 insertions(+), 119 deletions(-)