Message ID | 20221106100316.2803176-1-chenguokai17@mails.ucas.ac.cn |
---|---|
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp1420840wru; Sun, 6 Nov 2022 02:06:07 -0800 (PST) X-Google-Smtp-Source: AMsMyM4y3nfDDRZRbVNkXQPmhL6eUqgpEcWlL1uldmFFaJUr1TiZYisXYb6eXZ/LIpYBYNBXG0wW X-Received: by 2002:a17:903:1105:b0:178:ae31:aad with SMTP id n5-20020a170903110500b00178ae310aadmr45171268plh.3.1667729167124; Sun, 06 Nov 2022 02:06:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1667729167; cv=none; d=google.com; s=arc-20160816; b=iszoZ3vnRTHOjiXLw6NjEz/ACZFnfEmxnAVjpr90a6b+eysHAyafUpKzL7UCuR+0Q+ 6aIQrG7rf9D1daJ5lqJ6WfxpKimntw1z94rLNOWB4MShZhRIQM/fwgXNhn7vESlDpykk HArMT+QidgAUmsJZEfVa6cn6rz2tvNkH8ZA5I/itlspDxCIKs1k9KnnSXTV/SSZco5Ru tvxHUbaZoLIrfVC5RO6o/If7t7jXDtwBzgfTcBOuev4WbrH6Eqp2Us+W+Yc3a2gCCVS1 jfElkd93Fj0I8kFt8iA6/cjKcEkueUURzXQy2aXRuUeqnk74aumJOI0VoxVNEzd83mVj FDzw== 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 :message-id:date:subject:cc:to:from; bh=+64vH1tKxC/MVio9E+274+vgTV/AIcsSwP32ehBQ6GA=; b=dbBLs0Bf+sWlU203u3Yvv9vgZ77/ylyo8Zbmj1hLw6kY+SMFmwFVsZsbpPjXB2A4FA gwMkCjXmX5oPb1yqhTuClRjcd3/XLEXnng0YfWK/Y9FpWpv9DLGwE4LhWEbHQFBi0Ggn UKzaPV0TXoIOZBIuVikqwGhTCL5EHOV8JBB/J4sO9zyNnOF1+svuy6DJuDf2Y5UZ355s rlHEpiSBlmyjIWbWwfnhsD594i+hEt9PW2dts3yL14A6ujoOjor2YUUprgnQhjTdJNpy YeKvD5CwzpUNmJlQdSqOx3x6NcZ5pUNTqBQGnQbw62Ocp5uwfk5VGwBXNwrz5ogYylUZ 3Ptw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w21-20020a634755000000b0045ce0eba520si6296046pgk.751.2022.11.06.02.05.53; Sun, 06 Nov 2022 02:06:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229903AbiKFKEO (ORCPT <rfc822;hjfbswb@gmail.com> + 99 others); Sun, 6 Nov 2022 05:04:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56132 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229829AbiKFKDz (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sun, 6 Nov 2022 05:03:55 -0500 Received: from cstnet.cn (smtp84.cstnet.cn [159.226.251.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 315F4E09E for <linux-kernel@vger.kernel.org>; Sun, 6 Nov 2022 02:03:50 -0800 (PST) Received: from cgk-Precision-3650-Tower.. (unknown [219.141.235.82]) by APP-05 (Coremail) with SMTP id zQCowACnrKByhmdj7bRnCA--.7053S4; Sun, 06 Nov 2022 18:03:31 +0800 (CST) From: Chen Guokai <chenguokai17@mails.ucas.ac.cn> To: paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, rostedt@goodmis.org, mingo@redhat.com, sfr@canb.auug.org.au Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, liaochang1@huawei.com, Liao Chang <liaoclark@163.com> Subject: [PATCH v4 0/8] Add OPTPROBES feature on RISCV Date: Sun, 6 Nov 2022 18:03:08 +0800 Message-Id: <20221106100316.2803176-1-chenguokai17@mails.ucas.ac.cn> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: zQCowACnrKByhmdj7bRnCA--.7053S4 X-Coremail-Antispam: 1UD129KBjvJXoWxXw18Zry7Zw1DWFyDZr43KFg_yoWrGr4UpF WkKw45JrWUAr4fCrW3Jr4kuFySkan5Gw43ur1UJ34rX3y3JryFy3ZagayUZF15GF4Y934j qrn09ryvkFy5A3DanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUvlb7Iv0xC_Kw4lb4IE77IF4wAFF20E14v26r4j6ryUM7CY07I2 0VC2zVCF04k26cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rw A2F7IY1VAKz4vEj48ve4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xII jxv20xvEc7CjxVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4 A2jsIEc7CjxVAFwI0_GcCE3s1lnxkEFVAIw20F6cxK64vIFxWle2I262IYc4CY6c8Ij28I cVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx 0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwAC I402YVCY1x02628vn2kIc2xKxwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJV W8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF 1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6x IIjxv20xvEc7CjxVAFwI0_Jr0_Gr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvE x4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvj DU0xZFpf9x07b52NNUUUUU= X-Originating-IP: [219.141.235.82] X-CM-SenderInfo: xfkh0w5xrntxyrx6ztxlovh3xfdvhtffof0/1tbiCgUCE2NnSRxR0wAAsN X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_PASS, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748740779332752104?= X-GMAIL-MSGID: =?utf-8?q?1748740779332752104?= |
Series |
Add OPTPROBES feature on RISCV
|
|
Message
Xim
Nov. 6, 2022, 10:03 a.m. UTC
From: Liao Chang <liaoclark@163.com> From: Liao Chang <liaochang1@huawei.com> Add jump optimization support for RISC-V. Replaces ebreak instructions used by normal kprobes with an auipc+jalr instruction pair, at the aim of suppressing the probe-hit overhead. All known optprobe-capable RISC architectures have been using a single jump or branch instructions while this patch chooses not. RISC-V has a quite limited jump range (4KB or 2MB) for both its branch and jump instructions, which prevent optimizations from supporting probes that spread all over the kernel. Auipc-jalr instruction pair is introduced with a much wider jump range (4GB), where auipc loads the upper 12 bits to a free register and jalr Deaconappends the lower 20 bits to form a 32 bit immediate. Note that returns from probe handler requires another free register. As kprobes can appear almost anywhere inside the kernel, the free register should be found in a generic way, not depending on calling convention or any other regulations. The algorithm for finding the free register is inspired by the register renaming in modern processors. From the perspective of register renaming, a register could be represented as two different registers if two neighbour instructions both write to it but no one ever reads. Extending this fact, a register is considered to be free if there is no read before its next write in the execution flow. We are free to change its value without interfering normal execution. Static analysis shows that 51% instructions of the kernel (default config) is capable of being replaced i.e. one free register can be found at both the start and end of replaced instruction pairs while the replaced instructions can be directly executed. Contribution: Chen Guokai invents the algorithm of searching free register, evaluate the ratio of optimizaion, the basic function support RVI kernel binary. Liao Chang adds the support for hybrid RVI and RVC kernel binary, fix some bugs with different kernel configure, refactor out entire feature into some individual patches. v4: Correct the sequence of Signed-off-by and Co-developed-by. v3: 1. Support of hybrid RVI and RVC kernel binary. 2. Refactor out entire feature into some individual patches. v2: 1. Adjust comments 2. Remove improper copyright 3. Clean up format issues that is no common practice 4. Extract common definition of instruction decoder 5. Fix race issue in SMP platform. v1: Chen Guokai contribute the basic functionality code. Liao Chang (8): riscv/kprobe: Prepare the skeleton to implement RISCV OPTPROBES feature riscv/kprobe: Allocate detour buffer from module area riscv/kprobe: Prepare the skeleton to prepare optimized kprobe riscv/kprobe: Add common RVI and RVC instruction decoder code riscv/kprobe: Search free register(s) to clobber for 'AUIPC/JALR' riscv/kprobe: Add code to check if kprobe can be optimized riscv/kprobe: Prepare detour buffer for optimized kprobe riscv/kprobe: Patch AUIPC/JALR pair to optimize kprobe arch/riscv/Kconfig | 1 + arch/riscv/include/asm/bug.h | 5 +- arch/riscv/include/asm/kprobes.h | 48 ++ arch/riscv/include/asm/patch.h | 1 + arch/riscv/kernel/patch.c | 22 +- arch/riscv/kernel/probes/Makefile | 1 + arch/riscv/kernel/probes/decode-insn.h | 145 ++++++ arch/riscv/kernel/probes/kprobes.c | 25 + arch/riscv/kernel/probes/opt.c | 602 ++++++++++++++++++++++ arch/riscv/kernel/probes/opt_trampoline.S | 137 +++++ arch/riscv/kernel/probes/simulate-insn.h | 41 ++ 11 files changed, 1023 insertions(+), 5 deletions(-) create mode 100644 arch/riscv/kernel/probes/opt.c create mode 100644 arch/riscv/kernel/probes/opt_trampoline.S
Comments
Chen Guokai <chenguokai17@mails.ucas.ac.cn> writes: > From: Liao Chang <liaoclark@163.com> > > From: Liao Chang <liaochang1@huawei.com> > > Add jump optimization support for RISC-V. Thanks for working on this! I have some comments on the series, but I'll do that on a per-patch basis. Have you run the series on real hardware, or just qemu? Cheers, Björn
Hi Björn, Thanks for your great review! Some explanations below. > 2022年11月8日 00:54,Björn Töpel <bjorn@kernel.org> 写道: > > Have you run the series on real hardware, or just qemu? Currently only qemu tests are made, I will try to test it on a FPGA real hardware soon. > AFAIU, the algorithm only tracks registers that are *in use*. You are > already scanning the whole function (next patch). What about the caller > saved registers that are *not* used by the function in the probe range? > Can those, potentially unused, regs be used? Great missing part! I have made a static analyzation right upon receiving this mail. The result shows that this newly purposed idea reaches about the same success rate on my test set (rv64 defconf with RVI only) while when combined, they can reach a higher success rate, 1/3 above their baseline. A patch that includes this strategy will be sent soon. > >> +static void arch_find_register(unsigned long start, unsigned long end, > > Nit; When I see "arch_" I think it's functionality that can be > overridden per-arch. This is not the case, but just a helper for RV. It can be explained from two aspects. First, it can be extended to most RISC archs, which can be extracted into the common flow of Kprobe. Second, it is indeed a internal helper for now, so I will correct the name in the next version. >> static void find_free_registers(struct kprobe *kp, struct optimized_kprobe *op, >> - int *rd1, int *rd2) >> + int *rd, int *ra) > > Nit; Please get rid of this code churn, just name the parameters > correctly on introduction in the previous patch. Will be fixed. >> + *rd = ((kw | ow) == 1UL) ? 0 : __builtin_ctzl((kw | ow) & ~1UL); >> + *ra = (kw == 1UL) ? 0 : __builtin_ctzl(kw & ~1UL); > > Hmm, __builtin_ctzl is undefined for 0, right? Can that be triggered > here? Will be fixed. Regards, Guokai Chen
在 2022/11/8 19:04, Xim 写道: > Hi Björn, > > Thanks for your great review! Some explanations below. > >> 2022年11月8日 00:54,Björn Töpel <bjorn@kernel.org> 写道: >> >> Have you run the series on real hardware, or just qemu? > > Currently only qemu tests are made, I will try to test it on a FPGA real hardware soon. > >> AFAIU, the algorithm only tracks registers that are *in use*. You are >> already scanning the whole function (next patch). What about the caller >> saved registers that are *not* used by the function in the probe range? >> Can those, potentially unused, regs be used? > > Great missing part! I have made a static analyzation right upon receiving this mail. > The result shows that this newly purposed idea reaches about the same > success rate on my test set (rv64 defconf with RVI only) while when combined, > they can reach a higher success rate, 1/3 above their baseline. A patch that > includes this strategy will be sent soon. >> >>> +static void arch_find_register(unsigned long start, unsigned long end, >> >> Nit; When I see "arch_" I think it's functionality that can be >> overridden per-arch. This is not the case, but just a helper for RV. > > It can be explained from two aspects. First, it can be extended to most RISC > archs, which can be extracted into the common flow of Kprobe. Second, it is indeed > a internal helper for now, so I will correct the name in the next version. > >>> static void find_free_registers(struct kprobe *kp, struct optimized_kprobe *op, >>> - int *rd1, int *rd2) >>> + int *rd, int *ra) >> >> Nit; Please get rid of this code churn, just name the parameters >> correctly on introduction in the previous patch. > > Will be fixed. > >>> + *rd = ((kw | ow) == 1UL) ? 0 : __builtin_ctzl((kw | ow) & ~1UL); >>> + *ra = (kw == 1UL) ? 0 : __builtin_ctzl(kw & ~1UL); >> >> Hmm, __builtin_ctzl is undefined for 0, right? Can that be triggered >> here? This corner case has been taken into account, look these condition parts, if kw == 1UL this expression will return 0 directly, no chance to invoke __builtin_ctzl. Thanks. > > Will be fixed. > > Regards, > Guokai Chen >
"liaochang (A)" <liaochang1@huawei.com> writes: >>>> + *rd = ((kw | ow) == 1UL) ? 0 : __builtin_ctzl((kw | ow) & ~1UL); >>>> + *ra = (kw == 1UL) ? 0 : __builtin_ctzl(kw & ~1UL); >>> >>> Hmm, __builtin_ctzl is undefined for 0, right? Can that be triggered >>> here? > > This corner case has been taken into account, look these condition parts, > if kw == 1UL this expression will return 0 directly, no chance to invoke __builtin_ctzl. Indeed! Thanks for making that clear! Looking forward to the next revision! Björn