Bug 668489

Summary: vta: missing inline parameters, kernel fs/namei.c:may_create
Product: [Fedora] Fedora Reporter: Frank Ch. Eigler <fche>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: rawhideCC: aoliva, jakub
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: gcc-4.6.0-0.11.fc15 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-02-23 13:38:55 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
-fverbose-asm .s file, from a slightly newer kernel version, but same compiler
none
preprocessed source none

Description Frank Ch. Eigler 2011-01-10 16:21:54 UTC
Created attachment 472633 [details]
-fverbose-asm .s file, from a slightly newer kernel version, but same compiler

The linux kernel's fs/namei.c contains an inline function may_create.
While declared inline and called from four places, the compiler turns
out to instantiate only one out-of-line copy of it.  The problem is
that the the "child" parameter has no location info, even though it
is used.

gcc-4.5.1-6.fc15.x86_64
kernel-2.6.37-1.fc15.x86_64

Comment 1 Jakub Jelinek 2011-01-16 13:55:14 UTC
Please provide preprocessed source and gcc options used to compile it.  Thanks.

Comment 2 Frank Ch. Eigler 2011-01-27 15:51:41 UTC
Created attachment 475626 [details]
preprocessed source

gcc -Wp,-MD,fs/.namei.o.d  -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/4.6.0/include -I/notnfs/linux-2.6/arch/x86/include -Iinclude  -include include/generated/autoconf.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -Os -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Wframe-larger-than=2048 -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -pg -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO    -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(namei)"  -D"KBUILD_MODNAME=KBUILD_STR(namei)" -c -o fs/namei.o fs/namei.c -save-temps

gcc version 4.6.0 20110122 (Red Hat 4.6.0-0.3) (GCC) 
linux source v2.6.38-rc2-175-g6fb1b30

Comment 3 Jakub Jelinek 2011-02-23 13:29:14 UTC
The problem is IPA-SRA.  Self-contained testcase for -Os:
struct inode
{
  char i_pad[16];
  unsigned int i_flags;
};
struct dentry
{
  unsigned int d_pad[16];
  struct inode *d_inode;
};

extern int inode_permission (struct inode *, int);
extern int fsnotify_create (struct inode *, struct dentry *);

static inline int
may_create (struct inode *dir, struct dentry *child)
{
  if (child->d_inode)
    return -17;
  if (((dir)->i_flags & 16))
    return -2;
  return inode_permission (dir, 2 | 1);
}

int
foo (struct inode *dir, struct dentry *child)
{
  if (may_create (dir, child) < 0)
    return -1;
  return fsnotify_create (dir, child);
}

int
bar (struct inode *dir, struct dentry *child)
{
  if (may_create (dir, child) < 0)
    return -1;
  return fsnotify_create (dir, child);
}

int
baz (struct inode *dir, struct dentry *child)
{
  if (may_create (dir, child) < 0)
    return -1;
  return fsnotify_create (dir, child);
}

IPA-SRA decides (clearly it is a wrong decision here for code size) to not pass
child parameter to may_create, but instead pass it child->d_inode argument.
Thus in the may_create.isra.N function there really is no child parameter.

In this exact testcase this might be solvable in the future with my DW_TAG_GNU_call_site stuff together with the (still just in drafting) DW_OP_GNU_parameter_ref op, as in the callers the child is still available (copied from %rsi to %rbp where %rsi is call clobbered and overwritten by child->d_inode).  But e.g. if you just do return may_create (dir, child); above
as the whole fn body, it would be only available if the caller of that function had that value around in DW_TAG_GNU_call_site.

See
http://gcc.gnu.org/wiki/summit2010?action=AttachFile&do=get&target=jelinek.pdf
for more details.  The DW_TAG_GNU_call_site and DW_OP_GNU_entry_value stuff is currently awaiting for 4.6 branching, so that it can be resubmitted for 4.7 stage 1.

Comment 4 Jakub Jelinek 2011-02-23 13:38:55 UTC
Tracking this upstream, http://gcc.gnu.org/PR47858

Comment 5 Fedora Update System 2011-03-01 16:06:38 UTC
Package gcc-4.6.0-0.11.fc15:
* should fix your issue,
* was pushed to the Fedora 15 updates-testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing gcc-4.6.0-0.11.fc15'
as soon as you are able to, then reboot.
Please go to the following url:
https://admin.fedoraproject.org/updates/gcc-4.6.0-0.11.fc15
then log in and leave karma (feedback).

Comment 6 Fedora Update System 2011-03-03 03:37:27 UTC
gcc-4.6.0-0.11.fc15 has been pushed to the Fedora 15 stable repository.  If problems still persist, please make note of it in this bug report.