Message ID | 1683710206-23905-1-git-send-email-tangyouling@loongson.cn |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp3480855vqo; Wed, 10 May 2023 02:23:07 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ495ouqLDT2lxUuBBqr9Hf0KlRKn/EdR/q2w0UdnksPIlH5rYvq86bQW3erZFSzipYYDXra X-Received: by 2002:a05:6a00:16c5:b0:63d:38db:60ef with SMTP id l5-20020a056a0016c500b0063d38db60efmr19982157pfc.26.1683710587220; Wed, 10 May 2023 02:23:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683710587; cv=none; d=google.com; s=arc-20160816; b=Jj1RK57rvXf06XgOINEcadb7uRcj352MJQTzpgVpQ01uxgm9NhbaZt/oC7+k9zHSd0 Ls9EE1idREUmhOhDbTB1cuBcAPdxvrl7ceoX4/3TIMZOkvCu5c73G0n9q830bM8fDFGj Byk/aPkNwLOS+MFao47IW8uxB3YMbTikMKjG96XSxhvW8PwPUE6LVtAfcACfv+7A7Q8a Bn7S09vrmEx4yXoTm8IjUOPkhyDv9g0dxOAOdImTkPK9yr+WzqRQ3JoT/MC/k4vD/bcz aLWtkuueXPjPCFIT+v/BgL3UDj5aH2tXj57PYCvTSjJ31+QlcHBsVJTRPoU9nzHbSRf2 aQew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:date:subject:cc:to:from; bh=4I/ccGaHrtE7SqpsNXy+8Pv8epKmRxUPXnPKlKY1JzU=; b=ZdUmGu6UE++69cq5u6rQED908J6X5QB3UulSF3P/KyYMmTDLNSliFxbu9vr6p/h6te RdeG4gXsC2/ddUfpWkelDXgtaWBfiW4lFYqWb6YT2reAmxYymbhPn2oqVQwSLCvteOTM PvTJng9XJx+ftngkgDKJKMJYTJVgm4caU91K2hGObElRVF1MHXntr+q8uNIyRV4Y+XdH J4IVQ7i8XesywFNF9wczC0TB2/1QsPy7elD4bNgLb6M158SC8IEaTSK9pq9Htgi6pN1v 5qvKvhbH6EuvfAZo/0Gs0ZjH79tw+WYQsW6YlmasQJXsRSlsSHUC5NRiLwcZyQALHeWe d14A== 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 k5-20020aa79d05000000b0063b7465b6f8si4547619pfp.80.2023.05.10.02.22.55; Wed, 10 May 2023 02:23:07 -0700 (PDT) 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 S236322AbjEJJQ4 (ORCPT <rfc822;jeantsuru.cumc.mandola@gmail.com> + 99 others); Wed, 10 May 2023 05:16:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231486AbjEJJQx (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 10 May 2023 05:16:53 -0400 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A545CBF; Wed, 10 May 2023 02:16:48 -0700 (PDT) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8AxW+r_YFtkWk4HAA--.12277S3; Wed, 10 May 2023 17:16:47 +0800 (CST) Received: from bogon.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxKL3+YFtk7N5TAA--.18920S2; Wed, 10 May 2023 17:16:47 +0800 (CST) From: Youling Tang <tangyouling@loongson.cn> To: Huacai Chen <chenhuacai@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net>, Peter Zijlstra <peterz@infradead.org>, Josh Poimboeuf <jpoimboe@kernel.org>, Jason Baron <jbaron@akamai.com>, WANG Xuerui <kernel@xen0n.name>, Zhangjin Wu <falcon@tinylab.org>, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev Subject: [PATCH v2] LoongArch: Add jump-label implementation Date: Wed, 10 May 2023 17:16:46 +0800 Message-Id: <1683710206-23905-1-git-send-email-tangyouling@loongson.cn> X-Mailer: git-send-email 2.1.0 X-CM-TRANSID: AQAAf8BxKL3+YFtk7N5TAA--.18920S2 X-CM-SenderInfo: 5wdqw5prxox03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxGF1rZw4fAFW7Jry7Cr18uFg_yoW7Jry7pr 17Aws5GF4kGF1fJrZ8tryDur45Xan5Ga12gF13tFy8AF9rX34vvrn2kryDZF1DJ397GrWI gF1ruFsIva1UJ3JanT9S1TB71UUUUj7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU bS8YFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_Jrv_JF1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r126r1DM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E 87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lc7CjxV Aaw2AFwI0_JF0_Jw1l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxY O2xFxVAFwI0_JF0_Jw1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGV WUWwC2zVAF1VAY17CE14v26r1q6r43MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_ Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE42xK8VAvwI8IcIk0rV WUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r1j6r4U YxBIdaVFxhVjvjDU0xZFpf9x07j5o7tUUUUU= X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE 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?1765498512422202955?= X-GMAIL-MSGID: =?utf-8?q?1765498512422202955?= |
Series |
[v2] LoongArch: Add jump-label implementation
|
|
Commit Message
Youling Tang
May 10, 2023, 9:16 a.m. UTC
Add jump-label implementation based on the ARM64 version.
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
Changes in v2:
- Fix build errors.
- fix comment.
.../core/jump-labels/arch-support.txt | 2 +-
arch/loongarch/Kconfig | 2 +
arch/loongarch/configs/loongson3_defconfig | 1 +
arch/loongarch/include/asm/jump_label.h | 51 +++++++++++++++++++
arch/loongarch/kernel/Makefile | 2 +
arch/loongarch/kernel/jump_label.c | 23 +++++++++
6 files changed, 80 insertions(+), 1 deletion(-)
create mode 100644 arch/loongarch/include/asm/jump_label.h
create mode 100644 arch/loongarch/kernel/jump_label.c
Comments
On Wed, May 10, 2023 at 05:16:46PM +0800, Youling Tang wrote: > Add jump-label implementation based on the ARM64 version. > > Signed-off-by: Youling Tang <tangyouling@loongson.cn> > diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h > new file mode 100644 > index 000000000000..2f9fdec256c5 > --- /dev/null > +++ b/arch/loongarch/include/asm/jump_label.h > @@ -0,0 +1,51 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (C) 2023 Loongson Technology Corporation Limited > + * > + * Based on arch/arm64/include/asm/jump_label.h > + */ > +#ifndef __ASM_JUMP_LABEL_H > +#define __ASM_JUMP_LABEL_H > + > +#ifndef __ASSEMBLY__ > + > +#include <linux/types.h> > + > +#define JUMP_LABEL_NOP_SIZE 4 > + > +static __always_inline bool arch_static_branch(struct static_key * const key, > + const bool branch) > +{ > + asm_volatile_goto( > + "1: nop \n\t" > + " .pushsection __jump_table, \"aw\" \n\t" > + " .align 3 \n\t" > + " .long 1b - ., %l[l_yes] - . \n\t" > + " .quad %0 - . \n\t" > + " .popsection \n\t" > + : : "i"(&((char *)key)[branch]) : : l_yes); > + > + return false; > +l_yes: > + return true; > +} > + > +static __always_inline bool arch_static_branch_jump(struct static_key * const key, > + const bool branch) > +{ > + asm_volatile_goto( > + "1: b %l[l_yes] \n\t" > + " .pushsection __jump_table, \"aw\" \n\t" > + " .align 3 \n\t" > + " .long 1b - ., %l[l_yes] - . \n\t" > + " .quad %0 - . \n\t" > + " .popsection \n\t" > + : : "i"(&((char *)key)[branch]) : : l_yes); > + > + return false; > +l_yes: > + return true; > +} Seems simple enough; one change I did a while ago for the x86 version is to put the __jump_table entry generation in a macro so it could be shared between the (3 for x86) variants. Not saying you have to do that, just saying it's an option. > +#endif /* __ASSEMBLY__ */ > +#endif /* __ASM_JUMP_LABEL_H */ > diff --git a/arch/loongarch/kernel/jump_label.c b/arch/loongarch/kernel/jump_label.c > new file mode 100644 > index 000000000000..b06245955f7a > --- /dev/null > +++ b/arch/loongarch/kernel/jump_label.c > @@ -0,0 +1,23 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) 2023 Loongson Technology Corporation Limited > + * > + * Based on arch/arm64/kernel/jump_label.c > + */ > +#include <linux/jump_label.h> > +#include <linux/kernel.h> > +#include <asm/inst.h> > + > +void arch_jump_label_transform(struct jump_entry *entry, > + enum jump_label_type type) > +{ > + void *addr = (void *)jump_entry_code(entry); > + u32 insn; > + > + if (type == JUMP_LABEL_JMP) > + insn = larch_insn_gen_b(jump_entry_code(entry), jump_entry_target(entry)); > + else > + insn = larch_insn_gen_nop(); > + > + larch_insn_patch_text(addr, insn); > +} This all implies Loongarch is fine with the nop<->b transition (much like arm64 is), but I found no actual mention of what transitions are valid for the architecture in your inst.c file -- perhaps you could put a small comment there to elucidate the occasional reader that doesn't have your arch manual memorized? Anyway, as with most RISC implementations it's short and sweet. Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Hi Youling, On 2023/5/10 17:16, Youling Tang wrote: > Add jump-label implementation based on the ARM64 version. "Add support for jump labels based on ..." sounds better IMO. > > Signed-off-by: Youling Tang <tangyouling@loongson.cn> > --- > Changes in v2: > - Fix build errors. > - fix comment. > > .../core/jump-labels/arch-support.txt | 2 +- > arch/loongarch/Kconfig | 2 + > arch/loongarch/configs/loongson3_defconfig | 1 + > arch/loongarch/include/asm/jump_label.h | 51 +++++++++++++++++++ > arch/loongarch/kernel/Makefile | 2 + > arch/loongarch/kernel/jump_label.c | 23 +++++++++ > 6 files changed, 80 insertions(+), 1 deletion(-) > create mode 100644 arch/loongarch/include/asm/jump_label.h > create mode 100644 arch/loongarch/kernel/jump_label.c > > diff --git a/Documentation/features/core/jump-labels/arch-support.txt b/Documentation/features/core/jump-labels/arch-support.txt > index 2328eada3a49..94d9dece580f 100644 > --- a/Documentation/features/core/jump-labels/arch-support.txt > +++ b/Documentation/features/core/jump-labels/arch-support.txt > @@ -13,7 +13,7 @@ > | csky: | ok | > | hexagon: | TODO | > | ia64: | TODO | > - | loongarch: | TODO | > + | loongarch: | ok | +1 for updating the docs along with the implementation! > | m68k: | TODO | > | microblaze: | TODO | > | mips: | ok | > diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig > index d38b066fc931..193a959a5611 100644 > --- a/arch/loongarch/Kconfig > +++ b/arch/loongarch/Kconfig > @@ -83,6 +83,8 @@ config LOONGARCH > select GPIOLIB > select HAS_IOPORT > select HAVE_ARCH_AUDITSYSCALL > + select HAVE_ARCH_JUMP_LABEL > + select HAVE_ARCH_JUMP_LABEL_RELATIVE > select HAVE_ARCH_MMAP_RND_BITS if MMU > select HAVE_ARCH_SECCOMP_FILTER > select HAVE_ARCH_TRACEHOOK > diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig > index 6cd26dd3c134..33a0f5f742f6 100644 > --- a/arch/loongarch/configs/loongson3_defconfig > +++ b/arch/loongarch/configs/loongson3_defconfig > @@ -63,6 +63,7 @@ CONFIG_EFI_ZBOOT=y > CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y > CONFIG_EFI_CAPSULE_LOADER=m > CONFIG_EFI_TEST=m > +CONFIG_JUMP_LABEL=y > CONFIG_MODULES=y > CONFIG_MODULE_FORCE_LOAD=y > CONFIG_MODULE_UNLOAD=y > diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h > new file mode 100644 > index 000000000000..2f9fdec256c5 > --- /dev/null > +++ b/arch/loongarch/include/asm/jump_label.h > @@ -0,0 +1,51 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (C) 2023 Loongson Technology Corporation Limited > + * > + * Based on arch/arm64/include/asm/jump_label.h > + */ > +#ifndef __ASM_JUMP_LABEL_H > +#define __ASM_JUMP_LABEL_H > + > +#ifndef __ASSEMBLY__ > + > +#include <linux/types.h> > + > +#define JUMP_LABEL_NOP_SIZE 4 Saying LOONGARCH_INSN_SIZE here might be better for reducing redundancy, although that'll necessitate an extra include of <asm/inst.h>. Leaving the 4 alone won't cause much harm so I'm fine with either. > + > +static __always_inline bool arch_static_branch(struct static_key * const key, > + const bool branch) > +{ > + asm_volatile_goto( > + "1: nop \n\t" > + " .pushsection __jump_table, \"aw\" \n\t" > + " .align 3 \n\t" > + " .long 1b - ., %l[l_yes] - . \n\t" > + " .quad %0 - . \n\t" > + " .popsection \n\t" > + : : "i"(&((char *)key)[branch]) : : l_yes); > + > + return false; > +l_yes: > + return true; > +} > + > +static __always_inline bool arch_static_branch_jump(struct static_key * const key, > + const bool branch) > +{ > + asm_volatile_goto( > + "1: b %l[l_yes] \n\t" > + " .pushsection __jump_table, \"aw\" \n\t" > + " .align 3 \n\t" > + " .long 1b - ., %l[l_yes] - . \n\t" > + " .quad %0 - . \n\t" > + " .popsection \n\t" > + : : "i"(&((char *)key)[branch]) : : l_yes); > + > + return false; > +l_yes: > + return true; > +} > + > +#endif /* __ASSEMBLY__ */ > +#endif /* __ASM_JUMP_LABEL_H */ > diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile > index 9a72d91cd104..64ea76f60e2c 100644 > --- a/arch/loongarch/kernel/Makefile > +++ b/arch/loongarch/kernel/Makefile > @@ -54,4 +54,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o > > obj-$(CONFIG_KPROBES) += kprobes.o kprobes_trampoline.o > > +obj-$(CONFIG_JUMP_LABEL) += jump_label.o > + > CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) > diff --git a/arch/loongarch/kernel/jump_label.c b/arch/loongarch/kernel/jump_label.c > new file mode 100644 > index 000000000000..b06245955f7a > --- /dev/null > +++ b/arch/loongarch/kernel/jump_label.c > @@ -0,0 +1,23 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) 2023 Loongson Technology Corporation Limited > + * > + * Based on arch/arm64/kernel/jump_label.c > + */ > +#include <linux/jump_label.h> > +#include <linux/kernel.h> > +#include <asm/inst.h> > + > +void arch_jump_label_transform(struct jump_entry *entry, > + enum jump_label_type type) > +{ > + void *addr = (void *)jump_entry_code(entry); > + u32 insn; > + > + if (type == JUMP_LABEL_JMP) Please use a switch for dealing with enum-typed values. > + insn = larch_insn_gen_b(jump_entry_code(entry), jump_entry_target(entry)); > + else > + insn = larch_insn_gen_nop(); > + > + larch_insn_patch_text(addr, insn); > +}
Hi Peter, My 2 cents: On 2023/5/10 17:27, Peter Zijlstra wrote: > On Wed, May 10, 2023 at 05:16:46PM +0800, Youling Tang wrote: >> Add jump-label implementation based on the ARM64 version. >> >> Signed-off-by: Youling Tang <tangyouling@loongson.cn> > >> <snip> >> >> + if (type == JUMP_LABEL_JMP) >> + insn = larch_insn_gen_b(jump_entry_code(entry), jump_entry_target(entry)); >> + else >> + insn = larch_insn_gen_nop(); >> + >> + larch_insn_patch_text(addr, insn); >> +} > > This all implies Loongarch is fine with the nop<->b transition (much > like arm64 is), but I found no actual mention of what transitions are > valid for the architecture in your inst.c file -- perhaps you could put > a small comment there to elucidate the occasional reader that doesn't > have your arch manual memorized? Do you mean by "valid transition" something like "what kind of self-modification is architecturally sound, taking ICache / micro-architecture behavior etc. into consideration"? If so, I'd say things would be fine in LoongArch as long as an instruction fetch barrier is used. Maybe Youling can confirm and mention this in the next revision.
On Wed, May 10, 2023 at 05:34:33PM +0800, WANG Xuerui wrote: > Hi Peter, > > My 2 cents: > > On 2023/5/10 17:27, Peter Zijlstra wrote: > > On Wed, May 10, 2023 at 05:16:46PM +0800, Youling Tang wrote: > > > Add jump-label implementation based on the ARM64 version. > > > > > > Signed-off-by: Youling Tang <tangyouling@loongson.cn> > > > > > <snip> > > > > > > + if (type == JUMP_LABEL_JMP) > > > + insn = larch_insn_gen_b(jump_entry_code(entry), jump_entry_target(entry)); > > > + else > > > + insn = larch_insn_gen_nop(); > > > + > > > + larch_insn_patch_text(addr, insn); > > > +} > > > > This all implies Loongarch is fine with the nop<->b transition (much > > like arm64 is), but I found no actual mention of what transitions are > > valid for the architecture in your inst.c file -- perhaps you could put > > a small comment there to elucidate the occasional reader that doesn't > > have your arch manual memorized? > > Do you mean by "valid transition" something like "what kind of > self-modification is architecturally sound, taking ICache / > micro-architecture behavior etc. into consideration"? Yes that. There are definitely architectures that have limitations on what instructions can be hot-patched in the face of concurrent execution without jumping through too many hoops.
Hi, Peter On 05/10/2023 05:27 PM, Peter Zijlstra wrote: > On Wed, May 10, 2023 at 05:16:46PM +0800, Youling Tang wrote: >> Add jump-label implementation based on the ARM64 version. >> >> Signed-off-by: Youling Tang <tangyouling@loongson.cn> > >> diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h >> new file mode 100644 >> index 000000000000..2f9fdec256c5 >> --- /dev/null >> +++ b/arch/loongarch/include/asm/jump_label.h >> @@ -0,0 +1,51 @@ >> +/* SPDX-License-Identifier: GPL-2.0-only */ >> +/* >> + * Copyright (C) 2023 Loongson Technology Corporation Limited >> + * >> + * Based on arch/arm64/include/asm/jump_label.h >> + */ >> +#ifndef __ASM_JUMP_LABEL_H >> +#define __ASM_JUMP_LABEL_H >> + >> +#ifndef __ASSEMBLY__ >> + >> +#include <linux/types.h> >> + >> +#define JUMP_LABEL_NOP_SIZE 4 >> + >> +static __always_inline bool arch_static_branch(struct static_key * const key, >> + const bool branch) >> +{ >> + asm_volatile_goto( >> + "1: nop \n\t" >> + " .pushsection __jump_table, \"aw\" \n\t" >> + " .align 3 \n\t" >> + " .long 1b - ., %l[l_yes] - . \n\t" >> + " .quad %0 - . \n\t" >> + " .popsection \n\t" >> + : : "i"(&((char *)key)[branch]) : : l_yes); >> + >> + return false; >> +l_yes: >> + return true; >> +} >> + >> +static __always_inline bool arch_static_branch_jump(struct static_key * const key, >> + const bool branch) >> +{ >> + asm_volatile_goto( >> + "1: b %l[l_yes] \n\t" >> + " .pushsection __jump_table, \"aw\" \n\t" >> + " .align 3 \n\t" >> + " .long 1b - ., %l[l_yes] - . \n\t" >> + " .quad %0 - . \n\t" >> + " .popsection \n\t" >> + : : "i"(&((char *)key)[branch]) : : l_yes); >> + >> + return false; >> +l_yes: >> + return true; >> +} > > Seems simple enough; one change I did a while ago for the x86 version is > to put the __jump_table entry generation in a macro so it could be > shared between the (3 for x86) variants. Looks better, I will define JUMP_TABLE_ENTRY macro so that arch_static_branch and arch_static_branch_jump can share. Thanks, Youling. > > Not saying you have to do that, just saying it's an option. > >> +#endif /* __ASSEMBLY__ */ >> +#endif /* __ASM_JUMP_LABEL_H */ > >> diff --git a/arch/loongarch/kernel/jump_label.c b/arch/loongarch/kernel/jump_label.c >> new file mode 100644 >> index 000000000000..b06245955f7a >> --- /dev/null >> +++ b/arch/loongarch/kernel/jump_label.c >> @@ -0,0 +1,23 @@ >> +// SPDX-License-Identifier: GPL-2.0-only >> +/* >> + * Copyright (C) 2023 Loongson Technology Corporation Limited >> + * >> + * Based on arch/arm64/kernel/jump_label.c >> + */ >> +#include <linux/jump_label.h> >> +#include <linux/kernel.h> >> +#include <asm/inst.h> >> + >> +void arch_jump_label_transform(struct jump_entry *entry, >> + enum jump_label_type type) >> +{ >> + void *addr = (void *)jump_entry_code(entry); >> + u32 insn; >> + >> + if (type == JUMP_LABEL_JMP) >> + insn = larch_insn_gen_b(jump_entry_code(entry), jump_entry_target(entry)); >> + else >> + insn = larch_insn_gen_nop(); >> + >> + larch_insn_patch_text(addr, insn); >> +} > > This all implies Loongarch is fine with the nop<->b transition (much > like arm64 is), but I found no actual mention of what transitions are > valid for the architecture in your inst.c file -- perhaps you could put > a small comment there to elucidate the occasional reader that doesn't > have your arch manual memorized? > > > Anyway, as with most RISC implementations it's short and sweet. > > Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> >
Hi, Xuerui On 05/10/2023 05:28 PM, WANG Xuerui wrote: > Hi Youling, > > On 2023/5/10 17:16, Youling Tang wrote: >> Add jump-label implementation based on the ARM64 version. > > "Add support for jump labels based on ..." sounds better IMO. OK. > >> >> Signed-off-by: Youling Tang <tangyouling@loongson.cn> >> --- >> Changes in v2: >> - Fix build errors. >> - fix comment. >> >> .../core/jump-labels/arch-support.txt | 2 +- >> arch/loongarch/Kconfig | 2 + >> arch/loongarch/configs/loongson3_defconfig | 1 + >> arch/loongarch/include/asm/jump_label.h | 51 +++++++++++++++++++ >> arch/loongarch/kernel/Makefile | 2 + >> arch/loongarch/kernel/jump_label.c | 23 +++++++++ >> 6 files changed, 80 insertions(+), 1 deletion(-) >> create mode 100644 arch/loongarch/include/asm/jump_label.h >> create mode 100644 arch/loongarch/kernel/jump_label.c >> >> diff --git a/Documentation/features/core/jump-labels/arch-support.txt >> b/Documentation/features/core/jump-labels/arch-support.txt >> index 2328eada3a49..94d9dece580f 100644 >> --- a/Documentation/features/core/jump-labels/arch-support.txt >> +++ b/Documentation/features/core/jump-labels/arch-support.txt >> @@ -13,7 +13,7 @@ >> | csky: | ok | >> | hexagon: | TODO | >> | ia64: | TODO | >> - | loongarch: | TODO | >> + | loongarch: | ok | > > +1 for updating the docs along with the implementation! > >> | m68k: | TODO | >> | microblaze: | TODO | >> | mips: | ok | >> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig >> index d38b066fc931..193a959a5611 100644 >> --- a/arch/loongarch/Kconfig >> +++ b/arch/loongarch/Kconfig >> @@ -83,6 +83,8 @@ config LOONGARCH >> select GPIOLIB >> select HAS_IOPORT >> select HAVE_ARCH_AUDITSYSCALL >> + select HAVE_ARCH_JUMP_LABEL >> + select HAVE_ARCH_JUMP_LABEL_RELATIVE >> select HAVE_ARCH_MMAP_RND_BITS if MMU >> select HAVE_ARCH_SECCOMP_FILTER >> select HAVE_ARCH_TRACEHOOK >> diff --git a/arch/loongarch/configs/loongson3_defconfig >> b/arch/loongarch/configs/loongson3_defconfig >> index 6cd26dd3c134..33a0f5f742f6 100644 >> --- a/arch/loongarch/configs/loongson3_defconfig >> +++ b/arch/loongarch/configs/loongson3_defconfig >> @@ -63,6 +63,7 @@ CONFIG_EFI_ZBOOT=y >> CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y >> CONFIG_EFI_CAPSULE_LOADER=m >> CONFIG_EFI_TEST=m >> +CONFIG_JUMP_LABEL=y >> CONFIG_MODULES=y >> CONFIG_MODULE_FORCE_LOAD=y >> CONFIG_MODULE_UNLOAD=y >> diff --git a/arch/loongarch/include/asm/jump_label.h >> b/arch/loongarch/include/asm/jump_label.h >> new file mode 100644 >> index 000000000000..2f9fdec256c5 >> --- /dev/null >> +++ b/arch/loongarch/include/asm/jump_label.h >> @@ -0,0 +1,51 @@ >> +/* SPDX-License-Identifier: GPL-2.0-only */ >> +/* >> + * Copyright (C) 2023 Loongson Technology Corporation Limited >> + * >> + * Based on arch/arm64/include/asm/jump_label.h >> + */ >> +#ifndef __ASM_JUMP_LABEL_H >> +#define __ASM_JUMP_LABEL_H >> + >> +#ifndef __ASSEMBLY__ >> + >> +#include <linux/types.h> >> + >> +#define JUMP_LABEL_NOP_SIZE 4 > > Saying LOONGARCH_INSN_SIZE here might be better for reducing redundancy, > although that'll necessitate an extra include of <asm/inst.h>. Leaving > the 4 alone won't cause much harm so I'm fine with either. Using LOONGARCH_INSN_SIZE in v1, but causing build errors due to inclusion of <asm/inst.h> [1]. So I removed the <asm/inst.h> include and used hardcoded 4. [1]: https://lore.kernel.org/loongarch/202305100412.gazWW71q-lkp@intel.com/T/#m0d8393aaf529aea0a4dcc5985469e698d63d66b3 > >> + >> +static __always_inline bool arch_static_branch(struct static_key * >> const key, >> + const bool branch) >> +{ >> + asm_volatile_goto( >> + "1: nop \n\t" >> + " .pushsection __jump_table, \"aw\" \n\t" >> + " .align 3 \n\t" >> + " .long 1b - ., %l[l_yes] - . \n\t" >> + " .quad %0 - . \n\t" >> + " .popsection \n\t" >> + : : "i"(&((char *)key)[branch]) : : l_yes); >> + >> + return false; >> +l_yes: >> + return true; >> +} >> + >> +static __always_inline bool arch_static_branch_jump(struct static_key >> * const key, >> + const bool branch) >> +{ >> + asm_volatile_goto( >> + "1: b %l[l_yes] \n\t" >> + " .pushsection __jump_table, \"aw\" \n\t" >> + " .align 3 \n\t" >> + " .long 1b - ., %l[l_yes] - . \n\t" >> + " .quad %0 - . \n\t" >> + " .popsection \n\t" >> + : : "i"(&((char *)key)[branch]) : : l_yes); >> + >> + return false; >> +l_yes: >> + return true; >> +} >> + >> +#endif /* __ASSEMBLY__ */ >> +#endif /* __ASM_JUMP_LABEL_H */ >> diff --git a/arch/loongarch/kernel/Makefile >> b/arch/loongarch/kernel/Makefile >> index 9a72d91cd104..64ea76f60e2c 100644 >> --- a/arch/loongarch/kernel/Makefile >> +++ b/arch/loongarch/kernel/Makefile >> @@ -54,4 +54,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o >> obj-$(CONFIG_KPROBES) += kprobes.o kprobes_trampoline.o >> +obj-$(CONFIG_JUMP_LABEL) += jump_label.o >> + >> CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) >> diff --git a/arch/loongarch/kernel/jump_label.c >> b/arch/loongarch/kernel/jump_label.c >> new file mode 100644 >> index 000000000000..b06245955f7a >> --- /dev/null >> +++ b/arch/loongarch/kernel/jump_label.c >> @@ -0,0 +1,23 @@ >> +// SPDX-License-Identifier: GPL-2.0-only >> +/* >> + * Copyright (C) 2023 Loongson Technology Corporation Limited >> + * >> + * Based on arch/arm64/kernel/jump_label.c >> + */ >> +#include <linux/jump_label.h> >> +#include <linux/kernel.h> >> +#include <asm/inst.h> >> + >> +void arch_jump_label_transform(struct jump_entry *entry, >> + enum jump_label_type type) >> +{ >> + void *addr = (void *)jump_entry_code(entry); >> + u32 insn; >> + >> + if (type == JUMP_LABEL_JMP) > > Please use a switch for dealing with enum-typed values. Because the current type only has JUMP_LABEL_NOP and JUMP_LABEL_JMP, using if may be simpler than switch. Thanks, Youling. > >> + insn = larch_insn_gen_b(jump_entry_code(entry), >> jump_entry_target(entry)); >> + else >> + insn = larch_insn_gen_nop(); >> + >> + larch_insn_patch_text(addr, insn); >> +} >
On Thu, May 11, 2023 at 09:33:37AM +0800, Youling Tang wrote: > > > +void arch_jump_label_transform(struct jump_entry *entry, > > > + enum jump_label_type type) > > > +{ > > > + void *addr = (void *)jump_entry_code(entry); > > > + u32 insn; > > > + > > > + if (type == JUMP_LABEL_JMP) > > > > Please use a switch for dealing with enum-typed values. > > Because the current type only has JUMP_LABEL_NOP and JUMP_LABEL_JMP, > using if may be simpler than switch. IIRC we used an enum with descriptive names instead of a boolean because true/false just doesn't tell you much. The whole thing fundamentally is a boolean descision though, either you write a JMP or a NOP, jump-labels don't have more options.
On 2023/5/11 15:43, Peter Zijlstra wrote: > On Thu, May 11, 2023 at 09:33:37AM +0800, Youling Tang wrote: > >>>> +void arch_jump_label_transform(struct jump_entry *entry, >>>> + enum jump_label_type type) >>>> +{ >>>> + void *addr = (void *)jump_entry_code(entry); >>>> + u32 insn; >>>> + >>>> + if (type == JUMP_LABEL_JMP) >>> >>> Please use a switch for dealing with enum-typed values. >> >> Because the current type only has JUMP_LABEL_NOP and JUMP_LABEL_JMP, >> using if may be simpler than switch. > > IIRC we used an enum with descriptive names instead of a boolean because > true/false just doesn't tell you much. > > The whole thing fundamentally is a boolean descision though, either > you write a JMP or a NOP, jump-labels don't have more options. Ah thanks for the background. My previous suggestion is just kinda generally applicable software engineering best practice, so if the actual enum is unlikely to get >2 variants then it should be fine to keep using "if". Youling, feel free to ignore the piece of comment, and sorry for not doing my archaeology beforehand. :)
From: Youling Tang > Sent: 11 May 2023 02:34 ... > >> + if (type == JUMP_LABEL_JMP) > > > > Please use a switch for dealing with enum-typed values. > > Because the current type only has JUMP_LABEL_NOP and JUMP_LABEL_JMP, > using if may be simpler than switch. The generated code will be pretty much the same. Even if the compiler is allowed generate a jump table (which is almost certainly disabled) it won't if there are only two cases. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
diff --git a/Documentation/features/core/jump-labels/arch-support.txt b/Documentation/features/core/jump-labels/arch-support.txt index 2328eada3a49..94d9dece580f 100644 --- a/Documentation/features/core/jump-labels/arch-support.txt +++ b/Documentation/features/core/jump-labels/arch-support.txt @@ -13,7 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | - | loongarch: | TODO | + | loongarch: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index d38b066fc931..193a959a5611 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -83,6 +83,8 @@ config LOONGARCH select GPIOLIB select HAS_IOPORT select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_JUMP_LABEL + select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig index 6cd26dd3c134..33a0f5f742f6 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson3_defconfig @@ -63,6 +63,7 @@ CONFIG_EFI_ZBOOT=y CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y CONFIG_EFI_CAPSULE_LOADER=m CONFIG_EFI_TEST=m +CONFIG_JUMP_LABEL=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h new file mode 100644 index 000000000000..2f9fdec256c5 --- /dev/null +++ b/arch/loongarch/include/asm/jump_label.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2023 Loongson Technology Corporation Limited + * + * Based on arch/arm64/include/asm/jump_label.h + */ +#ifndef __ASM_JUMP_LABEL_H +#define __ASM_JUMP_LABEL_H + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> + +#define JUMP_LABEL_NOP_SIZE 4 + +static __always_inline bool arch_static_branch(struct static_key * const key, + const bool branch) +{ + asm_volatile_goto( + "1: nop \n\t" + " .pushsection __jump_table, \"aw\" \n\t" + " .align 3 \n\t" + " .long 1b - ., %l[l_yes] - . \n\t" + " .quad %0 - . \n\t" + " .popsection \n\t" + : : "i"(&((char *)key)[branch]) : : l_yes); + + return false; +l_yes: + return true; +} + +static __always_inline bool arch_static_branch_jump(struct static_key * const key, + const bool branch) +{ + asm_volatile_goto( + "1: b %l[l_yes] \n\t" + " .pushsection __jump_table, \"aw\" \n\t" + " .align 3 \n\t" + " .long 1b - ., %l[l_yes] - . \n\t" + " .quad %0 - . \n\t" + " .popsection \n\t" + : : "i"(&((char *)key)[branch]) : : l_yes); + + return false; +l_yes: + return true; +} + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_JUMP_LABEL_H */ diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile index 9a72d91cd104..64ea76f60e2c 100644 --- a/arch/loongarch/kernel/Makefile +++ b/arch/loongarch/kernel/Makefile @@ -54,4 +54,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_KPROBES) += kprobes.o kprobes_trampoline.o +obj-$(CONFIG_JUMP_LABEL) += jump_label.o + CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) diff --git a/arch/loongarch/kernel/jump_label.c b/arch/loongarch/kernel/jump_label.c new file mode 100644 index 000000000000..b06245955f7a --- /dev/null +++ b/arch/loongarch/kernel/jump_label.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2023 Loongson Technology Corporation Limited + * + * Based on arch/arm64/kernel/jump_label.c + */ +#include <linux/jump_label.h> +#include <linux/kernel.h> +#include <asm/inst.h> + +void arch_jump_label_transform(struct jump_entry *entry, + enum jump_label_type type) +{ + void *addr = (void *)jump_entry_code(entry); + u32 insn; + + if (type == JUMP_LABEL_JMP) + insn = larch_insn_gen_b(jump_entry_code(entry), jump_entry_target(entry)); + else + insn = larch_insn_gen_nop(); + + larch_insn_patch_text(addr, insn); +}