[llvm-bugs] [Bug 49610] New: 8ec7ea3ddce7379e13e8dfb4a5260a6d2004aa1c causes more stack usage on PowerPC
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Mar 16 16:00:09 PDT 2021
https://bugs.llvm.org/show_bug.cgi?id=49610
Bug ID: 49610
Summary: 8ec7ea3ddce7379e13e8dfb4a5260a6d2004aa1c causes more
stack usage on PowerPC
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: Backend: PowerPC
Assignee: unassignedbugs at nondot.org
Reporter: natechancellor at gmail.com
CC: llvm-bugs at lists.llvm.org, nemanja.i.ibm at gmail.com
Forgive me if I am filing this in the wrong section or tagging the wrong
people, this is just based on my investigation and triage.
After
https://github.com/llvm/llvm-project/commit/8ec7ea3ddce7379e13e8dfb4a5260a6d2004aa1c,
there was a balloon in stack usage in a particular function in the PowerPC KVM
section of the Linux kernel, which causes a build error because of -Werror.
Prior to 8ec7ea3ddce7379e13e8dfb4a5260a6d2004aa1c (with Linux at 5.12-rc3 for
https://git.kernel.org/linus/97e4910232fa1f81e806aa60c25a0450276d99a2):
# legacy pass manager
$ make -skj"$(nproc)" ARCH=powerpc CC=clang CROSS_COMPILE=powerpc64-linux-gnu-
KCFLAGS="-fno-experimental-new-pass-manager -Wframe-larger-than=1024"
O=build/ppc64 distclean pseries_defconfig disable-werror.config
arch/powerpc/kvm/book3s_hv_nested.o
arch/powerpc/kvm/book3s_hv_nested.c:264:6: warning: stack frame size of 1728
bytes in function 'kvmhv_enter_nested_guest' [-Wframe-larger-than=]
long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
^
1 warning generated.
# new pass manager
$ make -skj"$(nproc)" ARCH=powerpc CC=clang CROSS_COMPILE=powerpc64-linux-gnu-
KCFLAGS="-fexperimental-new-pass-manager -Wframe-larger-than=1024"
O=build/ppc64 distclean pseries_defconfig disable-werror.config
arch/powerpc/kvm/book3s_hv_nested.o
arch/powerpc/kvm/book3s_hv_nested.c:264:6: warning: stack frame size of 1712
bytes in function 'kvmhv_enter_nested_guest' [-Wframe-larger-than=]
long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
^
1 warning generated.
After 8ec7ea3ddce7379e13e8dfb4a5260a6d2004aa1c:
# legacy pass manager
$ make -skj"$(nproc)" ARCH=powerpc CC=clang CROSS_COMPILE=powerpc64-linux-gnu-
KCFLAGS="-fno-experimental-new-pass-manager -Wframe-larger-than=1024"
O=build/ppc64 distclean pseries_defconfig disable-werror.config
arch/powerpc/kvm/book3s_hv_nested.o
arch/powerpc/kvm/book3s_hv_nested.c:264:6: warning: stack frame size of 2480
bytes in function 'kvmhv_enter_nested_guest' [-Wframe-larger-than=]
long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
^
1 warning generated.
# new pass manager
$ make -skj"$(nproc)" ARCH=powerpc CC=clang CROSS_COMPILE=powerpc64-linux-gnu-
KCFLAGS="-fexperimental-new-pass-manager -Wframe-larger-than=1024"
O=build/ppc64 distclean pseries_defconfig disable-werror.config
arch/powerpc/kvm/book3s_hv_nested.o
arch/powerpc/kvm/book3s_hv_nested.c:264:6: warning: stack frame size of 2048
bytes in function 'kvmhv_enter_nested_guest' [-Wframe-larger-than=]
long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
^
1 warning generated.
For reference, GCC 10.2.0:
$ make -skj"$(nproc)" ARCH=powerpc ARCH=powerpc CROSS_COMPILE=powerpc64-linux-
KCFLAGS=-Wframe-larger-than=1024 O=build/ppc64 distclean pseries_defconfig
disable-werror.config arch/powerpc/kvm/book3s_hv_nested.o
arch/powerpc/kvm/book3s_hv_nested.c: In function 'kvmhv_enter_nested_guest':
arch/powerpc/kvm/book3s_hv_nested.c:387:1: warning: the frame size of 1280
bytes is larger than 1024 bytes [-Wframe-larger-than=]
387 | }
| ^
I tried to reduce this down with cvise and came up with:
struct hv_guest_state {
int vcpu_token;
long pcr;
long amor;
long dpdes;
long hfscr;
long tb_offset;
long srr0;
long srr1;
long sprg[4];
long pidr;
long cfar;
long ppr;
long dawr1;
long dawrx1;
} kvmhv_write_guest_state_and_regs_l2_hv;
struct pt_regs {
struct {
struct {
long gpr[32];
long nip;
long msr;
long orig_gpr3;
long ctr;
long link;
long xer;
long ccr;
long softe;
long trap;
long dar;
long dsisr;
long result;
};
long __pad[4];
};
} __srcu_read_unlock();
struct kvm_vcpu_arch {
struct pt_regs regs;
struct kvmppc_vcore *vcore;
int trap;
};
struct kvmppc_vcore {
long tb_offset;
long pcr;
};
struct kvm_nested_guest {
long l1_gr_to_hr;
};
int kvm_vcpu_read_guest();
static void kvmhv_update_ptbl_cache(struct kvm_nested_guest *gp) {
struct kvm_nested_guest __trans_tmp_14 = *gp;
__srcu_read_unlock(__trans_tmp_14);
}
void byteswap_pt_regs(struct pt_regs *regs) {
unsigned long *addr = (long *)regs;
for (; addr < (unsigned long *)(regs + 1); addr++)
*addr = __builtin_bswap64(*addr);
}
int kvmhv_read_guest_state_and_regs(struct hv_guest_state *l2_hv,
struct pt_regs *l2_regs) {
return kvm_vcpu_read_guest(l2_hv) || kvm_vcpu_read_guest(l2_regs);
}
long kvmhv_enter_nested_guest(struct kvm_vcpu_arch *vcpu) {
struct kvm_nested_guest *l2;
struct pt_regs l2_regs, saved_l1_regs;
struct hv_guest_state l2_hv;
struct kvmppc_vcore *vc = vcpu->vcore;
long regs_ptr = kvmhv_read_guest_state_and_regs(&l2_hv, &l2_regs);
byteswap_pt_regs(&l2_regs);
if (!l2->l1_gr_to_hr)
kvmhv_update_ptbl_cache(l2);
saved_l1_regs = vcpu->regs;
vc->tb_offset += l2_hv.tb_offset;
vcpu->regs = saved_l1_regs;
vc = vcpu->vcore;
vc->pcr = 0;
struct hv_guest_state *hr = 0;
hr->pidr = hr->dawr1 = __builtin_bswap64(hr->dawr1);
hr->dawrx1 = __builtin_bswap64(hr->dawrx1);
byteswap_pt_regs(&l2_regs);
kvm_vcpu_read_guest(kvmhv_write_guest_state_and_regs_l2_hv, regs_ptr);
return vcpu->trap;
}
which produces the same result: https://godbolt.org/z/754Men.
Prior to 8ec7ea3ddce7379e13e8dfb4a5260a6d2004aa1c
# LPM
$ clang -fno-experimental-new-pass-manager --target=powerpc64-linux-gnu -O2
-Wno-pointer-sign -Wframe-larger-than=512 -c -o /dev/null book3s_hv_nested.i
book3s_hv_nested.i:63:6: warning: stack frame size of 1136 bytes in function
'kvmhv_enter_nested_guest' [-Wframe-larger-than=]
long kvmhv_enter_nested_guest(struct kvm_vcpu_arch *vcpu) {
^
1 warning generated.
# NPM
$ clang -fexperimental-new-pass-manager --target=powerpc64-linux-gnu -O2
-Wno-pointer-sign -Wframe-larger-than=512 -c -o /dev/null book3s_hv_nested.i
book3s_hv_nested.i:63:6: warning: stack frame size of 640 bytes in function
'kvmhv_enter_nested_guest' [-Wframe-larger-than=]
long kvmhv_enter_nested_guest(struct kvm_vcpu_arch *vcpu) {
^
1 warning generated.
After 8ec7ea3ddce7379e13e8dfb4a5260a6d2004aa1c:
# LPM
$ clang -fno-experimental-new-pass-manager --target=powerpc64-linux-gnu -O2
-Wno-pointer-sign -Wframe-larger-than=512 -c -o /dev/null book3s_hv_nested.i
book3s_hv_nested.i:54:6: warning: stack frame size of 944 bytes in function
'byteswap_pt_regs' [-Wframe-larger-than=]
void byteswap_pt_regs(struct pt_regs *regs) {
^
book3s_hv_nested.i:63:6: warning: stack frame size of 2064 bytes in function
'kvmhv_enter_nested_guest' [-Wframe-larger-than=]
long kvmhv_enter_nested_guest(struct kvm_vcpu_arch *vcpu) {
^
2 warnings generated.
# NPM
$ clang -fexperimental-new-pass-manager --target=powerpc64-linux-gnu -O2
-Wno-pointer-sign -Wframe-larger-than=512 -c -o /dev/null book3s_hv_nested.i
book3s_hv_nested.i:54:6: warning: stack frame size of 944 bytes in function
'byteswap_pt_regs' [-Wframe-larger-than=]
void byteswap_pt_regs(struct pt_regs *regs) {
^
book3s_hv_nested.i:63:6: warning: stack frame size of 1520 bytes in function
'kvmhv_enter_nested_guest' [-Wframe-larger-than=]
long kvmhv_enter_nested_guest(struct kvm_vcpu_arch *vcpu) {
^
2 warnings generated.
Arnd Bergmann points out that this is most likely because PowerPC does not
appear to be using optimal assembly for byte swapping (or at least would help),
which I believe should be visible from the Godbolt link above.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210316/83e44c25/attachment-0001.html>
More information about the llvm-bugs
mailing list